边缘发光效果

前置知识点

引入模型后需要将模型从自身坐标系先转换到世界坐标系下,然后再转化到摄像机坐标,

UnityObjectToClipPos,将模型的点从自身的坐标系变换到摄像机坐标系的裁剪空间下

渲染管线传递给shader的参数提示,

normal是法线

实现

边缘发光效果,

前面—》篮球 —》背面黄色:
(1)我们的边缘的黄色怎么来的,是把这个球绘制了2次; —>pass 绘制黄色
(2)我就面对摄像机的这些面,有重新涂成了黄色;
(3)配置我们的渲染队列,修改我们的alpha;
(4)发光效果,是不是中间强,边缘弱;找个数学方式,能够做到中间强边缘弱?
(5)shader 常用技巧(解题技巧5)

image-20241028213739714

工作原理,在将模型的面投影到2D平面之前,会经历一步裁剪操作,默认将背朝摄像机的面裁剪掉,可以使用Cul Fron关键字将背面的模型也给渲染出来,同时适当增大vertex

具体原理解释

Unity用Shader实现边缘光效果_unity3d shader 边缘光-CSDN博客

对于一些规则的模型,当然可以使用数学计算来获取边缘,但是对于人形就不适用了,为了通用就用这个

在边缘光的设置上,通过使用 blend SrcAlpha One 可以实现透明的效果

image-20241028215156748

如果存在透明的要求,需要在Unity的配置界面中,将自定义Shader的渲染队列调整到 Transparent中,仍然使用默认渲染队列会出现透明物体最后是黑色的效果

边缘强度获取

点乘:数学概念

image-20241028220445402

被用来求两个向量之间的夹角

image-20241028221240429

使用一个点在观察空间下的的坐标和点的法线进行点乘操作,求得两条法线之间的夹角,

image-20241028221908793

单位化后对应向量的 模 就是 1 ,最后计算夹角的cos值的时候只需要求点乘的结果,因为 1 * 1 =1

image-20241028222653683

mul是矩阵乘法,当中的第一个参数是矩阵变换方程

image-20241028223120000

view_dir变量的计算方程的 的被减速 是Unity提供的 在世界中的相机坐标

image-20241028223355749

image-20241028223604459

但是在实际模型中,一个三角形并不会严格分布在裁剪面的正面或反面,会有跨过线的情况,也就导致了在裁剪面正面的角度 alpha 会小于 0,表现在视觉上边缘黑色,使用三元运算符号就行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
v2f vert(appdata v)
{
v2f o;
float4 new_vert =v.vertex + float4(v,normal, 1)* float4(0.1, 0.1, 0.1, 1).o.vertex = UnityObjectToClipPos(new vert):O.UV = TRANSFORM TEX(v.uv,MainTex);
o.w normal = UnityObjectToWorldNormal(v.normal);o.w_vertex=mul(unity ObjectToWorld, v.vertex);//20%
return o:
}
//着色shader 入口;
fixed4 frag(v2f i):SV Target
{
float3 view dir=i.w vertexWorldSpaceCameraPos;
float3 wnormal=i.w_normal;
view dir=normalize(view dir);
w_normal=normalize(wnormal);
float value=dot(view_dir,wnormal);//cos(a)[-1,1]
value=(value<0)?0:value;
value =pow(value,6) * 20;//使用指数效果来让渐变的效果明显,指数太大背面消失,乘上一个数就行了
fixed4 col=fixed4(1,1,0,value);return col;
}
ENDCG // end Cg;