glTF-Sample-Viewer icon indicating copy to clipboard operation
glTF-Sample-Viewer copied to clipboard

No specular from lights when roughness=0

Open rsahlin opened this issue 1 year ago • 6 comments

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

rsahlin avatar Jun 11 '24 09:06 rsahlin

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.

emackey avatar Jun 19 '24 20:06 emackey

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.

rsahlin avatar Jun 20 '24 10:06 rsahlin

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

emackey avatar Jun 20 '24 12:06 emackey

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.

rsahlin avatar Jun 24 '24 08:06 rsahlin

Using the same value for roughness as with sheen the reflaction is only a few pixels, it is barely visible:

grafik

I don't know how the value for sheen was chosen, but how should we chose a resonable value here? It should not be arbitrary otherwise the size of the specular lobe changes for each renderer.

UX3D-haertl avatar Aug 27 '24 16:08 UX3D-haertl

I still think this is just an issue of stacked approximations. A true point light is infinitely small, so if you had a theoretically perfectly smooth specular reflection of an infinitely small point with no bloom, it would be much less than one pixel. It "looks wrong" because in real life we're not accustomed to seeing anything like this: We don't get infinitely small light sources in real life.

Let's not introduce any new fudge factors here without first getting some buy-in from the PBR TSG, please.

emackey avatar Aug 27 '24 17:08 emackey