Hello
What i would like to do is to calculate the world space position of a pixel in a pixel shader used on a screen quad.
I understand that this is a "common" topic and i have read several posts about this, but they never show the whole picture and most of them are based on OpenGL when im using Directx 11. Im clearly missing something because its just not working for me.
The first pass in my render loop is to render a simple GBuffer.
struct PixelInputType {
float4 position : SV_POSITION;
float depth : TEXCOORD0;
float2 uv : TEXCOORD1;
float3 normal : TEXCOORD2;
};
PixelInputType vs_main( VertexInputType p_Input ) {
PixelInputType output;
output.position = mul( float4(p_Input.position, 1.0f), PM_MODEL_VIEW_PROJECTION );
output.depth = output.position.z;
// code removed for clairity
return output;
};
struct PixelOutputType {
float4 diffuse;
float4 normal;
float depth;
};
PixelOutputType ps_main( PixelInputType p_Input ) : SV_TARGET {
PixelOutputType output;
// code removed for clairity
output.depth = p_Input.depth / PM_FAR_CLIP;
return output;
}
Then i draw the screen quad where i try to recreate the world space position for each pixel.
Texture2D<float> g_Depth : register( t2 );
float3 world_position_from_depth( float2 uv, float depth ) {
float4 ndc = float4( uv * 2.0f - 1.0f, depth * 2.0f - 1.0f, 1.0f );
float4 clip = mul( ndc, PM_INVERSE_PROJECTION );
float4 view = mul( clip / clip.w, PM_INVERSE_VIEW );
return view.xyz;
}
float4 ps_main( PixelInputType p_Input ) : SV_TARGET {
float depth = g_Depth.Sample( g_ClampSampler, p_Input.uv );
float3 wp = world_position_from_depth( p_Input.uv, depth );
return visualize_position( wp );
}
I then visualize the position based on this thread: https://discourse.threejs.org/t/reconstruct-world-position-in-screen-space-from-depth-buffer/5532
From the result i can clearly tell that something is wrong. My lines are not "stationary" they move around and bend instead of sticking to their world space position when i move my camera in the world.
Shader constants used in the shaders are applied like this
PM_FAR_CLIP = p_Camera->getFarClip(); // 1000.0f
PM_INVERSE_PROJECTION = p_Camera->getProjection().inverse().transpose();
PM_INVERSE_VIEW = p_Camera->getView().inverse().transpose();
PM_MODEL_VIEW_PROJECTION = ( p_Transform * p_Camera->getView() * p_Camera->getProjection() ).transpose();
And finally, the depth target is created using DXGI_FORMAT_R16_FLOAT.
It became quite a long post but i wanted to ensure that i gave as much detail as i could since i cant figure out what im doing wrong.
If you have any suggestion or ideas they more than welcome!