Arzie100 发表于 2022-1-5 10:19

低粗糙度下Unity的GGX法线分布函数的计算结果数值特别大 ...

【问题】
Unity的GGX NDF在低粗糙度下的计算结果远大于1,在其他所有项都小于1的情况下(设定入射光线只有单位1),最终得到的反射数值远超过1,这样能量显然不守恒了,请问是哪里出了问题?
【背景过程】
最近在学PBR的内容,我用C#把Unity的BRDF模型重写了一遍,想算一下单位1的入射光摄向物体后,在镜面反射方向上最后出射的具体能量大小。但是在低粗糙度的情况下(例如粗糙度0.15),最终计算得到的出射光数值远远超过1,完全不是能量守恒的状态。Debug查找了一遍,发现只有GGX的法线分布函数计算结果特别大,能到700,800多,最后的出射光数值也能算到好几十,远大于入射光的1。
公式是完全照抄Unity的,应该是不会出问题,而且我把函数图像画出来之后发现了一个更奇怪的问题:这个函数的最大值并非是r=0处。最大值在r=0.133,从r=0.133到r=0,函数是减小的,导致r=0.05的出射光数值远远小于r=0.13的出射光数值。
//从 unity standard shader里改写出来的代码
private float GGXTerm(float NdotH, float roughness)
{
   float a2 = roughness * roughness;
   float d = (NdotH * a2 - NdotH) * NdotH + 1.0f;
   return a2 / (Mathf.PI * (d * d + 1e-7f));
}以下是画出来的GGX图像(NdotH=1,因为我只考虑镜面反射方向上的出射光):


Unity GGX
肯定不是这个模型有啥问题,应该是我哪里没有考虑到或者存在理解错误的地方,希望求教问题所在,非常感谢。
页: [1]
查看完整版本: 低粗糙度下Unity的GGX法线分布函数的计算结果数值特别大 ...