Skip to content
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

Initial color management support #26869

Closed
wants to merge 2 commits into from
Closed

Initial color management support #26869

wants to merge 2 commits into from

Conversation

ghost
Copy link

@ghost ghost commented Mar 10, 2019

This adds LUT based color management on the Rasterizer layer, to ensure that all content blitted
to screen are processed exactly once. Rasterizer::set_screen_lut and VisualServer::set_screen_lut are added. Implemented for both GLES3 and GLES2.

The feature is accessible under Editor Settings / Interface / Color Management. It depends on LittleCMS to handle ICC profiles. This implements #26826.


EDIT: Updated OP to reflect current state of the branch. Again.

@ghost ghost requested review from reduz and a team as code owners March 10, 2019 13:40
@Calinou
Copy link
Member

Calinou commented Mar 10, 2019

The feature is put behind a new command line flag --cm-lut, as I don't believe the interface is suitable for end users yet. Note that the flag is lost when you open an editor from the project manager.

Would this be better suited as an editor setting? This way, it would be preserved when editing a project using the Project Manager.

@ghost
Copy link
Author

ghost commented Mar 10, 2019

Would this be better suited as an editor setting? This way, it would be preserved when editing a project using the Project Manager.

Possibly, although I don't think it's very easy to use right now You still have to generate the LUT outside Godot somehow. I think an option for an ICC profile would be more fitting for an editor setting, in that it's an "easy" interface. That requires dependency (or a new ICC profile parser) however.

I can make it an editor setting if that's ok. Could you enlighten me a bit on the proper place in the code base to add a new setting?

@JFonS
Copy link
Contributor

JFonS commented Mar 10, 2019

Related to #26101 by @QbieShay.

@ghost
Copy link
Author

ghost commented Mar 10, 2019

#26101 and this PR address different needs. The former is for "in-game" grading (artistic effect), while this one is for global output gamut conversion (sRGB -> device gamut), intended to be used with the editor.

@groud
Copy link
Member

groud commented Mar 10, 2019

I am not sure this needs to be in the core. I think it might better suit a plugin.

@ghost
Copy link
Author

ghost commented Mar 11, 2019

I am not sure this needs to be in the core. I think it might better suit a plugin.

This needs to happen in Rasterizer to ensure that all output to screen are processed exactly once. I'm not aware of a way to plug into the Rasterizer. This cannot be a Node because:

  • A Node can be added multiple times. As a result, some content can be transformed more than once.
  • A Node is not guaranteed to be processed as the last step of rendering. As a result, some content may get rendered without being transformed.
  • Viewports can be attached to the screen directly, which will skip any Node-based post-processing. The function used to do this is blit_render_target_to_screen, which is where I put the code.

Because this feature is for color space conversion, not artistic effect, all the situations above are entirely undesirable. That leaves me no options other than putting it in the core. For more detailed background of this PR please see #26826.

@ghost
Copy link
Author

ghost commented Mar 11, 2019

Minor correctness fix in the shader and rebased on current master.

Moved clamp before texel alignment, so in the off case that HDR data is passed to this shader it would not wrap and print bad colors.

@ghost ghost requested a review from akien-mga as a code owner March 11, 2019 06:32
@ghost
Copy link
Author

ghost commented Mar 11, 2019

I have pushed an alternate version which allows users to choose an ICC profile in editor settings. It depends on LittleCMS for profile handling.

@Calinou Do you think this is better?

@groud
Copy link
Member

groud commented Mar 11, 2019

It does not need to be in the rasterizer. You can use a screen shader to do so.

@ghost
Copy link
Author

ghost commented Mar 11, 2019

It does not need to be in the rasterizer. You can use a screen shader to do so.

So where do I apply this screen shader?

@groud
Copy link
Member

groud commented Mar 11, 2019

I would say by using a Color rect node, taking the full scree size, and using SCREEN_TEXTURE as input. But indeed that requires that you have only one of them, and that it is put on top of your display.

But I mean, it might be OK as built-in, as long as it is a needed feature. Which I am not sure it is in the general case.

@Zireael07
Copy link
Contributor

