mrdoob / three.js

JavaScript 3D Library.
https://threejs.org/
MIT License
102k stars 35.33k forks source link

Allow to Use Roughness for SSR in Three.js #28752

Open Stanislav-Sobolev opened 3 months ago

Stanislav-Sobolev commented 3 months ago

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.

Mugen87 commented 3 months ago

@gonnavis Do you mind looking at this issue?

gonnavis commented 3 months ago

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.