• Advertisement
Sign in to follow this  

Sampling from Depth Buffer

This topic is 587 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

HI All,

 

I think I have most of this working, but you guys might be able to pick out where I am going wrong.

 

I'm going through and creating a resourceview for my depth buffer. I've tested everything and its green in the code.  No error results or warnings (with debug etc all on).

              D3D11.DepthStencilViewDescription stencilBufferViewDesc = new D3D11.DepthStencilViewDescription()
                {
                    Dimension = D3D11.DepthStencilViewDimension.Texture2DMultisampled,
                    Format = DXGI.Format.D24_UNorm_S8_UInt,
                    Flags = D3D11.DepthStencilViewFlags.None,
                    Texture2DMS = new D3D11.DepthStencilViewDescription.Texture2DMultisampledResource(),                    
                };



                D3D11.Texture2DDescription desc = new D3D11.Texture2DDescription()
                {
                   Format = DXGI.Format.R24G8_Typeless,                    
                    ArraySize = 1,
                    MipLevels = 1,
                    Width = m_gameResolution.Width,
                    Height = m_gameResolution.Height,
                    Usage = D3D11.ResourceUsage.Default,
                    SampleDescription = new DXGI.SampleDescription(s_antiAliasSample, 0),
                    BindFlags = D3D11.BindFlags.DepthStencil | D3D11.BindFlags.ShaderResource,
                    CpuAccessFlags = D3D11.CpuAccessFlags.None,
                    OptionFlags = D3D11.ResourceOptionFlags.None
                };
                m_depthBuffer = new D3D11.Texture2D(m_device, desc);
                m_stencilView = new D3D11.DepthStencilView(m_device, m_depthBuffer, stencilBufferViewDesc);

                /*---------------------------------------------*/
                // Creating depth buffer as resource



                D3D11.ShaderResourceViewDescription shaderResourceView = new D3D11.ShaderResourceViewDescription()
                {

                    Dimension = ShaderResourceViewDimension.Texture2DMultisampled,
                    Format = DXGI.Format.R24_UNorm_X8_Typeless,

                    //Flags = D3D11.DepthStencilViewFlags.None,
                    Texture2DMS = new D3D11.ShaderResourceViewDescription.Texture2DMultisampledResource()
                };

                // this is used to sample the DEPTH buffer!
                m_depthShaderResource = new D3D11.ShaderResourceView(m_device, m_depthBuffer, shaderResourceView);                

                m_renderTargetView = new D3D11.RenderTargetView(m_device, m_swapChainBuffer);

I am using a Texture2dMS so I have to use load to sample the texture in my fx code. But. I'm getting an exception thrown in my HLSL code.

 

No real error, not even with debugging in.  Just says something external has thrown an exception.  

 

I've defined my texture as in the fx code.

 

Texture2DMS<float4, 4> depthTexture;

 

I sample using the middle of the screen.  My expectation is that the entire landscape should change to a darker colour as I zoom out.  proving that I am indeed reading from the zbuffer correctly.

 

    texCoord.x = 0.5f;
    texCoord.y = 0.5f;
 
    float4 color = depthTexture.Load(texCoord, 0);

 

I update this from my main loop using "SetResource" and passing the depthshaderresource in.  

 

I've spent a fair bit of time on this. with no success.  including:

 

- Defining another texture (multisample) and using copy resource.  This doesn't cause an exception but I dont seem to get any thing from the sample that changes the colour.  I use copyresource after all the landscape is rendered and zbuffer written to (assume this).  NO errors, but no results on screen.  its always fully white.

 

- tried to define a single sample texture and use ResolveSubresource to downsample, but I can't find any formats where it will allow me to resolve. spent hours on this to no avail.

 

I'm sure im doing something simply wrong here, but I just can't find it.

 

 

 

 

 

 

 

    texCoord.x = 0.5f;
    texCoord.y = 0.5f;
 
    float4 color = depthTexture.Load(texCoord, 0);

Share this post


Link to post
Share on other sites
Advertisement
  1. Your shader should not be compiling. texture.Load requires integer arguments. To sample in the middle of a 1920x1080 depth buffer, you need to pass 960 & 540; not 0.5
  2. Depth buffers are not linear. They often do not work in visible ranges. It may be working but you're just not noticing visible changes. One solution is to pow() the sample to bring the range to something more visible.

Share this post


Link to post
Share on other sites

So, I fixed up the co-ordinates issue, still get a access violation in the shader.  

 

SO I changed tack to use a staging texture and copy the depth buffer across using Copy Resource.  No more access violation ,but but now when it copies, the terrain is all red.  Which is in line with a freshly cleared Z Buffer.  but I've drawn to the zbuffer before this, so Im perplexed, I seem to be copying nothing across.

 

