4
\$\begingroup\$

I want to render a depth map by importing it from a file, then creating an array of vertices and indices, and then displaying it using a basic shader (just apply the view and projection matrices on it and then display). I'm aware of GPU-based solutions, however, I want to perform additional calculations using the CPU on the vertices before rendering them.

So, basically what I do is that I have my vertices with there depth in a grid, and then I import my triangles as follows:

+--+--+--+--+--+--+
¦ \¦ \¦ \¦ \¦ \¦ \¦
+--+--+--+--+--+--+   meaning that I simply split every quad spanned by four pixels
¦ \¦ \¦ \¦ \¦ \¦ \¦   into two triangles.
+--+--+--+--+--+--+
¦ \¦ \¦ \¦ \¦ \¦ \¦
+--+--+--+--+--+--+

When I took the first best depth map that I've found on google, I've got this result: Working

However, as soon as I'm moving the camera up, strange things happen: Buggy pic Buggy pic 2

The problem seems to only arise when multiple triangles are rendered behind each other. In this case, a triangle from the back (a black one at infinity depth or a wall behind the front object) seems to shine through. Also, when I use "PIX for Windows", and I use the "Debug this pixel" functionality, I get two triangles for each of the buggy pixels I've checked.

The rendering is done as follows:

Initialize

graphics.PreferredBackBufferWidth = 1280;
graphics.PreferredBackBufferHeight = 720;
graphics.IsFullScreen = false;
graphics.ApplyChanges();
IsMouseVisible = true;

Draw

GraphicsDevice.Clear(ClearOptions.DepthBuffer | ClearOptions.Target, Color.Black, 0, 0);
DrawModel();
spriteBatch.Begin();
DrawControls();
DrawFileBrowser();
spriteBatch.End();
base.Draw(gameTime);

DrawModel

GraphicsDevice.RasterizerState =
    new RasterizerState {
        CullMode = CullMode.None
    };
// [...]
// set up view and projection matrix
// [...]
GraphicsDevice.DrawUserIndexedPrimitives(
    PrimitiveType.TriangleList,
    vertices,
    0,
    vertices.Length,
    indices,
    0,
    indices.Length / 3);

What could be the problem in my rendering method? Do I have to somehow order my triangles from back to front? (no alpha-values are used) If yes, how can I order them?

Is it maybe some problem with the depth buffer? How can I fix it?

Any other ideas on how to fix the problem?

Edit

Shader code is basic:

float4x4 View;
float4x4 Projection;

void VS_Model(in  float4 inPosition            : POSITION,
              in  float4 inColor               : COLOR,
              out float4 outPosition           : POSITION,
              out float4 outColor              : TEXCOORD0) 
{
    outPosition = mul(mul(inPosition, View), Projection);
    outColor = inColor;
}

void PS_Model(in  float4 inColor               : TEXCOORD0,
              out float4 outColor              : COLOR)
{
    outColor = inColor;
}

technique Model
{
    pass
    {
        VertexShader = compile vs_3_0 VS_Model();
        PixelShader = compile ps_3_0 PS_Model();
    }
}
\$\endgroup\$
4
  • \$\begingroup\$ are you using the z buffer the wrong way round? \$\endgroup\$ Jun 7, 2011 at 9:50
  • \$\begingroup\$ I've added the shader code. nothing magic there. How can I specify how the z-buffer is used? \$\endgroup\$
    – Etan
    Jun 7, 2011 at 11:13
  • \$\begingroup\$ You want to enable Z-testing. Less or LessEqual. This should be done in your render setup code, not in the shader. \$\endgroup\$
    – void
    Jun 7, 2011 at 11:17
  • \$\begingroup\$ thanks, that did it! Could you rewrite this as an answer so it can be accepted? \$\endgroup\$
    – Etan
    Jun 7, 2011 at 12:01

1 Answer 1

2
\$\begingroup\$

You seems to render without depth test on. This might make triangles further away render on top of closer triangles since they might be rendered afterwards.

The solution is to turn on depth testing in your render setup and set the depth compare function to Less or LessEqual. Remember to turn on depth write too if you happen to have that turned off.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ GraphicsDevice.DepthStencilState = new DepthStencilState { DepthBufferEnable = true, DepthBufferFunction = CompareFunction.Less }; \$\endgroup\$
    – Etan
    Jun 7, 2011 at 12:38
  • \$\begingroup\$ Seems sane. I don't know XNA so my answer only contains platform agnostic info. \$\endgroup\$
    – void
    Jun 7, 2011 at 12:47

You must log in to answer this question.

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