XaiJu
mankrip
mankrip

patreon


Fixing Per-Span Z-Fighting

Vanilla Quake's software renderer does have a pretty bad case of Z-fighting, which only happens between different BSP entities (be it external BSP entities, such as item boxes, or entities built internally into the map, such as doors and moving platforms).

Vanilla Quake only performs worldspace geometry clipping between individual BSP entities and the world, while worldspace geometry intersections between multiple BSP entities are ignored by the renderer. This makes the screenspace per-span depth checks to fail, with the spans containing the nearest on-screen edges obscuring the other spans all the way to the end of the object's on-screen projection.

Putting it simple, take a look at this WinQuake screenshot: The lines where the megahealth obscures the ammo are the lines where the obscuring megahealth's polygon have an edge closer to the screen, while the lines where the ammo obscures the megahealth are the lines where the obscuring ammo's polygon have an edge closer to the screen.

The simplest solution is to use per-pixel depth checks, which is generally slower than worldspace geometry clipping. Also, per-pixel depth checks are prone to per-pixel Z-fighting between polygons sharing the same plane (see the last pic); this is something that always happens in hardware-accelerated 3D games, and hardware-accelerated Quake ports usually employs several different methods to try to mitigate that.

The solution I'm working on is still not ideal, because of its impact on performance. The ideal solution should be to perform geometry clipping between different BSP entities, but this would be very difficult to do on rotated entities (I still haven't figured out how to cast raytraced shadows between multiple rotated BSP entities). I'll likely end up implementing geometry clipping between non-rotated BSP entities only, and use depth checks on rotated BSP entities.

Fixing Per-Span Z-Fighting Fixing Per-Span Z-Fighting Fixing Per-Span Z-Fighting

Comments

Stereo conversion apps for videos works on a different concept, which is essentially post-processed. In Retroquad, Z-ordering of entities can help to speed up rendering a little, but won't make difference on these glitches. Worldspace cross-entity geometry clipping is really the best solution, because it should be faster than per-pixel depth checks in nearly all cases.

mankrip

Hi Manoel, I’m not sure if this is relevant, but quite a few stereo conversion apps use z-ordering lists to fix perspective and z fighting issues, maybe something to consider?

Ironhell


More Creators