Jump to content
  • Advertisement
Sign in to follow this  
Giallanon

From Z buffer to world coordinate

This topic is 4347 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Giving the zbuffer filled with values from 0 to 1, I'm trying to get back the source world coordinate. What I'm doing right now is this: - IN.texSrc is 0,0 in the top left corner and 1,1 in the bottom right (a fullscreen quad). - invCamMatrix is the inverse of view*prj matrix - sampler2 is the texture filled with zvalue (R32F)
float3  screenCoord;
screenCoord.x = (IN.texSrc.x*2.0f) -1.0f;    // range from -1 to 1
screenCoord.y = 1.0f - (IN.texSrc.y*2.0f);   // range from 1 to -1
screenCoord.z = tex2D(sampler2,IN.texSrc).r; // z value 0 to 1

float4 worldCoord = mul (float4(screenCoord,1.0f),invCamMatrix);
worldCoord.xyz /= worldCoord.w;

I think this should work (and it seems to works...sometimes) but I believe i'm getting wrong world coordinate when the zbuffer value are close to 0 (maybe due to precision errors). I know that in the "deferred shading" way of rendering you've to get back the world position from the zbuffer just like I need to and so, I'd like hear if you have some tips to give me to improve the quality.

Share this post


Link to post
Share on other sites
Advertisement
If you are using a 32 bit floating point format you should have enough precision right up to the near clipping plane. Are you doing any filtering on your texture sampler? Make sure you are using point sampling (you probably are, but just checking) and not linear or aniso.

What type of values are you getting when the z values are very small?

Share this post


Link to post
Share on other sites
Mmm after a lot of investigation, I think the problem is not with the inverse transformation but with the z value.

To calculate the z value, I'm doing like this:

float3 f3WorldPos= mul (IN.pos,matW).xyz;
OUT.pos = mul (float4(f3WorldPos,1.0f),matVP);
OUT.f1Depth = OUT.pos.z/OUT.pos.w;
return OUT;


where matW is the world matrix, matVP is the View*Projection matrix.
f1Depth is the z value I'm storing in the R32F texture.

I'm not sure this is the right value to store.

Any tips ?

Share this post


Link to post
Share on other sites
Try doing the transform in one multiplication instead of two. I think setting the w coordinate to 1 after the first mul may cause trouble.

Share this post


Link to post
Share on other sites
Thank you...I'll try that but I think that the 4th coloumn of the world matrix is alway 0 0 0 1 so the world.w should be always 1...but anyway you never know..

Share this post


Link to post
Share on other sites
Well, I've found a solution.
After all, there was nothing wrong with my shaders. The problem was the interpolation.

I was filling the texture with z value calculated in the vertex shader like this : z=OUT.pos.z/OUT.pos.w
The pixel shader was as simple as writing the z value from the vertex shader
OUT.col.rgba = float4(IN.z,0,0,0)

This was not working due to interploation error (I guess)

What I do now, is this:
in vertex shader:
f2Depth.xy = OUT.pos.zw
in pixel shader
OUT.col.rgba = float4(IN.f2Depth.x/IN.f2Depth.y,0,0,0)

I'm calculating the z value (POS.z/POS.w) in the pixel shader (ie: for every texel) instead of calculating it in the vertex shader and let the pipeline to interploate it for me.
This is working :-)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!