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 2 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.
6 changes: 5 additions & 1 deletion src/renderers/WebGLRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -1430,7 +1430,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 +1462,9 @@ 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.


const renderBackground = xr.enabled === false || xr.isPresenting === false || xr.hasDepthSensing() === false;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do you mind passing the existing renderBackground flag from the render() method into renderTransmissionPass(). In this way, it's not necessary to make the same evaluation 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.

You can also consider to rename it to _renderBackground and store it in the same scope like _clippingEnabled. Then it is not necessary to change the signature of renderTransmissionPass().

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done!

if ( renderBackground ) background.render( scene );
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm not sure I understand the motivation for this part of the change, why would XR presentation and depth sensing affect whether the background is drawn?

Copy link
Collaborator Author

@gkjohnson gkjohnson May 20, 2024

Choose a reason for hiding this comment

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

I don't know the history of some of these decisions, unfortunately - just that it's already done elsewhere in WebGLRenderer to determine whether to draw the background. There's probably some clean up that should happen in the render function in this respect.

See https://github.com/mrdoob/three.js/blob/dev/src/renderers/WebGLRenderer.js#L1156

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ok! I don't know much about that part but will approve the PR in any case, thanks again!


// 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