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

Allow to Use Roughness for SSR in Three.js

Open Stanislav-Sobolev opened this issue 1 year ago • 2 comments

Description

I am using post-processing with WebGL 2.0 and encountered a limitation in the SSRShader. Currently, the shader uses only the metalness value to determine if SSR should be applied to a fragment:

float metalness = texture2D(tMetalness, vUv).r;
if (metalness == 0.0) return;

This limitation results in the same glossy reflection for all objects, regardless of their surface properties.

Solution

I propose to extend the SSRShader functionality by utilizing both metalness (for opacity/alpha SSR) and roughness (to determine the strength of SSR reflections). I have customized the shader to use ORM textures and modified it as follows:

float roughness = texture2D(tReflectance, vUv).g;
float metalness = texture2D(tReflectance, vUv).b;
if (metalness == 0.0) return;

float reflectionStrength = 1.0 * roughness;
gl_FragColor.xyz = reflectColor.xyz * reflectionStrength;
gl_FragColor.a = op * roughness * metalness;

This modification allows achieving more realistic reflections by adjusting their strength based on the roughness value.

Alternatives

Currently, the only alternative is to manually customize the shader code to incorporate roughness, as shown above. This approach is not ideal for all users and may lead to inconsistencies and maintenance challenges.

Additional context

Supporting roughness in the SSRShader to blur reflections based on roughness strength would allow for more accurate and varied reflections, improving visual realism for both metallic and non-metallic surfaces. This enhancement would greatly benefit the Three.js community and enhance the overall rendering quality.

Thank you for considering this request.

Stanislav-Sobolev avatar Jun 27 '24 07:06 Stanislav-Sobolev

@gonnavis Do you mind looking at this issue?

Mugen87 avatar Jun 29 '24 09:06 Mugen87

Sorry, I'm busy at work and might not have much time recently. I've tried something similar before https://github.com/mrdoob/three.js/pull/21487, but full PBR integration was too challenging for me and I couldn't complete it yet. However, it might still be helpful as a reference.

gonnavis avatar Jun 29 '24 13:06 gonnavis

@WestLangley I wonder what your opinion is on this topic. Right now, SSRNode relies the most basic approach by using the fragment's metalness value to modulate the SSR's opacity. A high metalness will result in more SSR reflections and vice versa. I'm not sure how to incorporate roughness into this process though. I'm trying to find out if it is actually correct to modulate the SSR color (or reflected color) based on the roughness. Also looking for a good reference.

Mugen87 avatar Nov 11 '24 13:11 Mugen87

@Mugen87 FWIW https://github.com/godotengine/godot/pull/69828

WestLangley avatar Nov 11 '24 17:11 WestLangley