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

WebGLRenderTarget: Allow opt-in for output transforms / image formation #29429

Open
donmccurdy opened this issue Sep 17, 2024 · 1 comment
Open

Comments

@donmccurdy
Copy link
Collaborator

donmccurdy commented Sep 17, 2024

Description

In recent three.js versions,renderer.outputColorSpace, render.toneMapping, and renderer.toneMappingExposure (jointly, the image formation step) are applied only when writing to the canvas drawing buffer (or WebXR) and disabled when writing to a render target. I think that's the right default. But it does constrain users' choices, and can force an additional (expensive!) pass in a post-processing stack. Based on feedback, this is problematic for mobile applications.

Solution

I'd like to suggest that we add a new property to WebGLRenderTarget, perhaps called target.needsOutputTransform. If enabled, WebGLRenderer would apply ...

when drawing to that render target. I believe renderer.outputColorSpace is not relevant here, since the render target already has a .colorSpace property.

Alternatives

Alternatively, we could make WebGLRenderer always apply these settings when drawing to a render target, and require explicit changes to the renderer's properties by the user. I expect this would be a significant breaking change, however.

Additional context

I don't know what this looks like in WebGPURenderer, or whether similar changes would be required there.

/cc @WestLangley

@donmccurdy
Copy link
Collaborator Author

donmccurdy commented Sep 20, 2024

I believe renderer.outputColorSpace is not relevant here, since the render target already has a .colorSpace property.

Hm. If the user's intention is to force blending in a particular color space like sRGB (building a 2D compositing application, for example) then expressing that in terms of the render target's color space won't be correct. WebGL will decode an sRGB framebuffer to linear when doing blending, it blends in linear when writing to both linear and sRGB framebuffers. In contrast to writing to the drawing buffer, where it blends in sRGB. So instead, the custom blending space use case might require:

renderer.outputColorSpace = SRGBColorSpace;

const target = new WebGLRenderTarget(width, height, {
  type: HalfFloatType,
  colorSpace: NoColorSpace, // ???
  needsOutputTransform: true
});

I don't love that; this needs some thought.

Context: https://discourse.threejs.org/t/wrong-colors-in-transparent-materials-when-using-effectcomposer-post-processing/70895

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

No branches or pull requests

2 participants