WebGLRenderTarget and scene.background has tonemapping issues
Description
scene.background = new THREE.Color("white")
...
gl.render(scene, camera)
produces a white background, i don't think three applies tm here
but the same thing on a fbo (mapped to a mesh-material) produces a gray background, presumably because threejs then tonemapps the result
state.gl.setRenderTarget(fbo)
state.gl.render(scene, camera)
state.gl.setRenderTarget(null)
...
const plane = new THREE.PlaneGeometry/(
const material = new THREE.MeshBasicMaterial({ map: fbo.texture })
const mesh = new THREE.Mesh(plane, material)
in this image you have the rendertarget in the middle, with a white scene.background just like the rest of the scene, but it appears gray, not white.
tonemapping with envmap background is fine
tonemapping with a background white plane instead of scene.background is fine
Live example
- https://codesandbox.io/p/sandbox/shadermaterials-forked-7r5knf
Screenshots
No response
Version
r0.167.0
Device
Desktop
Browser
Chrome
OS
MacOS
Related
- https://github.com/mrdoob/three.js/issues/22340#issuecomment-899684871
- https://github.com/mrdoob/three.js/issues/22340#issuecomment-2206457434
thanks for the context @hybridherbst this at least explains what is going on.
I'm not sure it was ever discussed before but maybe it would be a solution for WebGLRenderer: Instead of using gl.clear(), couldn't we apply a clear color similar to a textured background by rendering a colored (full screen) quad? In this way, background colors behave like textured backgrounds or skyboxes.
The colored plane mesh would be pushed at the very beginning of the opaque render list and writes no depth. In this way, subsequent render items shouldn't be affected. Does somebody see an obvious flaw compared to gl.clear()?
There is also a related issue with fog: https://github.com/mrdoob/three.js/pull/26857#issuecomment-1767943622
At least with WebGPURenderer all of these issues are already solved. Hopefully we get this fixed in WebGLRenderer as well.
Rendering a full screen quad is usually slower than gl.clear() on tiled GPUs (so, mobile), this would probably reduce framerate.
I wonder if the performance degradation would actually be noticeable as a lower frame rate. This is something that should be tested if the approach is given a try.