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

Reflector Color Space Issues #24384

Closed
WestLangley opened this issue Jul 23, 2022 · 4 comments · Fixed by #24386
Closed

Reflector Color Space Issues #24384

WestLangley opened this issue Jul 23, 2022 · 4 comments · Fixed by #24386

Comments

@WestLangley
Copy link
Collaborator

I am opening this as a separate issue in the hope we can keep the discussion focused.

Note that "color space" and "encoding" have still not been decoupled in the shader, so I am using legacy terminology here. Hopefully that will end soon.

  1. Reflector should render in scene-referred linear color space -- to a float or half-float render target. (Or to an RGBM-encoded UInt8 render target.) This is true, regardless of the renderer's output encoding. Setting the Reflector's renderTarget.texture.encoding to renderer.outputEncoding is not the right thing to do.

  2. Consequently, it is only correct to include encodings_fragment in the reflector's fragment shader if it is needed for something like RGBM encoding. But three.js no longer supports such encodings.

  3. When encoding to sRGB color space, tone mapping must proceed encoding. This is to ensure the inputs to the encoding step are in LDR. Reflector includes the encoding fragment, but not tone mapping fragment. Ideally, it should not include either of them.

Granted, encoding to sRGB and then decoding to linear-sRGB when reading back should not make a vast visual difference, except for rounding due to the Uint8 conversion. But still, it is unnecessary.

Feedback welcome.

three.js version: [r.142]

@Mugen87
Copy link
Collaborator

Mugen87 commented Jul 25, 2022

Ideally, it should not include either of them.

Reflector renders the scene from a virtual camera to a render target and then projects the respective texture onto its surface. The reflector's shader (which performs the projection) is equivalent to built-in materials, meaning it's fragment shader has to output the color in the same space defined in renderer.outputEncoding.

If encodings_fragment is going to be removed, how would be the color conversion be implemented when using the reflector within a sRGB workflow?

@WestLangley
Copy link
Collaborator Author

WestLangley commented Jul 25, 2022

The reflector's shader (which performs the projection) is equivalent to built-in materials

@Mugen87 You are correct. That is a very good way of thinking about it.

The reflector should include the tone mapping fragment.

@Mugen87
Copy link
Collaborator

Mugen87 commented Jul 25, 2022

The reflector should include the tone mapping fragment, however.

If we just include tonemapping_fragment and do nothing else, the code is not right. The problem is that the beauty pass of the reflector (rendered with the virtual camera) is already tone mapped. If tonemapping_fragment is added to the reflectors shader, tone mapping would be applied twice.

This can only be fixed if tone mapping is disabled when the beauty pass is performed (and then enabled back again). The code for this needs to be placed around this line of code:

renderer.render( scene, virtualCamera );

I would say it's indeed more correct to add the tone mapping fragment and update Reflector.onBeforeRender() as described above. The same should be done for Refractor.

@WestLangley
Copy link
Collaborator Author

WestLangley commented Jul 25, 2022

I am inclined to agree with what I intended to say in my original post, but did not say very precisely.

  1. When rendering with the virtual camera to the render target texture, rendering should be in scene-referred linear colorspace: no tone mapping, and no encoding (if floating point textures are supported). The render target texture is an HDR texture with linear encoding.

  2. When rendering with the real camera, both tone mapping and encoding should be included in the Reflector's shader.

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 a pull request may close this issue.

2 participants