简单看lighting.cginc中的相关函数:
3 | inline fixed4 LightingBlinnPhong (SurfaceOutput s, fixed3 lightDir, half3 viewDir, fixed atten) |
5 | half3 h = normalize (lightDir + viewDir); |
7 | fixed diff = max (0, dot (s.Normal, lightDir)); |
9 | float nh = max (0, dot (s.Normal, h)); |
10 | float spec = pow (nh, s.Specular*128.0) * s.Gloss; |
13 | c.rgb = (s.Albedo * _LightColor0.rgb * diff + _LightColor0.rgb * _SpecColor.rgb * spec) * (atten * 2); |
14 | c.a = s.Alpha + _LightColor0.a * _SpecColor.a * spec * atten; |
其中上面的注释已经明确提到在iOS上的浮点数精度会导致高光过曝的问题,而涉及到的viewDir和中间变量h都已是mediump的half了,试了下换成float也没有任何变化。
忽略中途google和若干各种尝试,最终发现问题还是精度导致的spec溢出,因为旁边比较关键的pow幂运算,而最终的解决方法就是将上面两个max的比较取值换为saturate,限制结果在0-1之间,从而不至于让运算结果过大导致本来想要衰减较大高光较暗的感觉变得太亮甚至过曝。