efel
efel

Reputation: 1106

opengl 3.3 z-fighting ortho 2d view

I'm having some issues with z fighting while drawing simple 2d textured quads using opengl. The symptoms are both objects moving at the same speed and one on top of another but periodically one can see through the other and vice versa - sort of like a "flickering". I assume this is indeed z fighting.

I have turned off Depth Testing and have the following as well:

gl.Disable(gl.DEPTH_TEST)
gl.DepthFunc(gl.LESS)
gl.Enable(gl.BLEND)
gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)

My view and ortho matrices are as follows:

I have tried to set the near and far distances much greater ( like range of 50000 but still no help)

Projection := mathgl.Ortho(0.0, float32(width), float32(height), 0.0, -5.0, 5.0)




View := mathgl.LookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)

The only difference with my opengl process is that instead of a drawelements call for each individual object, I package all vertices, uvs(sprite atlas), translation, rotation, etc in one big package sent to vertex shader.

Does anyone have remedies for 2d z fighting?

edit:

i'm adding some pictures to further describe the scenario:

img1

img2

These images are taken a few seconds apart from each other. They are simply texture moving from left to right. As they move; you see from the image, that one sprite over-lapse the other and vice versa back and forth etc very fast.

Also note that my images (sprites) are pngs that have a transparent background to them..

Upvotes: 0

Views: 1290

Answers (2)

Spektre
Spektre

Reputation: 51893

  1. This could be Z fighting

    the usual causes are:

    • fragments are at the same Z-coordinate or closer then accuracy of Z-coordinate
    • fragments are too far from perspective camera with perspective projection the more far you are from Z near the less accuracy

    some ways to fix this:

    • change size/position of overlapped surfaces slightly
    • use more bits for Z-Buffer (Depth)
    • use linear or logarithmic Z-buffer
    • increase Z-near or decrease Z-far or both for perspective projection you can combine more frustrums to get high definition Z range
    • sometimes helps to use glDepthFunc(GL_LEQUAL)
  2. This could be an issue with Blending.

    as you use Blending you need to render a bit differently. To render transparency correctly you must Z-sort the scene otherwise artifacts can occur. If you got too much dense geometry of transparent objects or objects near them (many polygon edges near). In addition Z-fighting creates a magnitude higher artifacts with blending.

    some ways to fix this:

    1. Z sorting can be partially done by multi pass rendering + Depth test + switching front face

      so first render all solids and then render Z-sorted transparent objects with front face set to the side not facing camera. Then render the same objects with front face set for side facing camera. You need to use depth test for this!!!. This way you do not need to sort all polygons of scene just the transparent objects. Results are not 100% correct for complex transparent geometries but the results are usually good enough (especially for dynamic scenes). This is how the output from this looks like

      example

      it is a glass cup a bit messed up visually by selected blending function for this case because darker pixels means 2 layers of glass on purpose it is not a bug. Therefore the opening looks like the front/back faces are swapped

    2. use less dense geometry for transparent objects

    3. get rid of Z-fighting issues

Upvotes: 1

Columbo
Columbo

Reputation: 6776

It definitely isn't depth fighting if you have depth testing disabled as shown in the code snippet.

"I package all vertices, uvs(sprite atlas), translation, rotation, etc in one big package sent to vertex shader." - You need to look into the order that you add your sprites. Perhaps it's inconsistent for some reason.

Upvotes: 2

Related Questions