Visitar URL original
ColorManagement: Remove ExtendedSRGBColorSpace by donmccurdy · Pull Request #34914 · mrdoob/three.js · GitHub
Skip to content

ColorManagement: Remove ExtendedSRGBColorSpace - #34914

Draft
donmccurdy wants to merge 5 commits into
mrdoob:devfrom
donmccurdy:refactor/rm-extended-srgb
Draft

donmccurdy wants to merge 5 commits into
mrdoob:devfrom
donmccurdy:refactor/rm-extended-srgb

Conversation

@donmccurdy

Copy link
Copy Markdown
Collaborator

With updates to WebGPU in Chrome 155-156, it's now possible to write "srgb-linear" and "display-p3-linear" color spaces directly to the canvas drawing buffer. We no longer need to define a new color space to implement the webgpu_hdr example. There are some conceptual problems with so-called "extended" color spaces, so I'd prefer to remove ExtendedSRGBColorSpace, and the changes to the color space config that it required.

Note that the webgpu_hdr example still relies on a bit of magic here:

const toneMappingMode = parameters.outputType === HalfFloatType ? 'extended' : 'standard';

I'd support adding a user-configurable option for that purpose, instead. Currently we're conflating the bit depth of the output buffer with the user's intentions for image formation. But that can be considered later.

@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

📦 Bundle size

Full ESM build including core, minified and gzipped.

Before After Diff
Core 390.53
102.46
390.21
102.40
-319 B
-60 B
WebGL 776.95
194.03
776.63
194.01
-325 B
-26 B
WebGPU 1089.68
293.76
1089.44
293.71
-248 B
-45 B
WebGPU Nodes 1087.63
293.41
1087.39
293.37
-248 B
-45 B

🌳 Bundle size after tree-shaking

Minimal build including a renderer, camera, empty scene, and dependencies.

Before After Diff
WebGL 518.47
124.58
518.15
124.53
-325 B
-50 B
WebGPU 769.32
206.26
769.07
206.22
-249 B
-41 B
WebGPU Nodes 716.57
193.02
716.32
192.98
-249 B
-40 B

@Mugen87

Mugen87 commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

Do we also have to update the WebGPU backend so colorSpace: 'srgb-linear' is passed to context.configure()? When I understand the spec correctly, webgpu_hdr would requires this now.

@donmccurdy

donmccurdy commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator Author

Oh, yes we should do that, thanks! So context.configure() should receive colorSpace directly from renderer.outputColorSpace. I guess the difference wasn't obvious in this example because it's achromatic. Will make the change.

@donmccurdy

Copy link
Copy Markdown
Collaborator Author

Updated! Requires Chrome 156. Tested in Chrome Canary; we may want to wait until this reaches stable Chrome.

Do we also have to update the WebGPU backend so colorSpace: 'srgb-linear' is passed to context.configure()?

We'll have to limit that, and only pass colorSpace when outputType == HalfFloatType, for the time being. Back when we enabled color management, there was an important opt-out workflow:

ColorManagement.workingColorSpace = THREE.LinearSRGBColorSpace;
renderer.outputColorSpace = THREE.LinearSRGBColorSpace;

It's a "two wrongs make a right" trick: the application is likely writing sRGB color to both, but because they match, no conversions happen, and it all looks fine1. But if we start passing colorSpace: "srgb-linear" to the WebGPU context in Chrome v156+, it will believe us and apply a conversion from "srgb-linear" to the actual display color space. That's good, but breaks the little trick above.

The "correct" way to express this workflow would really be...

ColorManagement.workingColorSpace = THREE.SRGBColorSpace;
renderer.outputColorSpace = THREE.SRGBColorSpace;

... but in practice it's been difficult to implement a sRGB working color space (e.g., how should textures be stored?) and so this doesn't work in three.js today. If we can later add support for workingColorSpace = THREE.SRGBColorSpace then I think we could remove the exception here and pass outputColorSpace to the WebGPU context unconditionally.


Footnotes

  1. As long as you're NOT doing lighting-based rendering, as that assumes linear color. The opt-out workflow is really meant only for preserving legacy code, and certain "unlit" applications. ↩

@mrdoob mrdoob added this to the r187 milestone Oct 9, 2026
Comment thread src/renderers/WebGLRenderer.js Resolved
format: this.utils.getPreferredCanvasFormat(),
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC,
alphaMode: alphaMode,
colorSpace: colorSpace,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you also set the drawingBufferColorSpace property in the WebGL backend?

@Mugen87

Mugen87 commented Oct 13, 2026 •

Copy link
Copy Markdown
Collaborator

I have tested the PR locally with a normal Chrome (155) and webgpu_hdr breaks with a runtime error.

Uncaught (in promise) TypeError: Failed to execute 'configure' on 'GPUCanvasContext': The provided value 'srgb-linear' is not a valid enum value of the type PredefinedColorSpace.

I understand it works in Canary but we must make sure browsers without the respective support can still run the code. Maybe like so:

try {

	context.configure( configuration );

} catch ( e ) {

	warnOnce( `WebGPURenderer: Canvas color space "${ colorSpace }" is not supported. Falling back to "srgb".` );

	delete configuration.colorSpace;
	context.configure( configuration );

}

@donmccurdy
donmccurdy marked this pull request as draft October 14, 2026 03:41
@donmccurdy

Copy link
Copy Markdown
Collaborator Author

Let's hold this back until the feature is at least in stable Chrome. I'll look into your feedback in the meantime, thanks @Mugen87! Possibly we'll also want a WebGPU equivalent of the existing WebGL.isColorSpaceAvailable( colorSpace ) utility, to check if an output color space is supported.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants