Weird world coordinate for post process pixel

Hi everyone,

I know what I am asking have been answered thousands of time, but I have a probelm that I can’t resolve though everything that I found on the internet, here it is:

I need to achieve a post process effect, a bit like a deferred lightening : I have a “source” object in the scene, which is a sphere. This sphere must changes all pixel in it radius from an original color into another one.

I based my code with this link there :
http://forum.unity3d.com/threads/97671-world-position-of-a-pixel-from-depth-texture
http://forum.unity3d.com/threads/151466-World-position-from-depth

I also tried with the Built-In Lightening PrePass shader from Unity, but no one of the method I am using is correct.

Here is a screenshot showing what I can’t achieve: As you can see, the red pixels are the one spheres (transparent in blue) are supposed to change, but there is something wrong with my 2D to 3D position calculation.

In my PostProcess script, attached to my camera, I’m using this line of code to send a “viewprojection inverse matrix”, and giving my “sphere world 3D position”:

m_materialPostProcess.SetMatrix ("_InvMatrix", (camera.projectionMatrix * camera.worldToCameraMatrix ).inverse);
m_list.ForEach (delegate(GameObject src)
{
     ...
    m_materialPostProcess.SetVector ("_Position", src.transform.position);
     ...
});

And here is my 2D to 3D coordinate shader code:

sampler2D _CameraDepthTexture;
float4x4 _InvMatrix;
float3 _Position;
	
struct v2f
{
	float4 pos : SV_POSITION;
	float2 uv : TEXCOORD0;
};

v2f vert(appdata_base v)
{
	v2f o;
	o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
	o.uv = v.texcoord.xy;
	return o;
}

half4 frag(v2f i) : COLOR
{    
	float2 uv = i.uv.xy * 2 - 1;
	float depth = UNITY_SAMPLE_DEPTH(tex2D(_CameraDepthTexture, i.uv.xy));
	
	//Get World Position in World Coordinate
	//H is the viewport position at this pixel in the range -1 to 1.
	float4 H = float4(uv, depth, 1);
	float4 D = mul(_InvMatrix, H);
	float3 wpos =  D.xyz / D.w;
	
    ...
}

I know this has been answered thousands of time, but i’m at a point where I can’t find any solution !
If you have any advice, i’ll be glad to hear where I’m wrong or if what i’m trying to do can’t be achieved the way i’m doing,

Thanks !

ACtually, that is caused by depth textures precision, the position values shift slightly.
Try to use other method with ray casting on camera frustum planes. You can see the example in unity provided Global Fog shader. And/Or height fog in my post process effects pack.

Thanks you very much for your reply Aubergine, it works very well !

The Global Fog is a very interesting script to see this kind of manipulation, even I am not sure to understand all of what is going on in the “black box” of this shader :wink:

Thank you for aiming me in the right direction !