three.js icon indicating copy to clipboard operation
three.js copied to clipboard

WebGLRenderer: Difference between Scene.background and setClearColor()

Open Mugen87 opened this issue 3 years ago • 7 comments

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?

Mugen87 avatar Aug 16 '21 09:08 Mugen87

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.

WestLangley avatar Aug 16 '21 12:08 WestLangley

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^^?

Mugen87 avatar Aug 16 '21 15:08 Mugen87

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

gkjohnson avatar Aug 16 '21 16:08 gkjohnson

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!

Mugen87 avatar Aug 16 '21 16:08 Mugen87

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.

WestLangley avatar Aug 16 '21 17:08 WestLangley

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.

WestLangley avatar Aug 16 '21 21:08 WestLangley

+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.

wmcmurray avatar Jul 28 '22 19:07 wmcmurray