How to get the world position of a vertex in a shader?

I am trying to get the world position of a vertex into my fragment shader but the _Object2World translation done in the vertex shader doesn’t appear to be working. Is there something I need to do in scripting such that the _Object2World matrix is setup/updated?

Below is my simplified shader. We are using the 3.4.2f3 version of unity.
My scene for this test contains:

plane pos: 0,0,100 rotation: 270,0,0 scale: 5,5,5

cube pos: 0,0,20 rotation: 0,0,0 scale: 1,1,1

camera pos: 0,0,0 rotation: 0,0,0 scale: 1,1,1

The result of this shader when applied to the scene is always red. I would expect to see green because the wpos.z should be in world coordinates and the vpos.z would still be in object coordinates.
Note that I did see a similar question(“How to get the global position of a vertex in a Cg vertex shader?”) in “Unity Answers” and have tried to make my vertex shader do exactly the same thing as the response to that question but it still doesn’t work as expected.

Help!

Shader “DepthEffect”
{
Properties
{
_MainTex (“Base (RGB)”, 2D) = “white” {}
}
SubShader
{
Pass
{
ZTest Always Cull Off ZWrite Off
Fog { Mode off }

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

sampler2D _MainTex;

struct v2f
{
float4 pos : POSITION;
float2 uv : TEXCOORD0;
float3 wpos : TEXCOORD1;
float3 vpos : TEXCOORD2;
};

v2f vert( appdata_img v )
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
float3 worldPos = mul (_Object2World, v.vertex).xyz;
o.wpos = worldPos;
o.vpos = v.vertex.xyz;
o.uv = v.texcoord.xy;
return o;
}

float4 frag (v2f i) : COLOR
{
if (i.vpos.z == i.wpos.z)
return float4(1,0,0,1);
else
return float4(0,1,0,1);
}
ENDCG
}
}
FallBack “Diffuse”
}

Wouldn’t o.pos after “mul(UNITY_MATRIX_MVP, v.vertex);” be the world position?

I don’t know Unity’s defines, but the short answer is to multiply it by the WorldViewProjection matrices/Matrix, which it looks like that line is doing.

Edit NM, correcting this, it should only be multiplied by the M(Model) in MVP. That looks like it would be the line you already tried, sorry looks like I’m no help.

Where does _Object2World get set by Unity? I’m thinking that maybe it is not being updated with the model matrix for each rendered game object. I suspect that _Object2World is the identity matrix. I will try to confirm that. Note that I tried adding the commented lines below to the vertex shader and the value makes it to the fragment shader since it renders green. This just confirms that the position vector is making it from the vert shader to the frag shader. Getting the correct world value into wpos within the vert shader is the problem.

v2f vert( appdata_img v )
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
float3 worldPos = mul(_Object2World, v.vertex).xyz;
//if (worldPos.z == v.vertex.z)
// worldPos = float3(0,0,40);
o.wpos = worldPos;
o.vpos = v.vertex.xyz;
o.uv = v.texcoord.xy;
return o;
}