-
-
Notifications
You must be signed in to change notification settings - Fork 35.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Material: Infer texture color space (WIP) #25857
Conversation
📦 Bundle sizeFull ESM build, minified and gzipped.
🌳 Bundle size after tree-shakingMinimal build including a renderer, camera, empty scene, and dependencies.
|
E2E tests fail on one example — webgl_nodes_loader_gltf_iridescence. Because getters are not enumerable, |
Should be fixed by #25861. |
I think I like the intent - I'm just not sure if I like the side effect of the material modifying the color space field on the Texture. Is this something the renderer can do based on the material field + texture combo? I assume no due to implicit hardware texture colorspace conversion. The other limitations make me hesitant to support this, though.
With more asset color spaces starting to become relevant part of me is wondering how far this idea of users not needing to know about color spaces will be able to go 😅 |
In that case... Wouldn't it be more consistent to use |
Indeed. Is this something the renderer could do instead? 🤔 |
I'm happy with either of these. The value of the NoColorSpace constant is currently an empty string, /cc @WestLangley
My thought was that we probably don't want the renderer having to know about every possible material, any more than it already does... if that isn't a concern then yes, I imagine the renderer could also do this. I see it as an advantage that the texture's
One thing I see in tools like OpenColorIO (used by Blender, Unreal, Substance, ...) is the concept of color space "roles". You don't necessarily assign every texture its color space, but might define in a config that the color space of all base color maps is X. For our purposes a similar idea could be: THREE.ColorManagement.textureColorSpace = DisplayP3ColorSpace; But still, yes, the user will certainly need to do some configuration to have wide-gamut color. |
Thinking... Do we need to explicitly differentiate between "not color data" and "unspecified color space", or can
I'm inclined to agree. I don't think the renderer should try to be so smart, lest it become too smart by half. |
So far I haven't been able to think of a case where we'd need both. Ok, it sounds like inferring texture color space doesn't currently belong in the material or renderer classes, so I'm happy to close out the PR for now. 👍 |
If that is the case, I agree |
An alternative to this PR... how do others feel about adding support for inferring texture color space from naming conventions? To my understanding some naming conventions are common in game engines, though I don't know if they're used for color space inferrence.
I'm not sure I'd want that on by default, but it should be easy enough to support an API, either in ColorManagement or TextureLoader, by which users can register their own naming convention — THREE.TextureLoader.setColorSpaceRules({
'_diffuse': THREE.SRGBColorSpace,
'_emissive': THREE.SRGBColorSpace,
'_occlusion': THREE.NoColorSpace,
'_metalness': THREE.NoColorSpace,
'_roughness': THREE.NoColorSpace,
}); Color spaces would be applied by TextureLoader, if a suffix matches the texture's filename. Model loaders can (and already do) override color space themselves. Related: |
I don't know if I love relying on filenames 😅 I might have mentioned this in another issue - but it would be good to know what the expected file format options are for p3 or other wide-gamut color content. In the case of PNG it will be ambiguous and using Depending on what the problem we're trying to solve here is we might consider adding another loader like But overall I think what you recommend in w3c/ColorWeb-CG#112 is the best option, though it will probably be awhile before it's available. |
Mainly the problem I'm trying to solve is that users don't know which textures should use which color space (or NoColorSpace). Even if we provided a complete list of recommendations, applying the color spaces correctly to every texture every time is verbose, e.g. in R3F it's something like... const map = useTexture('path/to/diffuse.png', (texture) => {
texture.colorSpace = THREE.SRGBColorSpace;
return texture;
});
I think that's a strength of filename conventions over the original PR here. If the user is authoring wide-gamut content they can simply adjust the map: THREE.TextureLoader.setColorSpaceRules({
'_diffuse': THREE.DisplayP3ColorSpace,
'_emissive': THREE.DisplayP3ColorSpace,
'_occlusion': THREE.NoColorSpace,
'_metalness': THREE.NoColorSpace,
'_roughness': THREE.NoColorSpace,
}); I don't necessarily think we should provide any default naming convention – much less one that encompasses wide-gamut color spaces. But I'm looking for methods users can set up once, or copy/paste from an example, rather than thinking about it on every texture load. :/ I'm not optimistic about w3c/ColorWeb-CG#112 solving this completely. Even if the feature is added, non-color maps often carry sRGB ICC profiles, and detecting SRGBColorSpace vs. NoColorSpace may remain hard. That may provide enough signal to identify Display P3 images correctly though. |
At the least I think users may understand which colors are "color" data and which ones are not when they're loading them - maybe not? But if they do then providing a separate loader specifically designated for color textures that auto-assigns a more sensible color space may be more intuitive.
fwiw these are both something that can be built now as a three.js example module that extends TextureLoader. But either way it's not a silver bullet. Content and textures using different color spaces can still be loaded into a single scene.
That may be right... Maybe more of a reason in that case to provide a texture loader specifically for color maps that tries to determine the right color space. And no-color-space textures would still use regular TextureLoader. |
Related issue:
Description
Updates THREE.MeshBasicMaterial and THREE.MeshStandardMaterial to infer the color space of assigned textures. This is possible based on a couple of assumptions:
.colorSpace === THREE.NoColorSpace
(default), THREE.NoColorSpace can safely be interpreted as "unknown" or "unspecified".type
propertyThere are limitations to this approach:
Just an idea — I don't yet feel confident enough about this to include it in r152 with the other color management changes.