Roadmap for a color-managed workflow in three.js
See original GitHub issueOverview
Summary issue to organize and track progress toward offering a color-managed workflow in three.js. Loosely based on Maya’s documentation, I’ll define color management as follows:
Color management involves applying the appropriate transforms to convert between color spaces as needed. These transforms are applied at specific points along the initialization, rendering, and display processes. For example:
- On input, a transform is applied to convert colors and textures from the color space in which they were saved into the working color space.
- As you work, colors in the working color space may be converted to/from other color spaces in order to accommodate bit depth and precision considerations.
- On output to an image or display, an output transform is applied to convert colors appropriately for the image format or browser and device capabilities.
Roadmap
- (1.1) Add documentation of color management APIs (@donmccurdy)
- (1.2) Loaders identify and convert color spaces correctly (@gkjohnson)
- (1.3) Rename “encoding” properties more precisely as “colorSpace”
-
renderer.outputEncoding
→renderer.outputColorSpace
-
texture.encoding
→texture.colorSpace
-
- (1.4) Change output color space default from Linear-sRGB to sRGB
- (1.5) Convert some inputs automatically from sRGB to Linear-sRGB (@donmccurdy)
- hexadecimal and CSS inputs: https://github.com/mrdoob/three.js/pull/23392
- (1.6) Change
texture.colorSpace
default toTHREE.NoColorSpace
(e.g. normal maps) - (1.7) Ensure intermediate frame buffers have sufficient bit depth for their color
space
- Unsure if further work is needed here. See: https://github.com/mrdoob/three.js/issues/23251#issuecomment-1014606909
- (1.8) Change
renderer.physicallyCorrectLights
default totrue
Timing considerations: If we are doing (1.3), (1.4), and (1.5), it would cause less disruption to existing code if we can make these changes within the same release. Fewer changes, if any, will be required for end-user code.
Future
These changes are more speculative, and may be considered explorative steps toward support for wide-gamut color spaces in WebGPU and SVG renderers.
- (2.1) Support changing
ColorManagement.workingColorSpace
- (2.2) Support color input/output in Display P3 color space
- (3.3) Support vertex color workflow changes if necessary (
ColorBufferAttribute
?)
Issue Analytics
- State:
- Created 2 years ago
- Reactions:7
- Comments:26 (7 by maintainers)
Top GitHub Comments
Hmmm, I think I’m willing to try changing the default to 2 (this month maybe) and see what happens…
Observation — I don’t have a good recommendation for unlit content at this time. Thinking of examples like Oat the Goat, 2D or illustrative styles:
Users certainly can use the full ‘linear workflow’ required for PBR rendering, but are they benefiting from that? I’m not sure if there’s performance overhead there, and/or if blending and color grading ops useful for 2D unlit content are better done in sRGB or Linear-sRGB working color spaces.
The current method to ‘opt out’ does work, but is totally indirect and misleading:
This is bad because the textures and the output are not Linear-sRGB, we’re just using those settings to disable conversions. We’ve discussed APIs equivalent to “disabling” color management, but I think those have similar problems. An option to set the ‘working color space’ to sRGB is the most semantically ‘correct’ API I can think of at the moment, like…
ColorManagement.workingColorSpace = SRGBColorSpace
… so then users (and loaders, etc.) can continue to use
map.encoding = sRGBEncoding
andrenderer.outputEncoding = sRGBEncoding
correctly, and three.js will skip the conversions for reasons that are more clear and legible. But if these use cases are better served by the linear workflow too, maybe it’s just an unnecessary option. 🤔