Sign in to follow this  
AgentSnoop

Reconstructing position from depth questions

Recommended Posts

AgentSnoop    110
Hey everyone. I know this topic has been posted a few times, and I've read them for the most part, I've seen other webpages regarding the topic (http://mynameismjp.wordpress.com/2009/05/05/reconstructing-position-from-depth-continued/), however, I'm having some trouble on it and I want to do if I'm making progress. I am trying to set up deferred lighting with shadow mapping now, so I want to reconstruct either world position or view position from my depth buffer. I'm trying to use the frustum corners method, but I'm not sure what my result should look like (full-screen quad): when I output the view-space position as colors, or my view direction as colors. Basically, I'm seeing my terrain (what I'm rendering) with sectors of color (red, yellow, green, black, white, magenta, cyan, green), and the colors more or less move with the camera. Currently I have view direction set up so it when you output it as colors you get: ________ | 1 | 2 | |__|___| | 3 | 4 | |__|___| where 1 is green, 2 is yellow, 3 is black, and 4 is red. Once I get this to work correctly, I can move on to shadows and what not, but everything else seems pretty dependent on this. So, what should I expect when outputing view position, world position, view direction, etc as colors? If you need more information, screen shots, just let me know. Thanks for any help!

Share this post


Link to post
Share on other sites
rubicondev    296
Sounds like you need to multiply your colours by 0.5 and add 0.5 to get all the colour you need. -1 to +1 is going to get clamped to 0 - 1 whatever you do.

I have a complete bit of source for setting this up in my SSAO tutorial over at www.rubicondev.com if you want to check that out.

Share this post


Link to post
Share on other sites
AgentSnoop    110
Alright, that makes sense. I guess I'm not really sure what I should be looking at when I output the view space position that I reconstruct.

This is what I get:
viewspace

This is with shifting the colors to positive ranges. So, those four colors are screen aligned, so they'll move around on the terrain.

Is this correct?

EDIT: Alright, so the picture I posted is slightly wrong, because apparently I was sending the nearclip distance as farclip, so I wasn't getting a proper view space depth. So I now have reconstructed view space positions, but world space positions still don't exactly seem correct.

[Edited by - AgentSnoop on November 10, 2009 6:43:45 PM]

Share this post


Link to post
Share on other sites
AgentSnoop    110
Ok, so this is what I'm getting for world space position:

This is how it's suppose to be (I assume.. I'm outputting this directly)
worldpos
And this is what I'm getting when I try to reconstruct it:
worldpos

The reconstruction is close, but the sectors move with the camera angle (and position maybe), and if I'm looking straight across, or more upwards (more prevalent when the camera is higher up), the blue, black, etc, start to come out as seen above.

I'm using the frustum corners in world space. Then,

float3 frustumRayWS = IN.frustum;
float3 wPos = depth * frustumRayWS + eyepos;

I think reconstructing view space works, but then when I try to transform the position to the light view space, etc, I seem to get weird results.

Even the ways that are more mathematically intensive aren't working correctly, like:
float4 hPos = float4(IN.hPos.xy, depth * IN.hPos.w, IN.hPos.w);
float4 wPos4d = mul(hPos, matViewProjInv);
float3 wPos3d = wPos4d.xyz / wPos4d.w;

EDIT: Also, apparently I can take wPos and multiply it by the view matrix to get what I believe I should get for view space position, so I'm not exactly sure if what I'm getting for world space position is correct or not.

[Edited by - AgentSnoop on November 11, 2009 1:19:19 AM]

Share this post


Link to post
Share on other sites
AgentSnoop    110
Alright, I figured out the problem. So in case anyone else happens to have this problem (doubtful most people will), here's the solution.

So, I was constructing view/world space correctly; however, when making my frustum corners, I copied how I saw it else where:

float farH = 2 * tanf(fov / 2.0f) * farZ;
float farW = farH * aspect;

float nearH = 2 * tanf(fov / 2.0f) * nearZ;
float nearW = nearH * aspect;

float nearX = nearW / 2.0f;
float nearY = nearH / 2.0f;
float farX = farW / 2.0f;
float farY = farH / 2.0f;

