Unity Shader 广告牌效果

广告牌效果指的是,一个二维平面的法线方向始终与视线(摄像机的观察方向)相同。广泛运用于渲染烟雾,云朵,闪光等。

它的本质在于构建旋转矩阵,此时我们可以选择三个基向量来构建此矩阵。

指向→的方向(X轴)

指向↑的方向(Y轴)

平面的法线方向(Z轴)

计算方法通常是:

1.根据当前摄像机的方向确定法线方向(广告牌效果的本质),并归一化

normal=normalize(viewDir);

2.根据得到的法线方向和初始的向上方向(在本地空间中即为float3(0,1,0))计算向右的方向,并归一化

right=normalize(cross(up,normal));(使用向量的叉乘计算)

3.用计算后的向右方向和法线方向重新校正向上的方向,得到精确值

up'=normalize(cross(right,normal));

 

计算出旋转矩阵后对原始的顶点进行各自方向上的偏移

 

脚本如下:

 1 // Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
 2 
 3 Shader "MyUnlit/Billboarding"
 4 {
 5     Properties
 6     {
 7         _MainTex ("Texture", 2D) = "white" {}
 8         _Color("Color Tint",color)=(1,1,1,1)
 9     }
10     SubShader
11     {
12         //对顶点进行变换需禁用合P
13         Tags{ "Queue" = "Transparent" "RenderType" = "Transparent" "IgnoreProjector" = "true" "DisableBatching" = "True" }
14 
15         Pass
16         {
17             //透明度混合
18             Tags{ "lightmode" = "forwardbase" }
19             ZWrite off
20             Blend SrcAlpha OneMinusSrcAlpha
21             Cull off
22 
23             CGPROGRAM
24             #pragma vertex vert
25             #pragma fragment frag
26             #pragma multi_compile_fog
27 
28             #include "UnityCG.cginc"
29 
30             struct appdata
31             {
32                 float4 vertex : POSITION;
33                 float2 uv : TEXCOORD0;
34             };
35 
36             struct v2f
37             {
38                 float2 uv : TEXCOORD0;
39                 UNITY_FOG_COORDS(1)
40                 float4 vertex : SV_POSITION;
41             };
42 
43             sampler2D _MainTex;
44             float4 _MainTex_ST;
45             fixed4 _Color;
46 
47             v2f vert (appdata v)
48             {
49                 v2f o;
50                 //计算模型空间中的视线方向
51                 float3 objViewDir = mul(unity_WorldToObject, float4(_WorldSpaceCameraPos, 1));
52 
53                 //计算旋转矩阵的各个基向量
54                 float3 normalDir =normalize(objViewDir);
55                 float3 upDir =float3(0, 1, 0);
56                 float3 rightDir = normalize(cross(normalDir, upDir));
57                 upDir = normalize(cross(normalDir, rightDir));
58 
59                 //用旋转矩阵对顶点进行偏移
60                 float3 localPos =rightDir * v.vertex.x + upDir * v.vertex.y + normalDir * v.vertex.z;
61 
62                 //将偏移之后的值作为新的顶点传递计算
63                 o.vertex = UnityObjectToClipPos(float4(localPos,1));
64                 o.uv = TRANSFORM_TEX(v.uv, _MainTex);
65                 UNITY_TRANSFER_FOG(o,o.vertex);
66                 return o;
67             }
68 
69             fixed4 frag (v2f i) : SV_Target
70             {
71                 fixed4 col = tex2D(_MainTex, i.uv);
72                 col.rgb *= _Color.rgb;
73                 UNITY_APPLY_FOG(i.fogCoord, col);
74                 return col;
75             }
76             ENDCG
77         }
78     }
79     fallback "Transparent/VertexLit"
80 }

 

posted @ 2019-07-03 11:53  汐夜  阅读(2883)  评论(1编辑  收藏  举报