Vertex Displacement in Forward Rendering Shader

I’m trying to implement a gras rendering shader with moving blades in Unity 3. Everything works fine, except when i turn on shadows and deferred rendering. The shader must be forward rendering (it needs a custom lighting function).

The problem apparently is that it renders “invisible holes” in the form of the gras texture during deferred rendering, but it doesn’t pick up the vertex displacement, so the result looks wrong (see picture below).

Here is the shader code:

Shader "Gras" {
Properties {
	_Color ("Main Color", Color) = (1,1,1,1)
	_MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
	_Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
}
SubShader {
	Tags {"Queue"="AlphaTest" "IgnoreProjector"="True" "RenderType"="TransparentCutout"}
	LOD 200
	Cull Off
CGPROGRAM
#pragma surface surf SoftLight alphatest:_Cutoff vertex:vert exclude_path:prepass addshadow    

half4 LightingSoftLight (SurfaceOutput s, half3 lightDir, half atten) {
	half NdotL = 0.35 * abs(dot (s.Normal, lightDir)) + 0.35 * lightDir.y;
	half4 c;
	c.rgb = s.Albedo * _LightColor0.rgb * (NdotL * atten * 2);
	c.a = s.Alpha;
	return c;
}

sampler2D _MainTex;
fixed4 _Color;
uniform float _Wind;
uniform float _WindStrength;
uniform float _WindDX;
uniform float _WindDY;

struct Input {
	float2 uv_MainTex;
	float4 color : COLOR;
};

void vert (inout appdata_full v)
{
	float ww = (0.25 - abs(sin(_Wind + v.texcoord1.y)) * 0.25) * _WindStrength * v.texcoord1.x;
	v.vertex += float4(ww * _WindDX, -ww * 0.5, ww * _WindDY, 0);	
	v.normal += float4(ww * _WindDX, -ww * 0.5, ww * _WindDY, 0);	
}

void surf (Input IN, inout SurfaceOutput o) {
	fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
	o.Albedo = c.rgb * IN.color * 1.5;
	o.Alpha = c.a;
}
ENDCG
}

Fallback "Transparent/Cutout/VertexLit"
}

alt text

Is there any way to make the deferred renderer pick up the vertex displacement or is this a bug?

Edit: Tried out some more and found out that the problem only arises when “Receive Shadows” is on - “Cast Shadows” makes no problems.

It’s the same in Unity 4.0. To reproduce:

  1. enable deferred rendering in player settings
  2. create a shader with vertex displacement and only forward lighting function, or add exclude_path:prepass
  3. apply the shader to a mesh with receive shadows enabled

Voilà.

Hi!

Maybe this helps somebody.