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

WebGLRenderer: Fix incorrect background color space when setting scene.background to color #28434

Merged
merged 4 commits into from
May 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified examples/screenshots/webgl_materials_car.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 10 additions & 5 deletions src/renderers/WebGLRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,8 @@ class WebGLRenderer {

const _emptyScene = { background: null, fog: null, environment: null, overrideMaterial: null, isScene: true };

let _renderBackground = false;

function getTargetPixelRatio() {

return _currentRenderTarget === null ? _pixelRatio : 1;
Expand Down Expand Up @@ -1153,8 +1155,8 @@ class WebGLRenderer {

}

const renderBackground = xr.enabled === false || xr.isPresenting === false || xr.hasDepthSensing() === false;
if ( renderBackground ) {
_renderBackground = xr.enabled === false || xr.isPresenting === false || xr.hasDepthSensing() === false;
if ( _renderBackground ) {

background.addToRenderList( currentRenderList, scene );

Expand Down Expand Up @@ -1199,7 +1201,7 @@ class WebGLRenderer {

}

if ( renderBackground ) background.render( scene );
if ( _renderBackground ) background.render( scene );

for ( let i = 0, l = cameras.length; i < l; i ++ ) {

Expand All @@ -1213,7 +1215,7 @@ class WebGLRenderer {

if ( transmissiveObjects.length > 0 ) renderTransmissionPass( opaqueObjects, transmissiveObjects, scene, camera );

if ( renderBackground ) background.render( scene );
if ( _renderBackground ) background.render( scene );

renderScene( currentRenderList, scene, camera );

Expand Down Expand Up @@ -1430,7 +1432,8 @@ class WebGLRenderer {
samples: 4,
stencilBuffer: stencil,
resolveDepthBuffer: false,
resolveStencilBuffer: false
resolveStencilBuffer: false,
colorSpace: ColorManagement.workingColorSpace,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, it hadn't occurred to me that the default color space of a render target is THREE.NoColorSpace! Good catch, and I expect that there my be some other places we may need to fix similar issues.

} );

// debug
Expand Down Expand Up @@ -1461,6 +1464,8 @@ class WebGLRenderer {

_this.clear();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After reading the code again I think _this.clear(); can be removed now. Otherwise clear() is effectively called twice.

Copy link
Collaborator

@Mugen87 Mugen87 May 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The previous approach only honored the clear color set via setClearColor(). But if you trigger the clear indirectly via background.render( scene ), then both clear color and Scene.background = new Color() are honored.

Copy link
Collaborator Author

@gkjohnson gkjohnson May 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's necessarily the case? Again the rationale behind the current transmission clearing logic isn't super clear to me and may deserve some more comments (especially for the white clear color, for example). If renderBackground is set to false then this call to "clear" will still be run, for example. I guess it can at least go in an "else" branch?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If renderBackground is set to false then this call to "clear" will still be run, for example. I guess it can at least go in an "else" branch?

That makes sense. This particular clear should be retained in XR.


if ( _renderBackground ) background.render( scene );

// Turn off the features which can affect the frag color for opaque objects pass.
// Otherwise they are applied twice in opaque objects pass and transmission objects pass.
const currentToneMapping = _this.toneMapping;
Expand Down