0
\$\begingroup\$

I'm beginning with the 3D rendering in Monogame and i'm facing not a real issue because i already find a way to bypass it but more of a question. I'm rendering a simple cube with 8 vertices like that:

_vertices[0] = new VertexPositionColor(new Vector3(-1, 1, -1), Color.Red);
_vertices[1] = new VertexPositionColor(new Vector3(-1, -1, -1), Color.Red);
_vertices[2] = new VertexPositionColor(new Vector3(1, -1, -1), Color.Red);
_vertices[3] = new VertexPositionColor(new Vector3(1, 1, -1), Color.Red);
_vertices[4] = new VertexPositionColor(new Vector3(-1, 1, 1), Color.Green);
_vertices[5] = new VertexPositionColor(new Vector3(-1, -1, 1), Color.Green);
_vertices[6] = new VertexPositionColor(new Vector3(1, -1, 1), Color.Green);
_vertices[7] = new VertexPositionColor(new Vector3(1, 1, 1), Color.Green);

But i'm also using an index buffer to draw each triangle for each faces and this is where my issue is. When i'm doing the following:

_indices = new int[] // 6 faces, each containing 2 triangles of 3 vertices
{
           0, 1, 2, 0, 2, 3, // front
           3, 2, 6, 3, 6, 7,
           4, 0, 3, 4, 3, 7,
           1, 5, 6, 1, 6, 2,
           4, 5, 1, 4, 1, 0,
           4, 7, 6, 4, 6, 5 // back
};

The render is perfect and every edge is rendered as you can see on this gif:

https://imgur.com/h7Kn4uH

But when i changed the order inside the index buffer of the back part, like the following:

_indices = new int[] // 6 faces, each containing 2 triangles of 3 vertices
{
           0, 1, 2, 0, 2, 3, // front
           3, 2, 6, 3, 6, 7,
           4, 0, 3, 4, 3, 7,
           1, 5, 6, 1, 6, 2,
           4, 5, 1, 4, 1, 0,
           4, 6, 7, 4, 5, 6 // back, update is here
};

The only thing that was updated is the order of the last column and the result is the following:

https://imgur.com/aCR3QXc

Why does the render is not done on the second case when the only change made is the order of two vertices ? I know that I can do a rasterize state to render each side of a triangle but one solution is working without it, so i'd like to avoid using it.

Thanks!

\$\endgroup\$
  • \$\begingroup\$ Your second example actually looks correct, given that one of your faces now has bad data. This would be expected behaviour with backface culling enabled; i.e triangles facing away from the camera are not rendered. So if your expected behaviour is to be able to see the inside of your cube, then you'll need to disable backface culling. As you do indeed note this in your question, you seem to actually understand what's happening here, and I'm not certain what your problem is. \$\endgroup\$ – Maximus Minimus Mar 10 '19 at 12:59
1
\$\begingroup\$

When you render a closed, opaque object like your cube, from any particular viewpoint, only about half of the triangles contribute to the final image: the ones on the side facing the camera. The ones on the far side would occupy the same silhouette on-screen, but would be hidden behind the front-facing triangles.

So, we can cut our rendering workload in half by not even trying to render those "back faces" in the first place, knowing they'll end up hidden. This is an optimization called "backface culling"

To figure out if a particular triangle is a back face, the GPU uses a neat trick: when we wall thorough the projected vertices of a non-degenerate triangle in the order they were given, the path we follow will turn either clockwise or counterclockwise in the plane of the screen. This is called the "winding" of the triangle. When we look at a triangle from its "back" side, the winding order flips, from clockwise to counter-clockwise or vice versa.

By setting up our input so that all the triangles we pass in are wound clockwise when viewed from their outside face, we can tell the GPU to draw only clockwise-wound faces and skip any thar are wound counter-clockwise, since the latter must be back faces.

When you exchange the order of two vertices in a triangle, you also change its winding order. So in your example, you told the GPU that the last two triangles in your buffer should only be drawn when viewed from the other side, so it culls them as back faces when looking at them directly.

The fact that these two triangles on the green face of the cube are not being drawn lets you see into the cube and notice that the other faces are also not being drawn — and this is correct, because we really are looking at them from behind. Normally the green face would be drawn in front, hiding the back sides of the other faces from view, so it would be safe to skip drawing those faces from this angle.

|improve this answer|||||
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for?Browse other questions tagged or ask your own question.