I made a shader for trees with a custom shadow caster pass for LOD crossfading.
For some reason, the shadow crossfading works perfectly fine in Scene window, but doesn’t work in Play mode or game build.
I’ve noticed that for some reason the LOD_FADE_CROSSFADE keyword isn’t being enabled at all for shadows in Play mode.
How can I fix this?
Here’s the shader:
Shader "Custom/Custom Tree: Leaves"
{
Properties
{
[noscaleoffset] _MainTex ("Albedo (RGBA)", 2D) = "white" {}
_Cutoff ( "Cutoff", Range( 0 , 1)) = 0.5
[noscaleoffset] _MaskMap ("Mask Map", 2D) = "green" {}
[noscaleoffset] _NoiseGlobal ("Noise Map (Bark)", 2D) = "black" {}
[noscaleoffset] _NormalMap ("Normal Map", 2D) = "bump" {}
_MotionPowerWeightMask("MotionPowerWeightMask", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="TransparentCutout" }
Cull Off
CGPROGRAM
#pragma multi_compile _ LOD_FADE_CROSSFADE
#pragma surface surf Standard vertex:vert alphatest:_Cutoff finalgbuffer:GBufferAccount exclude_path:forward
#pragma target 3.0
sampler2D _MainTex, _NormalMap, _MotionPowerWeightMask, _MaskMap, _NoiseGlobal;
uniform float2 _WindDirection;
float _Translucency;
struct Input
{
float4 screenPos;
float2 uv_MainTex;
};
void GBufferAccount(Input IN, SurfaceOutputStandard o, inout half4 diffuse, inout half4 specSmoothness, inout half4 normal, inout half4 emission)
{
normal.a = 0; diffuse.a = _Translucency;
}
void vert( inout appdata_full v, out Input o )
{
// ...
}
void surf (Input IN, inout SurfaceOutputStandard o)
{
//...
}
ENDCG
}
SubShader
{
Tags
{ "LightMode" = "ShadowCaster" }
Pass
{
Fog {Mode Off}
Cull Off
Offset 1, 1
CGPROGRAM
#include "UnityCG.cginc"
#include "TreeShadowCaster.cginc"
ENDCG
}
}
}
…And the cginclude for shadows:
#pragma multi_compile _ LOD_FADE_CROSSFADE
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_shadowcaster
#pragma multi_compile_instancing
#pragma target 3.0
sampler2D _MainTex;
float4 _MainTex_ST;
float _Cutoff;
struct v2f
{
float2 uv : TEXCOORD0;
V2F_SHADOW_CASTER;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
v2f vert(appdata_base v)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_TRANSFER_INSTANCE_ID(v, o);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
o.pos = ComputeScreenPos(UnityObjectToClipPos(v.vertex));
TRANSFER_SHADOW_CASTER(o)
return o;
}
float4 frag(v2f i) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(i);
clip(tex2D(_MainTex, i.uv).a - _Cutoff);
#ifdef LOD_FADE_CROSSFADE
float2 vpos = i.pos.xy / i.pos.w * _ScreenParams.xy;
UnityApplyDitherCrossFade(vpos);
#endif
SHADOW_CASTER_FRAGMENT(i)
}