SCREEN_TEXTURE does not take into account stuff using transparent pipeline, though (so anything with alpha won't show)

@QbieShay
Copy link
Contributor

@groud in that case I vote for world environment

@groud
Copy link
Member

groud commented Mar 11, 2019

@groud in that case I vote for world environment

Yeah it might make sense there.

@ghost
Copy link
Author

ghost commented Mar 11, 2019

@groud I'm not exactly sure how I can make sure that the ColorRect stays where it should without touching core stuff. AFAIK anyone can just place Nodes where they like.

I certainly believe this is needed as I need it, but I do understand that the rest of the community may not care about working with other color managed applications. If the community decides that this is unnecessary I'll respect the verdict.

@QbieShay This feature and your contribution work together. Where artist can use your tools to convey their vision, color management ensures that the exact vision is shown on the screen as correctly as possible.

@groud
Copy link
Member

groud commented Mar 11, 2019

AFAIK anyone can just place Nodes where they like.

Yeah, but that's not a problem. It is not up to us to check if users are using a node correctly (we must document things though) It's like, you cannot complain about one of your camera not working if you put two cameras in your tree.

Anyway, I think that if it should be built in it has to be a parameter of a WorldEnvironment node, as @QbieShay suggested.

@ghost
Copy link
Author

ghost commented Mar 11, 2019

AFAIK anyone can just place Nodes where they like.

Yeah, but that's not a problem. It is not up to us to check if users are using a node correctly (we must document things though) It's like, you cannot complain about one of your camera not working if you put cameras in your tree.

Anyway, I think that if it should be built in it has to be a parameter of a WorldEnvironment node, as @QbieShay suggested.

It appears that you have misunderstood the purpose of color management. This is not related to WorldEnvironment and is not something artists tweak or even put into the end game. It's for the editor itself, so that colors are correctly translated from sRGB to the color space of your monitor, so that they do not appear over-saturated and blown out.

WorldEnvironment does not work with 2D and most importantly does not reach the Editor UI, so it doesn't cover the use case at all.

@groud
Copy link
Member

groud commented Mar 11, 2019

Ah indeed sorry. If it's required for specific hardwares and in the editor it indeed has to be built in. Sorry for the inconvenience.

@ghost
Copy link
Author

ghost commented Mar 11, 2019

No inconvenience felt. It's sad but true that color management is little known or understood outside the artist/photographer crowd, but it's a great thing and we should work to make it more mainstream!

@akien-mga akien-mga added this to the 3.2 milestone Mar 11, 2019
@ghost ghost requested a review from neikeq as a code owner March 16, 2019 12:36
@ghost
Copy link
Author

ghost commented Mar 16, 2019

Added support for GLES2.

I accidentally created a doppelganger commit while rebasing which triggered a review from neikeq because apparently I can't count commits... It's removed now.

@ghost ghost changed the title Initial color management support on GLES3 Initial color management support Mar 16, 2019
@akien-mga akien-mga removed the request for review from neikeq April 1, 2019 09:34
@ghost
Copy link
Author

ghost commented May 3, 2019

Rebased on current master branch.

@fire
Copy link
Member

fire commented May 30, 2019

Sounds good.

@ghost
Copy link
Author

ghost commented Jun 23, 2019

Rebased and resolved merge conflicts.

@fire
Copy link
Member

fire commented Jul 5, 2019

Some errors compiling on windows:

1>cl : Command line warning D9025: overriding '/w' with '/W3'
1>cl : Command line warning D9002: ignoring unknown option '-std=c99'
1>cl : Command line warning D9002: ignoring unknown option '-O3'
1>cmscgats.c
1>thirdparty\lcms2\cmscgats.c : warning C4828: The file contains a character starting at offset 0x2748 that is illegal in the current source character set (codepage 65001).

Will report what happens when I start Godot.

@fire
Copy link
Member

fire commented Jul 5, 2019

I tried the PR it works. If I apply the icm profile twice by removing it and applying it causes the editor to turn darker than normal. Not sure if it's related.

image

@fire
Copy link
Member

fire commented Jul 5, 2019

Here is some research for how to fetch the device's icc profile and links:

@ghost
Copy link
Author

ghost commented Jul 5, 2019

If I apply the icm profile twice by removing it and applying it causes the editor to turn darker than normal. Not sure if it's related.

@fire There is an unrelated bug in Godot where the background dim from modal dialogs (e.g. engine settings & file browser) will persist after closing in some cases. That one looks like what you're getting. It may have something to do with the lag that LUT generation introduces triggering the bug, but I don't think fixing that is within this PR's scope.

errors compiling on windows

I'll check the build scripts on Windows as soon as possible.

how to fetch the device's icc profile

Thanks for the pointers. I'll get to it after/if the base functionality get merged.

@fire
Copy link
Member

fire commented Jul 5, 2019

@toasteater Can you point me to the bug number for the background dim?

@ghost
Copy link
Author

ghost commented Jul 6, 2019

@fire Didn't find an existing report, so I reported it at #30368, along with a way to reproduce it.

EDIT: Hopefully resolved Windows build warnings.

@akien-mga
Copy link
Member

Since this impacts the renderer and conflicts with the work done in the vulkan branch, this will have to wait for after the 3.2 release to be merged. At that point it will also need to be rebased once the vulkan branch is merged in master.

It can still be reviewed and tested as is, but merging it now would make rebasing the vulkan branch trickier (and this wouldn't be implemented for Vulkan either).

@akien-mga akien-mga modified the milestones: 3.2, 4.0 Jul 29, 2019
toasteater added 2 commits August 1, 2019 06:21
Use VisualServer::set_screen_lut to set a 3D texture for color management.
Its X, Y, Z axes correspond to R, G, B channels.

LUT transformation happens in Rasterizer, ensuring that all content blitted
to screen are processed exactly once.

This implements part of #26826.
This module adds Color Management to engine settings. It depends on LittleCMS
for ICC profile handling, and LUT support in Rasterizer for rendering.

This completes #26826.
@fire
Copy link
Member

fire commented Aug 21, 2019

@toasteater Since the vulkan branch has a 2d branch in theory we could try this in the editor.

@ghost
Copy link
Author

ghost commented Aug 22, 2019

@fire I don't see a separate 2d branch. Maybe I don't have the permissions? In any case I'd rather wait until things get more stable, after it's merged in master at least. 4.0 still seems very far away, I don't think rebases make sense currently.

That's said, if anyone wants to pick this feature up and start maintaining it for vulkan right now, please feel free to do so. From what I've seen about the vulkan branch, you probably have to do the rasterizer stuff from scratch, so the only thing you could reuse is the cm module, which is just rather trivial glue. If anyone is interested, please let me know!

@ghost
Copy link
Author

ghost commented Sep 4, 2019

Closing because I no longer have the intention to port the feature to 4.0. Again, if anyone is willing to pick this up, please feel free to do so.

@ghost ghost closed this Sep 4, 2019
@fire
Copy link
Member

fire commented Sep 4, 2019

I want to have this feature in 4.0. Is there anything you suggest I can do?

@ghost
Copy link
Author

ghost commented Sep 4, 2019

There are two commits in this PR. The first one adds LUT support at Rasterizer level, and the second one adds lcms glue and the user interface. Only the first one should conflict with vulkan.

I think if you implement set_screen_lut and modify blit_render_targets_to_screen for RasterizerRD, you can just cherry-pick the second commit and it should just work. For blit_render_targets_to_screen you need to write a shader to sample the LUT. Texel offset must be taken into consideration, or you'll get wrong colors from interpolation. The LUT itself is a cube texture with X as R, Y as G, Z as B.

The sampling has to happen at blit_render_targets_to_screen (instead of, say, during tonemapping), to ensure that everything is transformed once and only once.

@fire
Copy link
Member

fire commented Jan 14, 2020

@toasteater Is it ok to change the design so the lut is per rendertarget?

@ghost
Copy link
Author

ghost commented Jan 15, 2020

Why would you want to do that? How are you going to make sure the colors are transformed exactly once?

Keep in mind that this is for correct display on devices, not artistic effect.

@fire
Copy link
Member

fire commented Jan 15, 2020

I was trying to figure out how to do per screen color correction, but godot doesn't have an api for that.

@ghost
Copy link
Author

ghost commented Jan 15, 2020

I believe Godot is single-windowed-only at this moment? I don't think window managers allow us to see which part of the window is on which screen anyway. I have only seen applications that switch profiles depending on which screen it's mostly staying on, but not ones that do split rendering. It's probably too much work to be worthwhile for most cases.

@ghost
Copy link
Author

ghost commented Jan 15, 2020

Also, there were a lot of misunderstandings in the thread, and I see that it still persists, so I think it bears repetition here at the bottom:

To whoever it may concern:

Please do bear in mind that this is NOT for artistic effects. It DOES NOT replace the environment effect that is called "color correction", which should be used for artistic effects. It should not be applied in any way, other than for each pixel rendered to the screen, uniformly, and exactly once, as the last step of rendering. Literally any other way to use it is a misuse.

@fire
Copy link
Member

fire commented Jul 10, 2021

I am salvaging this.

This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants