-
-
Notifications
You must be signed in to change notification settings - Fork 35.4k
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
Roadmap for a color-managed workflow in three.js #23614
Comments
/cc @bhouston @gkjohnson @WestLangley I'm opening this is a higher-level tracking issue, since (a) any particular PR may be closed and lose that discussion context, and (b) more changes are needed than just #23392. |
From my perspective this is nearly done. Aside from FBX the most common format loaders and exporters are converted to handle the current three.js color system correctly. The rest I think are less commonly used and / or I don't know a lot about. It would be nice if someone could help with the FBXLoader and example conversion. |
#23392 (1.5) has been merged, and I'm hoping #23430 (1.1) will also make it into r139. At this point we may want to pause for a release or two, and see if there's feedback from users adopting the new |
Not going to push too hard if others feel this is out of scope, but I wonder if we should consider enabling |
That would be amazing! It was always a hack to make it false, but it was required initially until we settled on it being the right solution: #8260 |
Feedback from the R3F folks (pmndrs/react-three-fiber#2127) has been that switching old demos to What is WebGPURenderer doing in terms of |
when we switched to physicallyCorrectLights it seemed a change that is too big to just put out there. it didn't seem straight forward to restore projects and demos, everything turned pitch black. two properties (decay and intensity) didn't make it easier to comprehend how to fix it. when three makes it the default i think it should first educate people how to use it properly, similar to colormanagement.legacy=false and the new article explaining everything. as for color management, react+three + eco system uses it by default now. i have already updated most sandboxes and everything works great. i love being able to omit the occasional convertSRGBToLinear and everything behaves much more consistent. |
What we could do is to make If a developer uses However, I do not know how to change the lights |
I don't feel strongly on whether the Perhaps we could change the |
I'm glad this discussion came up^^. I have not added |
Hmmm, I think I'm willing to try changing the default to 2 (this month maybe) and see what happens... |
One more for the list – GammaCorrectionShader probably should be renamed to match up with the successor to For example: composer.addPass( new ShaderPass( ColorSpaceTransformShader ) ); Other ideas:
I'm not sure how to provide configuration options on a Shader object, but in current usage this would be Linear-sRGB to sRGB (the same as GammaCorrectionShader). |
|
BTW: I wonder if we could avoid the |
I'm happy with OutputColorSpaceShader if @WestLangley approves. 👍
It's also helpful to look at how desktop software like Blender and Maya (both using OpenColorIO) refer to these concepts:
The term "display" is usually involved in describing our equivalent of output color space, whereas "view" and "look" transforms refer to tone mapping. Not a perfect analogy though – desktop software can render more directly to the display, but we're constrained to writing to a Canvas (implicitly sRGB), regardless of what the final display might be. Or the result might be a file rather than a display of course. Perhaps "output" is better than "display" in our context, for these reasons. |
Maybe remove // The thing that is confusing, IMO, is something I mentioned previously. The terminology has changed, but the issue is the same: when rendering to a render target, do you honor the renderer's settings -- or the render target's texture settings? |
Maybe |
This is also fine with me. Is there a way for Shader objects to take configuration parameters? If not, we just need to be aware that the generically-named ColorSpaceShader will only do Linear-sRGB to sRGB conversions for the moment.
So the color space of a render target used throughout a post-processing chain should be decoupled from the output color space written to a Canvas. I can't quite tell how this works today – it looks like neither the renderer's nor the render target's encoding is determining the output-to-canvas color space (when post-processing uses Linear-sRGB throughout the internal chain), we instead specify an explicit GammaCorrectionShader and ignore encoding properties? |
I mean that in terms of encoding, no render target (i.e. renderer renders scene in linear color space - it applies post-processing effects that are working in linear color space - renderer converts the output to the color space of the render target - it applies post-processing effects that are working in output color space (linear or srgb) |
Can we avoid (or even deprecate) GammaCorrectionShader in that case? So output to the correct color space is not a separate pass in post-processing. I could — for example — make my last pass a DitherPass applied to linear colors, then write 8-bit sRGB output in the same pass. |
With what I proposed the renderer (and not the passes) will authomatically convert the output to the correct space and then yes, GammaCorrectionShader is not needed at all. |
Remaining work related to r152:
I believe (1) is necessary for r152, where (2) and (3) can be completed on a best-effort basis before or after the release. I'll work on (1) next. |
Since this release potentially needs more explanation, I wonder if it's best to write a topic at the forum similar when we removed https://discourse.threejs.org/t/three-geometry-will-be-removed-from-core-with-r125/22401 My impression is the community met both topics with positive response since they allowed users to ask related questions without filing new topics or issues. The structure of the topics (consequences of the change, motivation, migration tasks and a roadmap) also provide a compact overview since most users do not follow the entire discussion at GitHub. I think it's best to write a similar announcement for next week as an addition to the migration guide. @donmccurdy Since you are working on (1), do you think you can use the contents of your migration guide to build such a topic? |
Thanks @Mugen87, that's a great idea. I'll plan to post something on the forum early next week, and perhaps we link there from the migration guide. |
Awesome topic! I've pinned it globally for a month so it should be clearly visible for all forum users. |
Amazing @donmccurdy! 🙏🙏🙏 Nit:
How about |
Done! ✅ |
@donmccurdy Is there any ETA on P3 color support? I've had to abandon three.js as a solution because color accuracy for our application is mission-critical and we could not get accurate colors. Would love to re-integrate three but this is holding us back. Would be willing to assist if required. Thank you. |
Hi @mad-wizard! While I could be misunderstanding the issues you've encountered, I expect that a Display P3 workflow can solve "color accuracy" problems by itself if — and only if — you're using a fully unlit (no lighting) scene. For example, photogrammetry or baked lights. Is that the case here? In a lit scene, it's more likely that image formation (tone mapping, exposure, lighting, etc.) are the relevant concerns. If you aren't using tone mapping yet, then it's much too early in the image formation process to be worried about Display P3. 🙂 I believe it would also be fair to say that our current tone mapping options could be improved... if this sounds like it would be of interest, would you mind starting a new issue on the color accuracy problems you're facing? I'd also be interested in whether you've found alternatives to three.js that solve the problem better, or whether the problem remains completely unsolved for now. P.S. It's a deeper dive, but @elalish's writing on glTF Color Accuracy may provide helpful background. |
Thanks for the response! Yes I am using a texture rendered on a plane with an unlit material (MeshBasic). I have tried many encoding and color space changes and have isolated the problem; images taken with modern iPhones use the P3 color profile which has a wider gamut than sRGB. When these images are rendered in three.js they appear washed out. Here is an example of a P3 image. https://goldeneye.nyc3.cdn.digitaloceanspaces.com/woman.png I tried downloading the repo and replacing the texture of the crate in one of the examples with the above image of the woman, that should be a way for you to easily reproduce the issue. Since we are making a photo editing app, color quality is mission critical so we were on the verge of abandoning three.js, then this morning I was able to find a work-around where we convert the p3 profile to srgb manually and then use the processed texture in three.js this is not an ideal workaround. We want to use three.js to implement 3D effects and more advanced features than other photo editing apps. On an unrelated side-note, do you happen to have any idea on how we could implement photo filters using three.js for this type of app? Best Callan |
Independent of supporting the Color Space we need a way of determining what color space is used by a loaded texture. Currently there's no way to determine the color space of an image even if it's correctly embedded (see #21336). And even then when I use image magick to inspect the embedded color space of the image provided it says it's
In the interest of keeping issues on topic - you can ask questions at the forum: https://discourse.threejs.org/ |
Color space information embedded in PNG or JPEG images is very unreliable, unfortunately. The ICC Profile appears to have the correct information. I'm viewing this as a web platform issue – as things stand, we can't do it automatically. Perhaps it should be escalated to a W3C working group. In the meantime, and for the foreseeable future, users must identify the color space of their textures with Support for rendering lit scenes in wide color gamuts will be difficult. Support for rendering unlit scenes, much less so. But I'm unsure if we want to attempt one without the other. Perhaps this issue can now be closed, and another opened to discuss support for wide-gamut color spaces in three.js? This thread has probably covered enough territory already. 😅 |
I can share some ruby code I am using to convert the image from P3 to SRGB. It uses mini-magick: def convert_to_srgb!
unique_filename = "#{original.filename}-#{SecureRandom.uuid}"
download_path = Rails.root.join('tmp', unique_filename)
File.open(download_path, 'wb') { |file| file.write(original.download) }
image = MiniMagick::Image.open(download_path) # open with imagemagick
color_profile = image["%[profile:icc]"] # get color profile
unless color_profile.include?("Display P3") # if image is not p3, return
File.delete(download_path) if File.exist?(download_path)
return
end
image.combine_options do |b| # convert p3 color profile to sRGB
b.profile("#{Rails.root}/colors/P3.icc")
b.profile("#{Rails.root}/colors/sRGB.icc")
end
original.attach(io: File.open(image.path), filename: original.filename.to_s, content_type: original.content_type)
File.delete(download_path) if File.exist?(download_path)
end |
To be continued in #26479. |
Ha how nice that they keep two out of sync fields with color space information 😅
|
Overview
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:
Roadmap
renderer.outputEncoding
→renderer.outputColorSpace
texture.encoding
→texture.colorSpace
texture.colorSpace
default toTHREE.NoColorSpace
(e.g. normal maps)Ensure intermediate frame buffers have sufficient bit depth for their color space.See outputEncoding not handled correctly when using sRGB render target in WebGL2 #23251 (comment). No changes required.CubeTextureLoader
return sRGB cube textures by default.renderer.useLegacyLights
default tofalse
useLegacyLights
, change default tofalse
. #26392Timing 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.
ColorManagement.workingColorSpace
ColorBufferAttribute
?)Continued in #26479.
The text was updated successfully, but these errors were encountered: