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 }