其中链接二《猫都能学会的Unity Shader 入门指南(一)》中对Unity Shder 的 框架结构进行了透彻的讲解。如果你对 Shder一点也会了解的话,建议先去看这个。
大家都知道有直来直去的单向反射或称镜面发射。这些反射通过都发生在表面相对极其光滑平整的物体上(比如镜子)。而一般物体的表面多粗糙不平,入射线虽然为平行光线,但反射后的光线则向由于物体的凹凸不平程各个方向分散,此种现象为光的漫反射。 那么在Unity 的 shader 中 如何實現漫反射呢? 点积 大家都知道吧。百度中有提及:
向量的点积与它们夹角的余弦成正比,因此在聚光灯的效果计算中,可以根据点积来得到光照效果,如果点积越大,说明夹角越小,则物体离光照的轴线越近,光照越强。
那么我们就可以通过点积来得到物体此处面受到光照的强度。
下图中的物体为一个常见的矩形。矩形中 黄色的线 是 面的 法线。红色的线 是 顶点的 法线。
那么我们要做的就是计算灯光照射过来的的方向与物体表面法向量(黄色线)的 点积,得出一个光照在此面的强度。然后使用这个值对物体表面进行不同的颜色的改变。官方解释
Shader 中的代码呈现:
inline float4 LightingCustomDiffuse (SurfaceOutput s, fixed3 lightDir, fixed atten) { // s.Normal为物体面的法向量, lightDir为灯光方向。得到difLight 灯光强度 float difLight = max(0, dot (s.Normal, lightDir)); //声明一个颜色的变量 float4 col; //用这个物体面本来颜色 * 灯光颜色 * 灯光强度 * 衰减值 * 2 col.rgb = s.Albedo * _LightColor0.rgb * (difLight * atten * 2); //Alpha 为本来的值 col.a = s.Alpha; //返回新的颜色 return col; }顺便再说一下 Half Lambert灯光模型。这个技术最早用在游戏《半条命》中,以避免在低光下物体的走形。方法很简单,就是把光强度系数先取一半,再加上0.5f。这样,原来光强度是0的点,就成了0.5f。而原来为 1的点 还保持为1。
inline float4 LightingCustomDiffuse (SurfaceOutput s, fixed3 lightDir, fixed atten) { float difLight = dot (s.Normal, lightDir); float hLambert = difLight * 0.5 + 0.5; float4 col; col.rgb = s.Albedo * _LightColor0.rgb * (hLambert * atten * 2); col.a = s.Alpha; return col; }