[sub] world space reconstruction from a view space depthmap

Posted By: txesmi

[sub] world space reconstruction from a view space depthmap - 04/04/13 09:13

Hi,
I finally found a way to reconstruct the world space coords of a scene from a prerendered depthmap in view space. It has been quiet hard for me to find the proper info so I decided to share it. It is probably not the best way but it works!

I wanted to render the depthmap in view space because its linear distribution.

The view space depth is computed in the object shader
Code:
// vs
outDepth = mul ( inPos, matWorldView ).z;
// ps floating point bitmap
return float4 ( inDepth, 0, 0, 1.0f );
// ps packed for 8 bits bitmap channel
float viewDepth = ( inDepth - camera.clip_near ) / camera.view_fustrum_depth; //*


*view_fustrum_depth = clip_far - clip_near;

The deferred pass needs to convert the screen coords to any point in clip space in order to convert it to view space by inverse projection matrix multiply.
Code:
float4 Proj = float4 ( 2.0f * float2 ( inTex.x, 1.0f - inTex.y ) - 1.0f, fAnyDepth, 1.0f );
float3 View = mul(Proj, matProjInv).xyz;



This randomly selected point certainly describes the camera projection ray for the actual screen pixel, so we can scale its coords by the relation between the point depth and the depthmap value, and get the renderered coords in view space.
Code:
float fDepth = tex2Dlod ( DepthSampler, inTex ).r;
View = float3 ( View.xy * fDepth / View.z, fDepth );



Finally we only need to convert the view space coords to world space with the inverse view matrix.
Code:
float3 World = mul ( float4(View.xyz,1.0f), matViewInv ).xyz;



Hope it helps.
Salud!
Posted By: Kartoffel

Re: [sub] world space reconstruction from a view space depthmap - 04/04/13 11:19

thanks a lot! I'm currently trying to make my deferred renderer better and wanted to use z-Reconstrunction for the world coords in order to keep the gBuffer slim.

oh and talking about useful shader code (and if you don't mind contributing), this might be helpful as well (especially for SSAO or RLR):
convert world- to screen-space coordinates
Code:
float2 worldToScreenSpace(float3 worldPos)
{
	float3 temp = mul(worldPos - vecViewPos.xyz, matViewProj);
	
	temp *= 1 / temp.z; // normalize to z = 1
	return temp.xy * float2(0.5, -0.5) + 0.5 + vecViewPort.zw * 0.5; // final coords
}

Posted By: Hummel

Re: [sub] world space reconstruction from a view space depthmap - 04/04/13 14:14

This is what I use for wPos-reconstruction:
Code:
void VS(		
in float4 vPos		   : POSITION,

out float2 OutTex	      : TEXCOORD0,			
out float3 npPos	      : TEXCOORD1,						
out float4 Pos	         : POSITION
)
{
	Pos.xyzw = float4(vPos.xy, 1.f, 1.f);
	
	float2 XY = tan(radians(30)) * float2(1, vecViewPort.y * vecViewPort.z);

	npPos = mul(float4((vPos.xy) * XY, 1, 0), matViewInv).xyz;
	
	OutTex.xy = Pos.xy * float2(1,-1) * 0.5 + 0.5;
	OutTex.xy += vecViewPort.zw * 0.5f;
}

void PS(	
in float2 Tex	      : TEXCOORD0,			
in float3 npPos	   : TEXCOORD1,
//in float4 vPos	      : TEXCOORD2,

out float4 COL :COLOR0
) 
{	
	float Depth = tex2Dlod(DSmp, float4(Tex.xy, 0, 0)).x;
	
	COL.xyz = npPos.xyz * Depth + vecViewPos.xyz;

	//	COL.xyz = tex2D(WPosSmp, Tex).xyz;
	COL.xyz = length(COL.xyz - tex2Dlod(WPosSmp, float4(Tex.xy, 0, 0)).xyz) * 1000;
	COL.w=1;
}

technique Shading
{
	pass P0
	{	
		VertexShader = compile vs_3_0 VS();
		PixelShader  = compile ps_3_0 PS();
	}
}


I'm not using the GS standard pp-stuff since you can't use a custom vertex shader with it and the texture coordinates are weird sometimes. The FOV is hardcoded to 60° here. Note that this is not the actual default arc for views even it is documented this way in the manual (15 is also not the default clip_near..should probably post that in the manual forum too).
Posted By: BoH_Havoc

Re: [sub] world space reconstruction from a view space depthmap - 04/05/13 11:13

This is how i do it in Shade-C EVO

Code:
//Return position in view space
//inTex: texcoords in screenspace
//inDepth: linear depth * clip_far
float3 CalculatePosVSQuad(float2 inTex, float inDepth)
{
	float4 viewRay;
	viewRay.x = inTex.x*2-1;
	viewRay.y = (1-inTex.y)*2-1;
	viewRay.z = 1;
	viewRay.w = 1;
		
	viewRay.xyz = mul(viewRay, matProjInv).xyz;
	return (viewRay.xyz * inDepth);
}

© 2024 lite-C Forums