在移动端的BRDF计算中,当View和Light向量趋近于相反向量时候,H向量将不断趋近于0向量,这时候H向量的半精度可能会因精度不足出现0向量,导致后续计算NoH时出现问题。尤其是如果roughness小于0.05的时候GGX_Specular的计算错误会更加明显(shader代码中对于roughness的半精度保护是会clamp到大于0.015,0.05是合法值)
当前的ue代码和对应的在安卓上的GLSL代码:
[Image Removed]
官方代码在这里其实已经意识到这个H向量的精度问题,所以这里采用了临时提升精度的写法。但是问题就出在当dxc翻译这段代码的时候,猜测可能是H后续的dot使用需要与半精度的N计算,用于计算的V和L也是半精度,所以可能就优化掉了这次转换。生成的glsl代码如下:
[Image Removed]
这样最终效果如下(不带后效的,只有directional lighting):
[Image Removed]
我尝试如下修正,绕开dxc的优化:
[Image Removed]
对应的翻译后的平台shader:
[Image Removed]
对应的效果图:
[Image Removed]
[Attachment Removed]