shadows on geometry displaced by vertex shader

ahoi there

i’m using a vertex shader in order to simulate wind movement:

uniform float _Wind;
uniform float _WindStrength;
uniform float _WindDX;
uniform float _WindDY;

v2f vert (vin v)
{
	v2f o;
	float ww = (sin((_Wind + v.texcoord1.y) * 1.2) * 0.25 + 0.15) * _WindStrength * v.texcoord1.x;
	v.vertex += float4(ww * _WindDX, 0, ww * _WindDY, 0);
	PositionFog( v.vertex, o.pos, o.fog );
	o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);
	o.color = v.color;
	return o;
}

this works quite well, but when i turn on shadows, both projecting and receiving don’t work properly - shadow casting / receiving behaves as if the displacement didn’t occur.

is there a way to apply the same displacement in the shadow projection / receive code? i guess it has got to do with the AutoLight.cginc and UnityCG.cginc, but i’m a bit lost there - perhaps somebody can give me a hint where to change stuff?

thx a lot in advance :slight_smile:

ps: the code also uses the uv coords of the mesh - hope that is available in the shadow code…

When shadows are done, they render scene geometry using special projector and collector passes. There are a few default ones (to handle things like alpha testing), but if you want something fancy like vertex displacement, you’ll have to write your own. Luckily, all the source for those functions is available (built-in source and UnityCg/AutoLight) and the engine will call them automatically as long as they’re tagged properly.

The tree shaders use a special pass for shadowcasters because it too uses vertex animation.

Sample pass:

Pass {
			Name "ShadowCaster"
			Tags { "LightMode" = "ShadowCaster" }
			
			Fog {Mode Off}
			ZWrite On ZTest Less Cull Off
			Offset [_ShadowBias], [_ShadowBiasSlope]
	
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma multi_compile SHADOWS_NATIVE SHADOWS_CUBE
			#pragma fragmentoption ARB_precision_hint_fastest
			#include "UnityCG.cginc"
			#include "TerrainEngine.cginc"
			
			struct v2f { 
				V2F_SHADOW_CASTER;
			};
			
			struct appdata {
			    float4 vertex : POSITION;
			    float4 color : COLOR;
			};
			v2f vert( appdata v )
			{
				v2f o;
				TerrainAnimateTree(v.vertex, v.color.w);
				TRANSFER_SHADOW_CASTER(o)
				return o;
			}
			
			float4 frag( v2f i ) : COLOR
			{
				SHADOW_CASTER_FRAGMENT(i)
			}
			ENDCG	
		}

thanks for the prompt answers! one more question: is there any sample code for shadow collector passes? couldn’t find any in the builtin shaders… :?

edit: guess they are in the autolight.cginc, as has already been pointed out :sweat_smile:
so all i have to do for collectors is to insert some code in the shadow helpers, correct?