写这个Shader需要知道一些基础知识:
物体的每个地方的法线都是垂直于这个地方的
在Unity里我们看物体,实际上就是相机在看物体,我们看到的所有东西都是通过相机视角
根据上边两点,可以知道,我们看物体的边缘地方跟我们看物体的中心地方,角度是有一定的区别的,物体的中心区域的法线方向是垂直于物体中心区域,也就是与相机的视线平行,而物体的边缘区域的法线方向是垂直于物体边缘区域,也就是向外的(上下左右的方向)。
所以可以通过各个像素的法线方向跟相机视线的角度来做一个点乘:
viewDir:相机角度
normal:法线的方向
VDotN=dot(viewDir,normal)
众所周知,法线的取值范围是[-1.1]
所以需要使用shader的内置函数clamp来使得点乘的结果在[0,1]
具体做法:
VDotN=clamp(dot(viewDir,normal),0,1)
这样取得的结果就是在[0,1]
根据公式可以知道,物体越靠近中心区域,点乘的值越大,我们需要边缘区域更加明显,那么就做一个取反的操作:
VDotN= 1-clamp(dot(viewDir,IN.normal),0,1)
通过这个值,我们可以判断出哪里是物体的边缘区域
这里用SurfaceShader来举例:
在SurfaceShader中,默认的片段着色器:
void surf (Input IN, inout SurfaceOutput o)
{