Planar Shadow
阿新 • • 發佈:2018-04-03
返回 brush tro plan 顏色 sample RM matrix AI
Unity上平面陰影的計算與實現
//如何求頂點投影到平面上的點(陰影點) //當平面上取不相等的任意兩個點組成一個向量,與平面的法線總是垂直的,向量垂直點乘為0,因此可以通過一個點和一個法線來定義, //plane方程如下:(P - P0)·N = 0 N=normal,P0表示平面上的一個點,P表示平面上的任意點,當P = P0時 0·N = 0 //射線方程 P = o + t * D,(o為射線起點,t為標量,表示射線原點到和平面交點的距離)聯立兩個方程式可求交點。方程如下: // ( O + D·t - P0 )·N = 0 // => ( O - P0 )·N + D·N·t = 0 // => t = ( P0 - O)·N / D·N ( 其中D·N ≠0 ,向量點積滿足分配律) // p0表示平面上一點中心點(0,0,0) o:頂點世界坐標 N:平面的法向量(0,1,0)D:直射光方向 //註意兩點: //當 D·N = 0 時,表示射線與平面垂直,則射線與平面平行。 //解出 t < 0 時,表示 射線沿著平面相反的半平面發射,也是不相交的(當然如果是直線就沒關系啦) Shader "Pluto/PlanarShadow" { Properties { _ShadowColor ("Shadow Color",Color) = (0.25,0.25,0.25,0.25) _Center("Center", Vector) = (0,0.001,0,0) _Normal("Normal", Vector) = (0,1,0,0) _MainTex ("Texture", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" "LightMode"="ForwardBase" } LOD 100 //渲染模型 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; //模型空間中的頂點坐標 float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; //裁剪空間中的頂點坐標 }; sampler2D _MainTex; float4 _MainTex_ST; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); //將頂點從模型空間轉換到裁剪空間中,更高效 o.uv = TRANSFORM_TEX(v.uv, _MainTex); return o; } fixed4 frag (v2f i) : SV_Target { // sample the texture fixed4 col = tex2D(_MainTex, i.uv); return col; } ENDCG } //渲染平面陰影Pass Pass { ZWrite On ZTest LEqual Blend SrcAlpha OneMinusSrcAlpha Stencil{ Ref 0 Comp Equal Pass IncrWrap ZFail Keep } CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; }; struct v2f { float4 vertex : SV_POSITION; }; float4 _ShadowColor; //陰影顏色 float4 _Center; //平面上一點中心點 float4 _Normal; //平面法線 v2f vert (appdata v) { v2f o; float4 wPos = mul(unity_ObjectToWorld ,v.vertex); //頂點世界坐標 float4 lightDir = normalize(_WorldSpaceLightPos0); //直射光的方向 float dist = dot(_Center.xyz - wPos.xyz, _Normal.xyz) / dot(lightDir, _Normal.xyz); wPos = wPos + lightDir * dist; o.vertex = mul( UNITY_MATRIX_VP,wPos); //轉換到裁剪空間坐標 return o; } fixed4 frag (v2f i) : SV_Target { return _ShadowColor; //直接返回影子顏色 } ENDCG } } }
參考:https://www.jianshu.com/p/c8438bf6af0f
----碼字不易,歡迎轉載,但保留版權,請於明顯處標明出處:http://www.cnblogs.com/beeasy/
Planar Shadow