[Unity] vertex-frag形式的shader中接受Unity內置陰影

Unity5之前,想要接受陰影需要一個名爲ShadowCollector的Pass.參考這裏:

https://forum.unity.com/threads/i-put-a-shadowcollector-pass-in-my-shader-but-why-does-it-cant-recieves-shadow-why.160010/

但是Unity5之後這個Pass已經沒有用了,參見官網:

https://docs.unity3d.com/Manual/UpgradeGuide5-Shaders.html

有如下說明:

然後Unity5之後,想要接受陰影,比較簡單網上例子也比較多的是在surface shader中實現,這裏不多說.下面總結一個在vf形式的shader中添加接受陰影的方法(注意這裏簡短起見沒有自己寫投射陰影的ShadowCaster Pass,投射陰影是讀取了Fallback "Mobile/VertexLit"中的這個Pass).我們以一個Lambert光照模型爲基礎,添加接受陰影的功能.

Shader "Custom/Diffuse_ReceiveShadow"
{
	Properties
	{
		_MainTex ("Texture", 2D) = "white" {}
	}
	SubShader
	{
		Tags { "RenderType"="Opaque" }
		LOD 100

		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			// make fog work
			#pragma multi_compile_fog

			#pragma multi_compile _ SHADOWS_SCREEN //相關宏
			#include "UnityCG.cginc"
			#include "AutoLight.cginc" //SHADOW_COORDS需要
			#include "Lighting.cginc"
			
			struct appdata
			{
				float4 pos : POSITION;
				float2 uv : TEXCOORD0;
				float3 normal : NORMAL;
			};

			struct v2f
			{
				float4 pos : SV_POSITION;
				float2 uv : TEXCOORD0;
				float3 worldNormal : TEXCOORD1;
				float3 worldPos : TEXCOORD2;
				UNITY_FOG_COORDS(3)
				SHADOW_COORDS(4) //按TEXCOORD數遞增
			};

			sampler2D _MainTex;
			float4 _MainTex_ST;
			
			v2f vert (appdata v)
			{
				v2f o;
				o.pos = UnityObjectToClipPos(v.pos);
				o.uv = TRANSFORM_TEX(v.uv, _MainTex);
				o.worldPos = mul(unity_ObjectToWorld, v.pos);
				o.worldNormal = mul(v.normal, (float3x3)unity_WorldToObject);
				TRANSFER_SHADOW(o); //vertex中的處理
				UNITY_TRANSFER_FOG(o,o.pos);
				return o;
			}

			fixed4 frag (v2f i) : SV_Target
			{
				// sample the texture
				fixed3 col = tex2D(_MainTex, i.uv);
				fixed3 worldNormal = normalize(i.worldNormal);
				fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
				UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos); //fragment中的處理,輸出到atten
				fixed3 diffuse = _LightColor0.rgb * atten * col * saturate(dot(worldNormal, worldLightDir));
				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
				fixed3 color = ambient + diffuse;

				// apply fog
				UNITY_APPLY_FOG(i.fogCoord, color) ;				
				return fixed4(color, 1.0);
			}
			ENDCG
		}
	}
Fallback "Mobile/VertexLit"
}

簡單添加這5處修改之後,我們就可以在遊戲中看到接受陰影的效果了.

 

參考資料:

https://catlikecoding.com/unity/tutorials/rendering/part-7/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章