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

MeshNormalMaterial Color Differences Across Renderers #30575

Closed
cmhhelgeson opened this issue Feb 20, 2025 · 4 comments · Fixed by #30590
Closed

MeshNormalMaterial Color Differences Across Renderers #30575

cmhhelgeson opened this issue Feb 20, 2025 · 4 comments · Fixed by #30590
Milestone

Comments

@cmhhelgeson
Copy link
Contributor

cmhhelgeson commented Feb 20, 2025

Description

I was experimenting with MeshNormalMaterial in the WebGPURenderer when I noticed the colors of the normals seemed off when compared to the WebGLRenderer. I was wondering if this is expected behavior based on the differences between the two rendering APIS or whether this was a bug. I assume this might also just be differences in default color spaces, but just wanted to confirm.

Reproduction steps

  1. Create three renderers (WebGPURenderer with WebGPUBackend, WebGPURenderer with WebGLBackend, WebGLRenderer) that each render the same scene, containing a mesh with a MeshNormalMaterial.

Code

// NA

Live example

Live WebGPU Example

Screenshots

Image

Version

r173

Device

Desktop

Browser

Chrome

OS

Windows

@WestLangley
Copy link
Collaborator

This issue was raised in #28831 (comment).

I am disappointed it was considered not worthy of being fixed.

@cmhhelgeson
Copy link
Contributor Author

cmhhelgeson commented Feb 21, 2025

This issue was raised in #28831 (comment).

I am disappointed it was considered not worthy of being fixed.

I was able to do a dirty fix by simply moving the color space into workingColorSpace. I'll modify the example to demonstrate. WTS.

Live WebGPU Example

Relevant code:

if ( this.emulateWebGLOutput ) {

      diffuseColor.assign( toWorkingColorSpace( vec4( directionToColor( transformedNormalView ), opacityNode ), SRGBColorSpace ) );

} else {

     diffuseColor.assign( vec4( directionToColor( transformedNormalView ), opacityNode ) );

}

EDIT: Reading the original issue, I can understand and agree with most of the justifications for removing per material tone mapping. However, it would be nice to have more explicit documentation within the renderer itself explaining some of the philosophical differences between the WebGLRenderer and the WebGPURenderer. From my initial naive perspective, which is likely to be shared by a lot of people making the switch to the WebGPURenderer for the first time, this reads as a bug, even if it's an intentional and or negligible side effect of a shift in philosophy.

Maybe for some materials there could be a property like 'emulateMaterialToneMapping' that reverts the color of the material to its expected WebGLRenderer output in cases where the intent is to have strict parity with the WebGLRenderer.

@Mugen87
Copy link
Collaborator

Mugen87 commented Feb 21, 2025

However, it would be nice to have more explicit documentation within the renderer itself explaining some of the philosophical differences between the WebGLRenderer and the WebGPURenderer. From my initial naive perspective, which is likely to be shared by a lot of people making the switch to the WebGPURenderer for the first time, this reads as a bug, even if it's an intentional and or negligible side effect of a shift in philosophy.

We are in the process of improving documentation so this issue is on our list.

If somebody is interested in adding a new manual page in https://threejs.org/manual/, I would definitely invest time in supporting any efforts (in the weeks I will focusing on JSDoc though). It could be a page that explains the differences between WebGLRenderer and WebGPURenderer.

Tone mapping and color spaces are one topic, post processing, clipping, custom materials others.

Maybe for some materials there could be a property like 'emulateMaterialToneMapping' that reverts the color of the material to its expected WebGLRenderer output in cases where the intent is to have strict parity with the WebGLRenderer.

TBH, I do not support this. If you really need more flexibility, use PostProcessing and set postProcessing.outputColorTransform to false. Now tone mapping and color space conversion is really up to you. Like controlling which objects receive bloom, you could do the same for what objects should receive a color transform. Or simply render certain objects with a second non-tone mapped pass.

@cmhhelgeson
Copy link
Contributor Author

TBH, I do not support this. If you really need more flexibility, use PostProcessing and set postProcessing.outputColorTransform to false. Now tone mapping and color space conversion is really up to you. Like controlling which objects receive bloom, you could do the same for what objects should receive a color transform. Or simply render certain objects with a second non-tone mapped pass.

Fair enough, I'll close the issue since this topic has been discussed quite extensively across other issues.

@cmhhelgeson cmhhelgeson reopened this Feb 21, 2025
@cmhhelgeson cmhhelgeson closed this as not planned Won't fix, can't repro, duplicate, stale Feb 21, 2025
@Mugen87 Mugen87 added this to the r174 milestone Feb 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants