three.js
three.js copied to clipboard
WebGLRenderer: Difference between Scene.background and setClearColor()
Using Scene.background
and WebGLRenderer.setClearColor()
produces the same output in the following demos:
Scene.background
: https://jsfiddle.net/xkf3o8uw/5/
setClearColor()
: https://jsfiddle.net/xkf3o8uw/4/
However, when setting autoClear
to false
, the behavior is different:
Scene.background
: https://jsfiddle.net/0o38d67m/
setClearColor()
: https://jsfiddle.net/xkf3o8uw/2/
Scene.background
still works because of this line in Scene.background
:
https://github.com/mrdoob/three.js/blob/a4f742c7d7b61f3efae147235efb0b5bc73e6e03/src/renderers/webgl/WebGLBackground.js#L52
What is the reason for this discrepancy? Does it just mean Scene.background
used with a color should be decoupled of autoClear
settings?
Does it just mean Scene.background used with a color should be decoupled of autoClear settings?
Yes -- for a host of reasons...
This will be a breaking change -- but for the better. I think scene background as a color should behave identically to scene background as a solid texture.
Setting the renderer's clear color has completely different behavior.
I think scene background as a color should behave identically to scene background as a solid texture.
Do you mind explaining why you said that? It seems this is already the case, see https://jsfiddle.net/5j2uktdg/.
Yes -- for a host of reasons...
Do you mind mentioning them^^?
My feeling is that the behavior of scene.background when set to a solid color should be consistent when scene.background is set to a texture. Looking at the code when using a cube texture with scene.background the depth and stencil buffers are not overwritten but the color is written to regardless of whether or not renderer.autoClear is set to true. My guess is the background was cleared when the background was a solid color in an effort to make the behavior between the two cases more consistent. Possibly just the color buffer should be cleared with the background color if it is set to a color rather than clearing the depth and stencil, as well:
https://github.com/mrdoob/three.js/blob/a4f742c7d7b61f3efae147235efb0b5bc73e6e03/src/renderers/webgl/WebGLBackground.js#L66-L78
Thanks for clearing things up. Indeed, if you use a color for Scene.background
a full clear is executed even when autoClear
is set to false
. If a texture is used, no clear happens but the color buffer is overwritten with the background mesh.
Possibly just the color buffer should be cleared with the background color if it is set to a color rather than clearing the depth and stencil, as well:
That sounds good to me!
Do you mind mentioning them^^?
Sure.
renderer.setClearColor( 0xff0000, 0.5 ); // the behavior is as-expected
- supports alpha
- ignores viewport
- ignores outputEncoding
- ignores tonemapping
- honors scissor
scene.background = new THREE.Color( 0xff0000 ); // it currently behaves similar to clear color
- does not support alpha
- ignores viewport
- ignores outputEncoding
- ignores tonemapping
- honors scissor
scene.background = new THREE.DataTexture( new Uint8Array( [ 255, 0, 0 ] ), 1, 1, THREE.RGBFormat );
- does not support alpha
- honors viewport
- honors outputEncoding
- honors tonemapping
- honors scissor
- honors encoding
I think that is all correct....
And for consistency, the scene background color should be assumed to be in linear colorspace. Currently it is an unusual special case.
Be aware that In addition to clear color, fog-color is also currently in output color space. And it is not tonemapped.
See https://github.com/mrdoob/three.js/pull/11076#issuecomment-293567895.
+1
That forceClear = true
got me real confused this morning, I didn't expect Scene.background
to still clear the color even if autoClear === false
😕 ! For that reason, I ended up not using Scene.background
at all.