<p>If the surfaces are exactly co-planer, your fate is up to the FPU gods; you'll more than likely have Z-fighting. If the triangles are <em>identical</em> and you do the <em>exact</em> same math to each, you <em>will</em> end up with the same Z-values for both. But again, this will only happen if your math operations are identical for both. (Since, in general, FPU operations are not commutative)</p>

<p>One possible solution is to not use the Z-buffer at all. Rather you can use the <a href="https://en.wikipedia.org/wiki/Painter%27s_algorithm">Painter's Algorithm</a>. Granted, this comes with all the problems of the painters algorithm as well. But, it would solve the Z-fighting.</p>

<p>In your example case of Screen Space Decals (SSDs), the common solution is to use an offset, aka a simple thin cube. See Warhammer 40k's <a href="http://www.slideshare.net/blindrenderer/screen-space-decals-in-warhammer-40000-space-marine-14699854">presentation</a> about SSDs for reference. Or Bart Wronski's <a href="http://bartwronski.com/2015/03/12/fixing-screen-space-deferred-decals/">post</a> which addresses some other issues with decals, but also links to a few other presentations about SSDs</p>

CC BY-SA 3.0
2015-08-08T17:51:51.780Z
Re-rendering the same geometry with the same transforms does reliably generate the same depth values every time. (I.e. it's not a *might*, it's a *will*). That's why multi-pass forward lighting works, for instance.
Nathan Reed
CC BY-SA 3.0
2015-08-10T11:11:30.830Z
To get that functionality you need to use the invariant qualifier in glsl: https://www.opengl.org/wiki/Type_Qualifier_%28GLSL%29#Invariance_qualifiers
ashleysmithgpu
CC BY-SA 3.0
2015-08-10T11:13:07.507Z
Note that identical shader expressions (and inputs, obviously) when evaluating vertex positions may not be enough to get identical results as some optimisations may depend on the rest of the shader. 

GLSL has the "invariant" keyword to declare shader outputs that must be evaluated identically in different shaders.
Firadeoclus
CC BY-SA 3.0
2015-08-07T20:33:07.803Z
2015-08-09T18:44:10.750Z
2015-08-09T18:44:10.750Z
RichieSams
<p>Here's how I've solved this in the past:</p>

<ol>
<li>Draw the first object (the one that should appear behind the other object) by depth testing but <strong>not</strong> depth writing</li>
<li>Draw the second object by depth testing and depth writing.  This won't cause z-fighting since we didn't write any depth in step 1.  </li>
<li>Draw the first object by only writing to the depth buffer and <strong>not</strong> to the color buffer. This makes sure the depth buffer is up to date for any pixels that are covered by object 1 but not by object 2.</li>
</ol>

<p>Note, the objects need to be drawn consecutively for this to work.</p>

CC BY-SA 3.0
2016-05-19T17:41:41.510Z
2016-05-20T13:51:31.210Z
2016-05-20T13:51:31.210Z
default
<p>Depending on your renderer you could make the surfaces more "fuzzy" applying a miniscule offset in multisampling depth using a noise like algorithm. This should result in a sort of blending effect for surfaces in close depth proximity. For what I know setting per-sample depth in fragment shader is quite recent in OpenGL and then only as an extension.</p>

<p>OpenGL has the PolygonOffset but requires knowing in advance you are about to render something coplanar. While not feasible for surfaces within a single model it could work nicely for example when rendering a road overlaid on a piece of land.</p>

CC BY-SA 3.0
2017-09-13T19:23:35.453Z
2017-09-13T19:23:35.453Z
Andreas
<p>When rendering two overlapping co-planar surfaces, a common issue is "z-fighting", where the renderer can't decide which of the two surfaces is closer to the camera, giving visual artifacts in the area of overlap.</p>

<p>The standard solution to this is to give the surfaces a slight offset when designing the model.  Is there any other solution?</p>

