Ok, sort of. After much experimenting, this is the simplest method I could come up with.
This method uses linear depth, and reconstructs the position in world space.
To store the position:
/* Vertex Shader */ float4 viewPosition = mul(input.Position, mul(World, View)); output.Depth = (-viewPosition.z - NearPlane) / (FarPlane - NearPlane); /* Pixel Shader */ output.Depth = input.Depth; // Um... yeah... just output the depth...
To reconstruct the position, we're going to interpolate between the camera's frustum corners.
So:
/* Your Code (C#) */ BoundingFrustum frustum = new BoundingFrustum(view * projection); effect.SetParameter["FrustumCorners"].SetValue(frustum.GetCorners());
/* Screen Space Pixel Shader */ float depthSample = tex2D(DepthTextureSampler, screenCoord); float3 position = lerp( lerp( lerp(FrustumCorners[0], FrustumCorners[1], screenCoord.x), lerp(FrustumCorners[3], FrustumCorners[2], screenCoord.x), screenCoord.y), lerp( lerp(FrustumCorners[4], FrustumCorners[5], screenCoord.x), lerp(FrustumCorners[7], FrustumCorners[6], screenCoord.x), screenCoord.y), depthSample);
So there you have it.
View comments