Help! Trying to convert PlanarShadow to CG

So I’m trying to convert the GLSL shader at GLSL Programming/Unity/Shadows on Planes - Wikibooks, open books for an open world to CG, but something’s going wrong and I don’t even know how to start debugging it. It compiles, but I never see anything, so I’m not really sure where the vertices are going or what’s wrong. My code is as follows. I’ve got a script in the scene setting _World2Receiver to the ground plane’s worldToLocalMatrix.

Shader “PlaneShadow” {
Properties {
_Color (“Shadow’s Color”, Color) = (0,0,0,1)
}
SubShader {
Pass {
Tags { “LightMode” = “ForwardBase” }
Offset -1.0, -2.0
Cull Off

CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include “UnityCG.cginc”

float4 _Color;
float4x4 _World2Receiver;

struct v2f {
float4 pos : SV_POSITION;
};

v2f vert (appdata_base v)
{
// Here’s the beef

v2f o;

float4x4 modelMatrix = _Object2World;
float4x4 modelMatrixInverse = _World2Object;
modelMatrixInverse[3][3] = 1.0;
float4x4 viewMatrix = UNITY_MATRIX_MV * modelMatrixInverse;

float4 lightDirection;
lightDirection = -normalize(_WorldSpaceLightPos0); // assuming a directional light

float4 vertexInWorldSpace = mul(modelMatrix, v.vertex);
float distanceOfVertex =
(mul(_World2Receiver, vertexInWorldSpace)).y; // height over plane
float lengthOfLightDirectionInY =
(mul(_World2Receiver, lightDirection)).y; // length in y direction

lightDirection = lightDirection * (distanceOfVertex / (-lengthOfLightDirectionInY));

o.pos = mul(UNITY_MATRIX_P, mul(viewMatrix, vertexInWorldSpace + lightDirection));

return o;

// That was the beef.
}

half4 frag (v2f i) : COLOR
{
return _Color;
}

ENDCG
}
}
FallBack “Diffuse”
}

UPDATE: I’m an idiot. Used UNITY_MATRIX_MVP where it should have been UNITY_MATRIX_MV. Still getting strange results though, so something’s wrong…I get a strange mess of polygons in no obvious shape from this. And it doesn’t show anything at all without Cull Off.

UPDATE 2: On a whim I replaced the last line of the vertex shader with:

o.pos = mul( UNITY_MATRIX_MVP, v.vertex ) + lightDirection;

and it sort of works now – I get results when the light is pointing only in a certain quadrant. But it still overlaps everything and somehow is only being partly flattened. Could still use some guidance.

Success! Mostly. I got it working – everything happens correctly in the vertex side. Unfortunately, the fragment side still shows some overlaps when I use a transparent color for the shadow. Can anyone diagnose why? Here’s the final shader code:

Shader “PlaneShadow” {
Properties {
_Color (“Shadow’s Color”, Color) = (0,0,0,1)
}
SubShader {
Tags { “LightMode” = “ForwardBase” “Queue”=“Transparent” “IgnoreProjector”=“True” “RenderType”=“Transparent” }
Pass {

Offset -0.1, -0.1
Blend SrcAlpha OneMinusSrcAlpha

CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include “UnityCG.cginc”

float4 _Color;
float4x4 _World2Receiver;

struct v2f {
float4 pos : SV_POSITION;
};

v2f vert (appdata_base v)
{

v2f o;

float4 lightDirection;
lightDirection = -normalize(_WorldSpaceLightPos0); // assuming a directional light

float4 vertexInWorldSpace = mul(_Object2World, v.vertex);
float4 world2ReceiverRow1 =
float4(_World2Receiver[0][1], _World2Receiver[1][1],
_World2Receiver[2][1], _World2Receiver[3][1]);
float distanceOfVertex =
dot(world2ReceiverRow1, vertexInWorldSpace); // height over plane
float lengthOfLightDirectionInY =
dot(world2ReceiverRow1, lightDirection); // length in y direction

if (distanceOfVertex > 0.0 lengthOfLightDirectionInY < 0.0) {
lightDirection = lightDirection * (distanceOfVertex / (-lengthOfLightDirectionInY));
} else {
lightDirection = float4(0.0, 0.0, 0.0, 0.0);
}

o.pos = mul(UNITY_MATRIX_VP, vertexInWorldSpace + lightDirection);
return o;

}

half4 frag (v2f i) : COLOR
{
return _Color;
}

ENDCG
}
}
FallBack “Diffuse”
}