[shader]邊緣自定角度高光,描邊,閃爍
阿新 • • 發佈:2019-01-28
Shader "QQ/RimLight" { Properties{ _Color("Color", Color) = (1,1,1,1) _MainTex("紋理", 2D) = "white" {} <span style="white-space:pre"> </span>_LightColor("燈顏色",Color) = (1,1,1,1) _LightDir("燈方向",Vector) = (0,1,0,1) _OutLine("描邊顏色",Color) = (1,1,1,1) _EdgeChange("描邊大小",Range(0,.1)) = .05 _FlickerTime("閃爍時間,0為關閉",Range(0,2)) = 1 } CGINCLUDE #include "UnityCG.cginc" #pragma vertex vert #pragma fragment frag #pragma target 3.0 ENDCG SubShader{ Tags{ "RenderType" = "Transparent" "Queue" = "Transparent" "LightMode" = "ForwardBase" } LOD 200 Pass { Cull Front ZWrite Off Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM fixed4 _OutLine; float _EdgeChange; float _FlickerTime; struct a2v { float4 vertex:POSITION; float3 normal : NORMAL; }; struct v2f { float4 pos : POSITION; }; v2f vert(a2v v) { v2f o; //參考部落格 http://blog.csdn.net/candycat1992/article/details/45577749 o.pos = mul(UNITY_MATRIX_MV,v.vertex); v.normal = mul((float3x3)UNITY_MATRIX_MV,v.normal); v.normal.z = -.5; o.pos.xyz += v.normal*_EdgeChange; o.pos = mul(UNITY_MATRIX_P,o.pos); //參考官方教程 //v.vertex.xyz += v.normal*_EdgeChange; //o.pos = mul(UNITY_MATRIX_MVP, v.vertex); return o; } fixed4 frag(v2f i) :COLOR { //閃爍的乒乓的速度,如果指令碼傳值可以把這段刪掉 _OutLine.a = abs(cos(_Time.x*_FlickerTime)); return _OutLine; } ENDCG } Pass { CGPROGRAM fixed4 _Color; sampler2D _MainTex; fixed4 _MainTex_ST; fixed4 _LightColor; fixed4 _LightDir; struct a2v { float4 vertex:POSITION; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; }; struct v2f { float4 pos : POSITION; float2 uv:TEXCOORD0; float3 normal:TEXCOORD1; float3 viewDir:TEXCOORD2; UNITY_FOG_COORDS(3) }; v2f vert(a2v v) { v2f o; o.pos = mul(UNITY_MATRIX_MVP, v.vertex); float4 wPos = mul(_Object2World, v.vertex); o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); //不過分追求效果的情況下在這裡normalize,如果追求效果,請在frag內normalize,否則插值會被歸一。 o.normal = normalize(mul(v.normal, _World2Object).xyz); //我們希望光是從攝像機對面過來的,所以就反減 o.viewDir = normalize(wPos.xyz - _WorldSpaceCameraPos); //旋轉矩陣 float3x3 rotaX = { 1,0,0,0,cos(_LightDir.x),sin(_LightDir.x),0,-sin(_LightDir.x),cos(_LightDir.x) }; float3x3 rotaY = { cos(_LightDir.y),0,sin(_LightDir.y),0,1,0,-sin(_LightDir.y),0,cos(_LightDir.y) }; float3x3 rotaZ = { cos(_LightDir.z),sin(_LightDir.z),0,-sin(_LightDir.z),cos(_LightDir.z),0,0,0,1 }; o.viewDir = mul(rotaX, o.viewDir); o.viewDir = mul(rotaY, o.viewDir); o.viewDir = mul(rotaZ, o.viewDir); //矩陣相乘後結果不太對,可能寫錯了。 //float3x3 rota = { sin(_LightDir.y)*sin(_LightDir.z),sin(_LightDir.y)*cos(_LightDir.z),cos(_LightDir.y), // -sin(_LightDir.y)*cos(_LightDir.x)*sin(_LightDir.z) - sin(_LightDir.x)*sin(_LightDir.z),-sin(_LightDir.y)*cos(_LightDir.x)*cos(_LightDir.z) + sin(_LightDir.x)*cos(_LightDir.z),cos(_LightDir.x)*cos(_LightDir.y), // -sin(_LightDir.y)*cos(_LightDir.x)*sin(_LightDir.z) + sin(_LightDir.x)*sin(_LightDir.z),-sin(_LightDir.y)*cos(_LightDir.x)*cos(_LightDir.z) - sin(_LightDir.x)*cos(_LightDir.z),cos(_LightDir.x)*cos(_LightDir.y) //}; //o.viewDir = mul(rota, o.viewDir); return o; } fixed4 frag(v2f i) :COLOR { fixed4 col; fixed4 tex = tex2D(_MainTex,i.uv); //點乘normal和視線,判斷相似度 float diff = max(0,dot(i.normal, i.viewDir)); col = tex*_Color + _LightColor*diff*_LightDir.w; return col; } ENDCG } } FallBack "Diffuse" }