KhronosGroup / glTF-Sample-Viewer

Physically-Based Rendering in glTF 2.0 using WebGL
Apache License 2.0
1.23k stars 227 forks source link

No specular from lights when roughness=0 #547

Open rsahlin opened 1 month ago

rsahlin commented 1 month ago

There are no specular highlights when roughness = 0.0 The likely cause for this is that the NDF function needs to limit roughness to a small value.

Since glTF does not use solid angle for lights, most engines use a simplified model where the NDF will create specular lobe using roughness. However, values of 0.0 roughness will not produce any specular at all.

image

emackey commented 3 weeks ago

This is a known artifact of a "point light" being infinitesimally small. You can't look in your bathroom mirror and spot an individual bacterium relaxing on the wall behind you. In a true physical situation, the light bulb would have some actual radius, but there's no radius here. The only way to see light on the smoothest spheres would be through blooming, and we don't have blooming in this render. That's why there's no visible light there.

rsahlin commented 3 weeks ago

I know that the spec defines the punctual lights as being infinitely small points, ie they have no solid angle.
There is no need for an effect such as blooming - we can simply limit the roughness value to something (very) small.

The reason why there is no visible light from materials where roughness = 0 is due to the NDF function being used. They work by extending the specular highlight based on the roughnessfactor, when roughness = 0 there is nothing to distribute.

Using the argument that we are displaying light from infinitely small points, ie the solid angle is 0.0, there would not be any specular reflection even as roughness increases. So, either the solid angle is not 0.0 - in which case there shall be visible light coming from smooth surfaces. Or, there can be no visible light reflecting off surfaces as roughness increases.

This is simply an effect of the simplified runtime model - for consistency I still argue that we should limit roughness in the NDF to get small highlights for perfectly smooth materials.

emackey commented 3 weeks ago

I wouldn't want to limit roughness for materials, because folks want smooth IBL reflections on mirror-like objects.

rsahlin commented 2 weeks ago

I think you misunderstand. There will be no limitation of roughness - this is just a shader bugfix in the functions that creates the specular lobe (NDF)

The sampleviewer implementation uses the GGX normal distribution function - this takes NdotH and alphaRoughness as parameters. The bugfix is as easy as making sure roughness is not zero in the _DGGX and D_GGX_anisotropy functions:

float D_GGX(float NdotH, float alphaRoughness)
{
    //Make sure there is the equivalent of a solid angle to create the specular lobe. 
   alphaRoughness = max(alphaRoughness, 0.00002);
   float alphaRoughnessSq = alphaRoughness * alphaRoughness;

This fix is already present for the sheen distribution functions, so I see no reason why it should not be applied to the ndf.