关于Unity3D内置Blinn Phong光照模型计算在移动设备上的曝光问题


Unity3D的
surface shader用起来很是方便,比直接的cg写起来省事的多,而且有很多现成的东西可以include,比如光照部分就是,常用的lambert, blinn phong都提供了现成的实现,但是最近在做specular时发现,内置(https://unity3d.com/unity/download/archive下载全部内置shader source或{unity install path}/Data/CGIncludes/Lighting.cginc Windows, /Applications/Unity/Unity.app/Contents/CGIncludes/Lighting.cginc Mac)的LightingBlinnPhong在移动设备上使用时会出现高光曝掉的问题!

简单看lighting.cginc中的相关函数:

1 // NOTE: some intricacy in shader compiler on some GLES2.0 platforms (iOS) needs 'viewDir' & 'h'
2 // to be mediump instead of lowp, otherwise specular highlight becomes too bright.
3 inline fixed4 LightingBlinnPhong (SurfaceOutput s, fixed3 lightDir, half3 viewDir, fixed atten)
4 {
5     half3 h = normalize (lightDir + viewDir);
6
7     fixed diff = max (0, dot (s.Normal, lightDir));
8
9     float nh = max (0, dot (s.Normal, h));
10     float spec = pow (nh, s.Specular*128.0) * s.Gloss;
11
12     fixed4 c;
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;
15     return c;
16 }

其中上面的注释已经明确提到在iOS上的浮点数精度会导致高光过曝的问题,而涉及到的viewDir和中间变量h都已是mediump的half了,试了下换成float也没有任何变化。
忽略中途google和若干各种尝试,最终发现问题还是精度导致的spec溢出,因为旁边比较关键的pow幂运算,而最终的解决方法就是将上面两个max的比较取值换为saturate,限制结果在0-1之间,从而不至于让运算结果过大导致本来想要衰减较大高光较暗的感觉变得太亮甚至过曝。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值