그림자를 수신하는 지원을 구현하려면 기본 조명 패스를 여러 배리언트로 컴파일하여 ’그림자 없는 방향 광원’인 경우와 ’그림자 있는 방향 광원’인 경우에 올바르게 처리해야 합니다. #pragma multi_compile_fwdbase 지시문이 이를 수행합니다(자세한 내용은 다중 셰이더 배리언트 참조). 실제로는 훨씬 더 많은 것을 수행합니다. 또한 인라이튼 실시간 전역 조명 켜기 또는 끄기 등 다양한 라이트맵 유형의 배리언트를 컴파일합니다. 지금은 이러한 것이 모두 필요하지는 않으므로 이러한 배리언트는 명시적으로 건너뜁니다
다음으로 실제 그림자 계산 결과를 얻으려면 #include “AutoLight.cginc” 셰이더 include 파일을 포함하고 이로부터 SHADOW_COORDS, TRANSFER_SHADOW, SHADOW_ATTENUATION 매크로를 사용합니다.
다음은 셰이더입니다.
Shader "Lit/Diffuse With Shadows"
{
Properties
{
[NoScaleOffset] _MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Pass
{
Tags {"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
// compile shader into multiple variants, with and without shadows
// (we don't care about any lightmaps yet, so skip these variants)
#pragma multi_compile_fwdbase nolightmap nodirlightmap nodynlightmap novertexlight
// shadow helper functions and macros
#include "AutoLight.cginc"
struct v2f
{
float2 uv : TEXCOORD0;
SHADOW_COORDS(1) // put shadows data into TEXCOORD1
fixed3 diff : COLOR0;
fixed3 ambient : COLOR1;
float4 pos : SV_POSITION;
};
v2f vert (appdata_base v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord;
half3 worldNormal = UnityObjectToWorldNormal(v.normal);
half nl = max(0, dot(worldNormal, _WorldSpaceLightPos0.xyz));
o.diff = nl * _LightColor0.rgb;
o.ambient = ShadeSH9(half4(worldNormal,1));
// compute shadows data
TRANSFER_SHADOW(o)
return o;
}
sampler2D _MainTex;
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
// compute shadow attenuation (1.0 = fully lit, 0.0 = fully shadowed)
fixed shadow = SHADOW_ATTENUATION(i);
// darken light's illumination with shadow, keep ambient intact
fixed3 lighting = i.diff * shadow + i.ambient;
col.rgb *= lighting;
return col;
}
ENDCG
}
// shadow casting support
UsePass "Legacy Shaders/VertexLit/SHADOWCASTER"
}
}
이제 그림자가 생겼습니다!