你能看到这篇文章,说明你最近在和我做一样的事情(学习Shader)。由于也是刚开始学习,此处也是整理一些基础的知识。
首先,展示几个有助与学习Shader的 文章或网站。
- unity官网资源网站 : 着色器
- 猫都能学会的Unity Shader
- Unity 官方Shder教程
- 一个大神的个人网站
- 一个CG大神的CSDN
- Humus-一个国外网站,感觉很有用,可以下载源码
- Shadertoy-这个更厉害了,一看就是高级货,一般人我不分享的
其中链接二《猫都能学会的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;
}