CC BY-SA 3.0
2015-08-07T08:12:14.850Z
You could checkout logarithmic depth buffers. There's an article on [gamasutra](http://www.gamasutra.com/blogs/BranoKemen/20090812/85207/Logarithmic_Depth_Buffer.php)
Soapy
CC BY-SA 3.0
2015-08-07T12:55:57.560Z
When you say "co-planar" do you mean "nearly"  or "exactly" co-planar and if the latter, are those surfaces ever identical surfaces/triangles? The rendering hardware should be deterministic (assuming you aren't submitting in random order) for the last case and not have fighting.  
If it's a case of non-identical surfaces but exactly co-planar, could you update the model to split surfaces into overlapping and non-overlapping portions?
Simon F
CC BY-SA 3.0
2015-08-07T18:38:11.437Z
@SimonF, by "co-planar" I mean "exactly co-planar".  Soapy's solution only works in the "nearly co-planar" case.
Mark
CC BY-SA 3.0
2015-08-07T20:28:32.447Z
Could you give an example of your surfaces? The only thing I can think of off the top of my head is duplicate triangles as @SimonF mentioned.
RichieSams
CC BY-SA 3.0
2015-08-07T23:15:29.387Z
@RichieSams the most common case that I can think of is decals, where you don't need exactly duplicate triangles.
rys
CC BY-SA 4.0
2024-05-01T14:12:41.430Z
Note: The above mentioned article link broke when Gamasutra rebranded & the [replacement version on GameDeveloper.com](https://www.gamedeveloper.com/programming/logarithmic-depth-buffer) lacks the images / illustrations, but you can still find a [near complete version of the content via Wayback](https://web.archive.org/web/20120512095233/http://www.gamasutra.com/blogs/BranoKemen/20090812/85207/Logarithmic_Depth_Buffer.php)
Pikalek
<rendering>
Avoiding z-fighting with coincident surfaces
Mark
# Avoiding z-fighting with coincident surfaces

(Asked by: username_0 on 2015-08-07)

When rendering two overlapping co-planar surfaces, a common issue is "z-fighting", where the renderer can't decide which of the two surfaces is closer to the camera, giving visual artifacts in the area of overlap.

The standard solution to this is to give the surfaces a slight offset when designing the model. Is there any other solution?

**Tags:** rendering

> **Comments:**
> **username_1**: You could checkout logarithmic depth buffers. There's an article on [gamasutra](http://www.gamasutra.com/blogs/BranoKemen/20090812/85207/Logarithmic_Depth_Buffer.php)  
> **username_2**: When you say "co-planar" do you mean "nearly"  or "exactly" co-planar and if the latter, are those surfaces ever identical surfaces/triangles? The rendering hardware should be deterministic (assuming you aren't submitting in random order) for the last case and not have fighting.   If it's a case of non-identical surfaces but exactly co-planar, could you update the model to split surfaces into overlapping and non-overlapping portions?  
> **username_0**: @username_2, by "co-planar" I mean "exactly co-planar".  username_1's solution only works in the "nearly co-planar" case.  
> **username_3**: Could you give an example of your surfaces? The only thing I can think of off the top of my head is duplicate triangles as @username_2 mentioned.  
> **username_4**: @username_3 the most common case that I can think of is decals, where you don't need exactly duplicate triangles.  
> **username_5**: Note: The above mentioned article link broke when Gamasutra rebranded & the [replacement version on GameDeveloper.com](https://www.gamedeveloper.com/programming/logarithmic-depth-buffer) lacks the images / illustrations, but you can still find a [near complete version of the content via Wayback](https://web.archive.org/web/20120512095233/http://www.gamasutra.com/blogs/BranoKemen/20090812/85207/Logarithmic_Depth_Buffer.php)  

---

## 3 answers

### Answer by username_3 on 2015-08-07. Score: 11

If the surfaces are exactly co-planer, your fate is up to the FPU gods; you'll more than likely have Z-fighting. If the triangles are *identical* and you do the *exact* same math to each, you *will* end up with the same Z-values for both. But again, this will only happen if your math operations are identical for both. (Since, in general, FPU operations are not commutative)

One possible solution is to not use the Z-buffer at all. Rather you can use the [Painter's Algorithm](https://en.wikipedia.org/wiki/Painter%27s_algorithm). Granted, this comes with all the problems of the painters algorithm as well. But, it would solve the Z-fighting.

In your example case of Screen Space Decals (SSDs), the common solution is to use an offset, aka a simple thin cube. See Warhammer 40k's [presentation](http://www.slideshare.net/blindrenderer/screen-space-decals-in-warhammer-40000-space-marine-14699854) about SSDs for reference. Or Bart Wronski's [post](http://bartwronski.com/2015/03/12/fixing-screen-space-deferred-decals/) which addresses some other issues with decals, but also links to a few other presentations about SSDs

> **Comments:**
> **username_6**: Re-rendering the same geometry with the same transforms does reliably generate the same depth values every time. (I.e. it's not a *might*, it's a *will*). That's why multi-pass forward lighting works, for instance.  
> **username_7**: To get that functionality you need to use the invariant qualifier in glsl: https://www.opengl.org/wiki/Type_Qualifier_%28GLSL%29#Invariance_qualifiers  
> **username_8**: Note that identical shader expressions (and inputs, obviously) when evaluating vertex positions may not be enough to get identical results as some optimisations may depend on the rest of the shader.   GLSL has the "invariant" keyword to declare shader outputs that must be evaluated identically in different shaders.  

---

### Answer by username_9 on 2016-05-19. Score: 4

Here's how I've solved this in the past:

1. Draw the first object (the one that should appear behind the other object) by depth testing but **not** depth writing
2. Draw the second object by depth testing and depth writing. This won't cause z-fighting since we didn't write any depth in step 1.
3. Draw the first object by only writing to the depth buffer and **not** to the color buffer. This makes sure the depth buffer is up to date for any pixels that are covered by object 1 but not by object 2.

Note, the objects need to be drawn consecutively for this to work.


---

### Answer by username_10 on 2017-09-13. Score: 0

Depending on your renderer you could make the surfaces more "fuzzy" applying a miniscule offset in multisampling depth using a noise like algorithm. This should result in a sort of blending effect for surfaces in close depth proximity. For what I know setting per-sample depth in fragment shader is quite recent in OpenGL and then only as an extension.

OpenGL has the PolygonOffset but requires knowing in advance you are about to render something coplanar. While not feasible for surfaces within a single model it could work nicely for example when rendering a road overlaid on a piece of land.


---

