Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where do pixel gaps come from in OpenGL?

Tags:

c++

opengl

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.

like image 840
obsilp Avatar asked Oct 10 '16 12:10

obsilp


People also ask

What is pixel transfer in OpenGL?

Pixel Transfer. A Pixel Transfer operation is the act of taking pixel data from an unformatted memory buffer and copying it in OpenGL-owned storage governed by an image format.

What is glreadpixels in OpenGL?

Transfers from OpenGL to the user: glReadPixels: Reads pixel data from the currently bound framebuffer object or the default framebuffer. If this is a color read, then it reads from the buffer designated by glReadBuffer. glGetTexImage: Reads all of the pixels from a mipmap level of the bound texture object.

What are the possible pixel formats for OpenGL?

The possible per-component formats use the enumerators for OpenGL types : However, there are packed arrangements of pixel data that are useful, where each component is packed into non-byte-length values. A common example is a 16-bit RGB color, where the red and blue components take up 5 bits and the green is 6.

What are pack and unpack operations in OpenGL?

Therefore, transfers to OpenGL memory are called unpack operations, and transfers from OpenGL memory are called pack operations. There are a number of OpenGL functions that initiate a pixel transfer operation. Pixel pack operations (ie: transfers from OpenGL to the user):


Video Answer


1 Answers

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.

like image 175
Nicol Bolas Avatar answered Sep 27 '22 21:09

Nicol Bolas