14

The problem that I have is, that there are some pixles in my rendered scene that seem to be missing/invisible and therefore have the same color as my clear color. Interestingly, this only happens if MSAA is turned off.

Blue pixel are the problematic ones

My first thought was, that it could have something to do with the fact, that all the triangles are overlapping and somehow distorted by the projection matrix but these artifacts only seem to occur on lines rather than edges.

Wireframe of the scene above (leaking pixels are white)

I read about just applying a scale of 1.00001 to everything in another question but that seems like a cheap hack to me that could cause other problems. Although these artifacts seem to be reduced when using hardware multisampling, I want to know if there is any other way to solve this.

Edit:

A way to solve this by Nicol Bolas:

OpenGL (and all other hardware rasterizers) only guarantees gapless rendering of the edge between two triangles if the edges exactly match. And that means you can't just have one triangle next to the edge of another. The two triangles must have identical vertices on the shared edge between them.

So if you have a long triangle next to a short triangle, what you have to do is split the long triangle into several triangles, so that the shared portion of the edge is properly shared between two triangles.

As stated, a possible solution is to split the big triangles into small ones to ensure that all overlapping vertecies are identical (i.e. abolishing the greedy meshing). But in my case I want to keep the greedy meshing due to performance aspects.

Community
  • 1
  • 1
obsilp
  • 296
  • 2
  • 7
  • 16 bit floats - gotta hate them – dtech Oct 10 '16 at 12:14
  • Being low precision machines, you really don't want to have your geometry laid edge to edge (as you would want it in practice or a CAD drawing), because approximation errors eventually manifest as graphical artifacts. Typically, you'd have a single plane for a floor, and it will slightly go into the walls and so on. – dtech Oct 10 '16 at 13:17
  • You have T-junctions. This is an exact duplicate of http://stackoverflow.com/questions/18523231/opengl-shimmering-pixels-artifact -- posting it because somebody reopened (why?) – Yakov Galka Oct 10 '16 at 14:47
  • The answer to the linked question isn't what I am look for. The problem there seems to have to do with the applied shader but not the geometry itself. – obsilp Oct 10 '16 at 15:16
  • @DieEidechse12: you are mistaken. Read carefully: the OP *thinks* it's with his fragment shader, but in fact the proposed solution is to adjust the geometry in the vertex shader to hide the artifact. This way you don't need to abolish the greedy meshing -- unlike what Nicol suggests. – Yakov Galka Oct 10 '16 at 16:39

3 Answers3

13

OpenGL (and all other hardware rasterizers) only guarantees gapless rendering of the edge between two triangles if the edges exactly match. And that means you can't just have one triangle next to the edge of another. The two triangles must have identical vertices on the shared edge between them.

So if you have a long triangle next to a short triangle, what you have to do is split the long triangle into several triangles, so that the shared portion of the edge is properly shared between two triangles.

Since you seem to be building a world made of cubes, this should be fairly easy for you.

The other thing you have to do is make certain that the two shared vertices between the two triangles are binary identical. The gl_Position output from the vertex shader needs to be the exact same value. So if you're computing the position of the cube's vertices in the VS, you need to do that in a way that will guarantee binary identical results.

But in my case I want to keep the greedy meshing due to performance aspects.

Then you need to decide which is more important: performance, or correctness. Because there's no way to force the rasterizer allow such edges to be gapless. It's a matter of floating-point precision and such, which will always be different on different hardware.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • Disabling my greedy meshing fixed it (as you suggested with splitting big triangles into small ones), but thats not how I want to solve it. I edited my question, is there another way without abandoning the vertex merging? – obsilp Oct 10 '16 at 15:21
  • @DieEidechse12: Edited. – Nicol Bolas Oct 10 '16 at 16:18
  • thank you. do you have an idea how modern game engines tackle this problem? – obsilp Oct 10 '16 at 16:23
  • @DieEidechse12: Most game engines render meshes that are built by the maker of the game. If those meshes do not properly connect, then garbage in, garbage out. It's up to the people creating the meshes to make sure that they work. – Nicol Bolas Oct 10 '16 at 16:52
3

It's called "stitching". The rasterizer isn't matching the triangles exactly and some pixels are missing. Others have explained how to set up the triangles so OpenGL knows they share an edge. However as your model-building logic gets more and more complicated sometimes stitching is hard to avoid. The workaround is to clear to black or dark grey, and the stitches are then nearly invisible.

Alex Jasmin
  • 39,094
  • 7
  • 77
  • 67
Malcolm McLean
  • 6,258
  • 1
  • 17
  • 18
1

This is due to there being an issue of you having two polygons touching on the edges, and but being there would be some small error. (most likely round-off error in the floating point units being used to estimate the edge) There should theoretically also be times that they are overlapping their edges, but this would be far less noticeable. Setting a really small magnification factor, or going and just moving the polygons themselves a fraction towards each-other should resolve it. The reason it only occurs when MSAA is turned off as generally it would help prevent this type of issue. (This is due to it running all of the calculations at a higher resolution, but then downscaling everything to a lower resolution so it won't be as noticeable. The issue actually does still occur, but because of the downscaling, the missing pixels will disappear as they are blended into the surrounding pixels. )

Lilith Daemon
  • 1,473
  • 1
  • 19
  • 37