I tested the pixel shader to ensure it at least displayed colours with a simple posz/posw test and it works.  But the copyresource seems to be doing nothing.

                // Depth Buffer

                D3D11.DepthStencilViewDescription stencilBufferViewDesc = new D3D11.DepthStencilViewDescription()
                {
                    Dimension = D3D11.DepthStencilViewDimension.Texture2DMultisampled,
                    Format = DXGI.Format.D24_UNorm_S8_UInt,
                    Flags = D3D11.DepthStencilViewFlags.None,
                    Texture2DMS = new D3D11.DepthStencilViewDescription.Texture2DMultisampledResource(),                    
                };


                D3D11.Texture2DDescription desc = new D3D11.Texture2DDescription()
                {
                   Format = DXGI.Format.D24_UNorm_S8_UInt,                    
                    ArraySize = 1,
                    MipLevels = 1,
                    Width = m_gameResolution.Width,
                    Height = m_gameResolution.Height,
                    Usage = D3D11.ResourceUsage.Default,
                    SampleDescription = new DXGI.SampleDescription(s_antiAliasSample, 0),
                    BindFlags = D3D11.BindFlags.DepthStencil ,
                    CpuAccessFlags = D3D11.CpuAccessFlags.None,
                    OptionFlags = D3D11.ResourceOptionFlags.None
                };
                m_depthBuffer = new D3D11.Texture2D(m_device, desc);
                m_stencilView = new D3D11.DepthStencilView(m_device, m_depthBuffer, stencilBufferViewDesc);

                // END DEPTH BUFFER ------------------------------------------------------------------------

                /*---------------------------------------------*/
                // Creating depth buffer textureresource

                D3D11.Texture2DDescription desc2 = new D3D11.Texture2DDescription()
                {
                    Format = DXGI.Format.R24G8_Typeless,
                    ArraySize = 1,
                    MipLevels = 1,
                    Width = m_gameResolution.Width,
                    Height = m_gameResolution.Height,
                    Usage = D3D11.ResourceUsage.Default,
                    SampleDescription = new DXGI.SampleDescription(s_antiAliasSample, 0),
                    BindFlags =  D3D11.BindFlags.ShaderResource,
                    CpuAccessFlags = D3D11.CpuAccessFlags.None,
                    OptionFlags = D3D11.ResourceOptionFlags.None
                };
                m_depthBufferTexture = new D3D11.Texture2D(m_device, desc2);


                D3D11.ShaderResourceViewDescription shaderResourceView = new D3D11.ShaderResourceViewDescription()
                {
                    Dimension = ShaderResourceViewDimension.Texture2DMultisampled,
                    Format = DXGI.Format.R24_UNorm_X8_Typeless,                               
                 Texture2DMS = new D3D11.ShaderResourceViewDescription.Texture2DMultisampledResource(),
                }; 

                // this is used to sample the DEPTH buffer!
                m_depthShaderResource = new D3D11.ShaderResourceView(m_device, m_depthBufferTexture, shaderResourceView);

Im assuming I should be pulling the texture2d resources from resourceviews.

        public void updateBackBufferTexture()
        {
            D3D11.Texture2D source;
            D3D11.Texture2D destination;

            source = m_stencilView.ResourceAs<D3D11.Texture2D>();
            destination = m_depthShaderResource.ResourceAs<D3D11.Texture2D>();

            m_device.ImmediateContext1.CopyResource(source, destination);
        }

Share this post


Link to post
Share on other sites

A couple of nuggets I read about, more like well Duh moments.

 

1 - I should unbind my depth buffer from rendertargets before copying.

2 - I should for my pixel shader have a set of the transformed vertex co-ordinates stored in a texture variable and passed as input.  Because using the SV_Position values is bad, mainly because they are offset by 0.5.  So in vertex shader, just pop the converted position into a texture variable prior to exit from the function.

3 - check my clip planes that they are set correctly.  Ala that they aren't too far apart therefore the values in the buffer are not just between 0.999 and 1.0

 

I will try these 3 things tonight.  If successful, will post for future reference in here.

Edited by ErnieDingo

Share this post


Link to post
Share on other sites

Ok, its SOLVED!

 

A few things.  

 

Firstly, I wasn't setting my Rendertarget to Null for depthstencil, but I found that it was an intermittent problem if I used CopyResource without setting this to null, I assume because the resource may or may not be available due to renderer still using it.  So for correct usage, I did reset this to null when I wanted to copy the resource.

 

Secondly, I was about to sample the depth buffer correctly after reading a write up on the rastertek website.

 

I've add this code to my gpu code.

    int2 xy;

    xy.x = input.uv.x * 1920;
    xy.y = input.uv.y * 1080;


    float4 color = depthTexture.Load(xy, 2);
    color.w = 1.0f;

    float depthValue = color.r;

	// First 10% of the depth buffer color red.
	// First 10% of the depth buffer color red.
    if (depthValue < 0.9f)
    {
        color = float4(1.0, 0.0f, 0.0f, 1.0f);
    }
	
	// The next 0.025% portion of the depth buffer color green.
    if (depthValue > 0.9f)
    {
        color = float4(0.0, 1.0f, 0.0f, 1.0f);
    }

	// The remainder of the depth buffer color blue.
    if (depthValue > 0.925f)
    {
        color = float4(0.0, 0.0f, 1.0f, 1.0f);
    }

What this does is render the depth buffer value based on colour.  So on my uniform grid, the colours change on each quad based on this.  As per screenshots, as I look up, the colour blue becomes more predominant as the Z Buffer is dominated more by mid range geometry.  So its working, thanks all

example1.png

 

example2.png

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement