GLSL PBS实现,奇怪的着色器行为

GLSL PBS实现,奇怪的着色器行为,glsl,shader,fragment-shader,Glsl,Shader,Fragment Shader,我使用的是库克·托伦斯镜面反射BRDF+迪士尼的漫反射BRDF灯光模型,如果单独应用,效果会很好。不幸的是,如果我尝试将它们结合起来,就会发生一些奇怪的事情: 漫反射光照贴图如下所示: 镜面反射光照贴图(请注意地形边缘上的瑕疵): 生成的光照贴图的计算方式如下: float result = Fr + Fd; 其中Fd是漫反射BRDF组件,Fr是镜面反射BRDF组件 为什么在生成的光照贴图上会出现这样的瑕疵 我认为产生的光强度超出了范围[0;1],以检查我是否修改了代码,如下所示: retu

我使用的是库克·托伦斯镜面反射BRDF+迪士尼的漫反射BRDF灯光模型,如果单独应用,效果会很好。不幸的是,如果我尝试将它们结合起来,就会发生一些奇怪的事情: 漫反射光照贴图如下所示: 镜面反射光照贴图(请注意地形边缘上的瑕疵):

生成的光照贴图的计算方式如下:

float result = Fr + Fd;
其中Fd是漫反射BRDF组件,Fr是镜面反射BRDF组件

为什么在生成的光照贴图上会出现这样的瑕疵

我认为产生的光强度超出了范围[0;1],以检查我是否修改了代码,如下所示:

return result <= 1.0 ? result : 1.0;

返回结果正如@Columbo提到的,这是一个异常(被零除的原因),导致了奇怪的着色器行为。我稍微修改了代码:

float F_Schlick (in float f0, in float f90, in float u)
{
    return f0 + ( f90 - f0 ) * pow(clamp(1.0 - u, 0.0, 1.0), 5.0); //line 34
}
点积应大于零:

float dotNV = abs(dot(N, V));
float dotNL = abs(dot(N, L));

似乎很难解释。我唯一一次从着色器中看到这种奇怪的结果,它是由一些未定义的数学导致的,这些数学导致NaN以奇怪的方式传播和破坏东西。也许看看所有的pow函数,并确保第一个参数不能是负的,通过临时侵入abs/max/saturate或所有函数上的任何东西(线pow(pow(dotNH,2.0)*(m_alpha-1.0)+1.0,2.0));可能有一个负数(例如)。如果那还不行,我会试试的simplifyin@Columbo非常感谢。N和L的点积是0,它给出了零误差除法。我添加了abs功能作为修补程序。