<p>It sounds like this code is using the stencil buffer to mask off the locations to draw the line. This isn't a &quot;typical&quot; decal approach. Normally the decal is draw directly into the scene and &quot;depth bias&quot; is turned on for the graphics state (OpenGL) or the graphics pipeline (Vulkan). Then turned off when done, again for OpenGL.</p>
<p>A solution that doesn't change the current rendering approach (which i guessed at) is to use a depth buffer when rendering the terrain. Then pass that depth buffer as an input to your decal shader, read the depth buffer and compare it to the depth of your current fragment. Then discard the fragment if the depth test fails. Basically, it is doing depth buffering by hand. It isn't to hard to set up and there are lots of tutorials out there to help get you going.</p>
<p>It also might be possible to just change the stencil buffer based on depth values this would be dependent on how the stencil is being generated. If it is regenerated each frame this could be a quick and easy solution.</p>
<p>On the other hand, if you are drawing lines or polygons directly, then you really should look into using depth bias settings. Assuming you are using OpenGL this is turned on before rendering the decal then turned off after rendering it. The hardware then computes an offset depending on how far the camera is away from the object up to some limit (which is also programable). This approach would allow the depth testing to be left on, it is view independent so it works from any direction, and it would allow the decal to be textured.</p>
<p>Also: The issue described here isn't really z fighting. Z fighting usually occurs when two fragments are being rendered to the same location and quantization causes the fragments to &quot;fight&quot; for visibility. As the camera moves one of the two fragments wins the &quot;fight&quot;, but the winner keeps changing depending how much floating point error there is.</p>

CC BY-SA 4.0
2021-02-03T14:37:31.590Z
2021-02-03T14:50:04.190Z
2021-02-03T14:50:04.190Z
pmw1234
<p>I need to create a decaling into a surface like a mesh, and to avoid Z-fighting I've been using Stencil Buffer to Turn-off depth test and make the decaling over the surface the Stencil Op permits. In fact that decaling fails when we turn the camera in a such way that the viewer has more than one surface point &quot;competing&quot; for the same pixel. This happens when the surface isn't a plane, in our example we have a mesh representing a terrain. The problem is that we turn-off the depth test and the decaling object is always visible, even when we have a surface point closer to the camera. Is there someone here that had the same problem ? Do I have to quit stencil solution to avoid Z-fighting ?</p>
<p>Without problem: <a href="https://i.sstatic.net/3cGwK.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/3cGwK.png" alt="enter image description here" /></a></p>
<p>The Problem: <a href="https://i.sstatic.net/zhVEv.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/zhVEv.png" alt="enter image description here" /></a></p>

CC BY-SA 4.0
2021-02-02T21:06:32.000Z
Why not use hardware offset capabilities when setting up a sampler?
pmw1234
CC BY-SA 4.0
2021-02-02T21:35:47.137Z
I can't see your point. Could you explain in details ?
lealericsson
<opengl><rendering><z-buffer><stencil-buffer>
Problem using Decaling with Stencil to avoid Z-fighting
lealericsson
# Problem using Decaling with Stencil to avoid Z-fighting

(Asked by: username_0 on 2021-02-02)

I need to create a decaling into a surface like a mesh, and to avoid Z-fighting I've been using Stencil Buffer to Turn-off depth test and make the decaling over the surface the Stencil Op permits. In fact that decaling fails when we turn the camera in a such way that the viewer has more than one surface point "competing" for the same pixel. This happens when the surface isn't a plane, in our example we have a mesh representing a terrain. The problem is that we turn-off the depth test and the decaling object is always visible, even when we have a surface point closer to the camera. Is there someone here that had the same problem ? Do I have to quit stencil solution to avoid Z-fighting ?

Without problem: [![enter image description here](https://i.sstatic.net/3cGwK.png)](https://i.sstatic.net/3cGwK.png)

The Problem: [![enter image description here](https://i.sstatic.net/zhVEv.png)](https://i.sstatic.net/zhVEv.png)

**Tags:** opengl, rendering, z-buffer, stencil-buffer

> **Comments:**
> **username_1**: Why not use hardware offset capabilities when setting up a sampler?  
> **username_0**: I can't see your point. Could you explain in details ?  

---

## 1 answers

### Answer by username_1 on 2021-02-03. Score: 1

It sounds like this code is using the stencil buffer to mask off the locations to draw the line. This isn't a "typical" decal approach. Normally the decal is draw directly into the scene and "depth bias" is turned on for the graphics state (OpenGL) or the graphics pipeline (Vulkan). Then turned off when done, again for OpenGL.

A solution that doesn't change the current rendering approach (which i guessed at) is to use a depth buffer when rendering the terrain. Then pass that depth buffer as an input to your decal shader, read the depth buffer and compare it to the depth of your current fragment. Then discard the fragment if the depth test fails. Basically, it is doing depth buffering by hand. It isn't to hard to set up and there are lots of tutorials out there to help get you going.

It also might be possible to just change the stencil buffer based on depth values this would be dependent on how the stencil is being generated. If it is regenerated each frame this could be a quick and easy solution.

On the other hand, if you are drawing lines or polygons directly, then you really should look into using depth bias settings. Assuming you are using OpenGL this is turned on before rendering the decal then turned off after rendering it. The hardware then computes an offset depending on how far the camera is away from the object up to some limit (which is also programable). This approach would allow the depth testing to be left on, it is view independent so it works from any direction, and it would allow the decal to be textured.

Also: The issue described here isn't really z fighting. Z fighting usually occurs when two fragments are being rendered to the same location and quantization causes the fragments to "fight" for visibility. As the camera moves one of the two fragments wins the "fight", but the winner keeps changing depending how much floating point error there is.


---