However, I was not setting up my perspective matrix like this, I was messing around with being able to set vertical and horizontal FOVs, so I needed to set my farW differently... essentially the same as farH, but with the FOV i used for the horizontal. This pretty much fixed everything up.

Now I'm just trying to get the shadowing to work. I'm having a weird banding issue where it seems values are going out of bounds (negative, then extreme positive real fast) with my rotating directional light. I'm going to have to investigate it a little bit.

Share this post


Link to post
Share on other sites
MJP    19755
Quote:
Original post by AgentSnoop
Now I'm just trying to get the shadowing to work. I'm having a weird banding issue where it seems values are going out of bounds (negative, then extreme positive real fast) with my rotating directional light. I'm going to have to investigate it a little bit.


Are you using DirectX? Debugging shaders in PIX works wonders for this sort of thing.

Share this post


Link to post
Share on other sites
AgentSnoop    110
Quote:
Original post by MJP
Are you using DirectX? Debugging shaders in PIX works wonders for this sort of thing.


Hey, thanks for the suggestion. I played a little bit with it last night and seems like a valuable tool.

Anyway, I had a question for you, I'm looking at what you wrote at http://mynameismjp.wordpress.com/2009/05/05/reconstructing-position-from-depth-continued/ :

void VSBoundingVolume( in float3 in_vPositionOS : POSITION,
out float4 out_vPositionCS : POSITION,
out float3 out_vPositionVS : TEXCOORD0 )
{
out_vPositionCS = mul(in_vPositionOS, g_matWorldViewProj);

// Pass along the view-space vertex position to the pixel shader
out_vPositionVS = mul(in_vPositionOS, g_matWorldView);
}

float3 VSPositionFromDepth(float2 vTexCoord, float3 vPositionVS)
{
// Calculate the frustum ray using the view-space position.
// g_fFarCip is the distance to the camera's far clipping plane.
// Negating the Z component only necessary for right-handed coordinates
float3 vFrustumRayVS = vPositionVS.xyz * (g_fFarClip/-vPositionVS.z);
return tex2D(DepthSampler, vTexCoord).x * vFrustumRayVS;
}

Does this only work for reconstructing view space, or can it be used for reconstructing world space as well?

Also, thanks for all the indirect help with writing the articles.

Share this post


Link to post
Share on other sites
AverageJoeSSU    564
the out put your getting is similar to what i got.

i am not reconstructing depth yet, but the output should not look different.

you can see a bunch of videos of my stuff here. I am using OpenGL and my coordinate system is flipped compared to yours (i think). so your output looks normal.

Share this post


Link to post
Share on other sites
MJP    19755
Yeah, you can make that work for world-space. You can either simply take the view-space position that you get and transform it by the inverse of your view matrix, or you rotate (not translate) vFrustumRayVS by the inverse of the view matrix so that it's in world space. Something like this should work (not tested):


float3 vFrustumRayVS = vPositionVS.xyz * (g_fFarClip/-vPositionVS.z);
float3 vFrustumRayWS = mul(vFrustumRayVS, (float3x3)matInvView);
return camPosWS + tex2D(DepthSampler, vTexCoord).x * vFrustumRayWS;


matInvView would be your inverse view matrix (the world matrix of your camera), and camPosWS would be the world-space position of your camera.

Share this post


Link to post
Share on other sites
AgentSnoop    110
Quote:
Original post by MJP
Yeah, you can make that work for world-space. You can either simply take the view-space position that you get and transform it by the inverse of your view matrix, or you rotate (not translate) vFrustumRayVS by the inverse of the view matrix so that it's in world space. Something like this should work (not tested):


float3 vFrustumRayVS = vPositionVS.xyz * (g_fFarClip/-vPositionVS.z);
float3 vFrustumRayWS = mul(vFrustumRayVS, (float3x3)matInvView);
return camPosWS + tex2D(DepthSampler, vTexCoord).x * vFrustumRayWS;


matInvView would be your inverse view matrix (the world matrix of your camera), and camPosWS would be the world-space position of your camera.


Ah, that makes sense. Thank you very much!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this