5
\$\begingroup\$

I'm relatively new to DirectX, and am currently converting some WPF 2D graphics code that displays geo-located sonar returns. I am using SharpDX, and rendering via a D3DImage.

I've got the basics working nicely, with very good performance, rendering segments of sonar as a set of quads textured via a texture array of chunks of sonar data.

I am now trying to modify the pixel shader so that it shows the highest "quality" signal return in the case where I have an overlap. Consider that the sonar return spreads from a central point, and (generally) gets worse the further away it is. When we have an overlap, a starting point to showing only the best data is to simply show the pixels that are nearest to the centre of the track, and a simple way I thought to do this would be to modify the depth values in the pixel shader so that the depth varies with the signal distance.

I have added a PS_OUT struct as so:

struct PS_OUT
{
    float4 Colour   : SV_Color;
    float Depth     : SV_Depth;
};

and a simplified version of the PixelShader:

    float quality = 1 - input.domain_uv.x;
    result.Colour = float4(quality, quality, quality, 1);
    result.Depth = quality;
    return result;

where the quality value varies from 0-1, and in this example I am also colouring the output with this quality value:

"depth" output

..which gives the expected colour output, but not the depth output. What I expect (want!) is that the higher quality (lighter coloured) output is preferred over the dark on a per-pixel basis.

I can confirm that depth testing is enabled, as I can vary the z coordinates of my quads and see the results. What seems to be my sticking point is that the depth value I calculate in the pixel shader is simply ignored, and my best guess is that I am missing something obvious - like I need to tell Directx to use it, and not its own calculated values. I can't find any documentation that suggests anything other than modifying the shader semantics is required.

The depth buffer/stencil is set up like this - this is taken from a WPF/SharpDX integration package:

 Set(ref m_depthStencil, DXUtils.CreateTexture2D(this.m_device, w, h,    BindFlags.DepthStencil, Format.D24_UNorm_S8_UInt));
  //Set(ref m_depthStencil, DXUtils.CreateTexture2D(this.m_device, w, h, BindFlags.DepthStencil, Format.D32_Float));
 Set(ref m_depthStencilView, new DepthStencilView(this.m_device, m_depthStencil));

 m_device.ImmediateContext.Rasterizer.SetViewports(new ViewportF[] { new ViewportF(0, 0, w, h, 0.0f, 1.0f) }, 1);
 m_device.ImmediateContext.OutputMerger.SetTargets(m_depthStencilView, m_renderTargetView);

I did try varying the texture format (see commented line), to no avail.

Subsequent to this, I also want to blend the very edges of the joins - but I'll leave that question for another day.

thanks, Matt

edit: I can simulate the final effect that I am after by adjusting the depths of my quad vertices such that the middle is lower than the outer. Depths are then "real" depths, and the correct pixels are drawn. I don't think, however, that this is going to work as a solution for me because I want to be able to implement a slightly more complicated "quality" metric in the pixel shader. SO the question remains: why are my depth values calculated in the PS being ignored?

Here's an image of overlapping tracks where the "closest" pixel is rendered at all times:

Closest pixel rendered

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

There is a chance that your depth value calculation is wrong. The way the GPU's are calculating the depth values is not that simple. For example if we take a point right in the middle between the near and far planes of the camera, the depth value is not 0.5 .

You can refer to this post by Steve Baker to see how you can calculate the depth value: http://www.sjbaker.org/steve/omniv/love_your_z_buffer.html

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .