Sign in to follow this  
Skiz0

Issue when downsampling MSAAX2 depth buffer

Recommended Posts

Hi, I am having some issues when downsampling a MSAAx2 depth buffer and using it when redenring in a 1x buffer: Here is a quick summary of what I do: The opaque objects are rendered in a RGBA8 MSAA 2x, and translucent objects in a FP16 1x Buffer. After rendering the opaque objects, the MSSA 2x depth buffer as well as the MSAA 2x color buffer get downsampled using a draw quad and a specific pixel shader. Once done, the translucent objects are drawn into the FP16 buffer using the downsampled depth buffer . Fragment from the translucent objects are testing against the 1x zbuffer and some pixels are not drawn because of the loss of precision during the depth buffer downsampling. I tried several methods to ensure to get the best depth buffer downsample technique: Everything is in float in the fragement shader, When sampling the 2x depth buffer, the sampler filters are correctly set to NEAREST, texture is correctly aliased to a RGBA8 value without sRGB correction and the depth value is retrieved using texDepth2D in the FP. Here are the different techniques I tried: Getting the 2 neighbours value of depth:
void PS(PixelInput IN, out float d : DEPTH)
{
	#define DEPTH(POS) texDepth2D(MSAADepthSampler, (POS))

	const float2 offset0 = float2(1.0f / 2560.0f, 0.0f); // sample from MSAA2x Depth buffer 
	float z1 = DEPTH(IN.UV0 + offset0);
	float z2 = DEPTH(IN.UV0 - offset0);
	d = min(z1, z2)
}
Averaging 2 depth values in camera space and put it back in [0;1] space:
void PS(PixelInput IN, out float d : DEPTH)
{
    #define DEPTH(POS) texDepth2D(MSAADepthSampler, (POS)) // sample from MSAA2x Depth buffer 

    float n = ProjectionClipNearFar.x;
    float f = ProjectionClipNearFar.y;
    float a0 = (-2*f*n);
    float a1 = (f-n);
    float a2 = (f+n);

    const float2 offset0 = float2(1.0f / 2560.0f, 0.0f);
    float z1 = DEPTH(IN.UV0 + offset0);
    float z2 = DEPTH(IN.UV0 - offset0);

    z1 = (z1 * 2.0f) - 1.0f; //[-1;1]
    z2 = (z2 * 2.0f) - 1.0f; //[-1;1]

    //http://en.wikipedia.org/wiki/Z-buffer
    //z = (-2*f*n) / ((z * (f-n)) - (f+n));
    z1 = a0 / ((z1 * a1) - a2); // Camera space
    z2 = a0 / ((z2 * a1) - a2); // Camera space

    float z = (z1 + z2) * 0.5f; // Average

    z = (a2/a1) + ((1.0f/z) * (a0/a1)); // [-1;1]

    d = (z * 0.5f) + 0.5f; // [0;1]
}
Any idea, or any suggestion would be highly appreciated. Thanks

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