<p>I actually can't get enough information from the description and the variable names are... confusing to me. Also, I can't recall formulae similar to those in your question, so I can only make a guess, as I think it actually looks like ray-intersection op in ray tracing. I am not sure whether it would be the case of yours.</p>
<p>Could it be something wrong with round off error? I know normally if it is so, the artifacts can be seen almost everywhere, but I do remember to have seen some rendering results partially spattered with round-off artifacts. It is basically like the following figures. I notice that there seems to be regular stripes in the artifacts, which looks familiar to me, as I've encountered similar artifacts in my own renderer:</p>
<div class="s-table-container">
<table class="s-table">
<thead>
<tr>
<th>Without roundoff protection</th>
<th>With roundoff protection</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://i.sstatic.net/roC9G.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/roC9G.png" alt="enter image description here" /></a></td>
<td><a href="https://i.sstatic.net/1agt6.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/1agt6.png" alt="enter image description here" /></a></td>
</tr>
</tbody>
</table>
</div>
<p>I see that in your code:</p>
<pre class="lang-cpp prettyprint-override"><code>if(z &gt; buf_z)
{
    ...
    depthbuf[y * frame-&gt;width + x] = z;
}
</code></pre>
<p>which seems to lack a bound check (necessary?) and a round-off error protection like this:</p>
<pre class="lang-python prettyprint-override"><code>for mesh_idx in range(start_id, tri_num + start_id):
    p1 = self.prims[mesh_idx, 0]
    v1 = self.precom_vec[mesh_idx, 0]
    v2 = self.precom_vec[mesh_idx, 1]
    mat = ti.Matrix.cols([v1, v2, -ray]).inverse()
    u, v, t = mat @ (start_p - p1)
    if u &gt;= 0 and v &gt;= 0 and u + v &lt;= 1.0:
        if t &gt; 1e-4 and t &lt; min_depth:      # round-off error protection, a small value like 1e-4 here
            min_depth = t
</code></pre>
<p>For the code above, if I replace 1e-4 with 0 then there will be artifacts. So I think maybe you can try adding round-off error protection in your code.</p>

CC BY-SA 4.0
2023-07-10T16:11:46.737Z
My variable names are admittedly bad and I forgot to include all checks in the code I posted. Sorry. The code my function is from takes vertex data for a tri, loops over the pixels in its AABB, skips any pixels outside the tri or the view (by checking a mix of transformed vertex coords and barycentric coords), recalculates perspective correct barycentric coords for any pixels inside the tri, and shades those. So all necessary bounds checking should have been done by the time I get to that block where I compare a pixel's screenspace z-value to the screenspace z-values in the buffer.
sunsigil
CC BY-SA 4.0
2023-07-09T13:20:37.503Z
2023-07-09T13:20:37.503Z
Enigmatisms
<p>I am writing a polygon rasterization renderer. Some meshes render flawlessly, but some produce strange artefacts in the depth buffer. These artefacts do not just appear when I save the depth buffer for inspection but are clearly part of the buffer itself during runtime, as you can see it affecting the result of rendering very clearly. Does this look like some familiar problem? Do you have advice on how to diagnose this issue if not? I have attached two images, one of the render result and one of the saved depth buffer. I have also included a snippet of my code that handles depth testing:
<a href="https://i.sstatic.net/URthK.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/URthK.png" alt="enter image description here" /></a></p>
<p><a href="https://i.sstatic.net/wlf5B.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/wlf5B.png" alt="enter image description here" /></a></p>
<pre><code>if(mat_min(zs) &lt; 0.0 || mat_max(zs) &gt; 1.0)
{ return; }
// Exit if vertex is outside of depth range ^
...
double zpc_inv = bary.data[0] / zcs.data[0] + bary.data[1] / zcs.data[1] + bary.data[2] / zcs.data[2];
double zpc = 1.0 / zpc_inv;
double upc = bary.data[1] * zpc / zcs.data[1];
double vpc = bary.data[2] * zpc / zcs.data[2];
double wpc = 1.0 - upc - vpc;
bary = mat_row(3, wpc, upc, vpc);
// Calculate new perspective-correct barycentric coordinates ^
double z = mat_lincomb(zs, bary).data[0];
double buf_z = depthbuf[y * frame-&gt;width + x];
// Calculate depth from said coords ^
if(z &gt; buf_z)
{
    ...
    depthbuf[y * frame-&gt;width + x] = z;
}
// Draw if depth is suitable ^
</code></pre>
<p>EDIT: Based on an answer given here, I decided to do some experimentation with bounds. The artefacting is somehow caused by pixels which should have invalid bounds passing bounds checks. By changins some <code>&lt;=</code> and <code>&gt;=</code> into <code>&lt;</code> and <code>&gt;</code>, I tightened the bounds on what is considered a &quot;valid&quot; barycentric coord for shading and it helped significantly but did not eliminate the problem entirely.</p>

CC BY-SA 4.0
2023-07-07T07:22:50.827Z
I would test, when that problem shows up. Does this appear when only rendering the background?
Thomas
<3d><rasterizer><depth-map><bitmap-graphics>
Patchy patterned artefacting in depth buffer
sunsigil
# Patchy patterned artefacting in depth buffer

(Asked by: username_0 on 2023-07-06)

I am writing a polygon rasterization renderer. Some meshes render flawlessly, but some produce strange artefacts in the depth buffer. These artefacts do not just appear when I save the depth buffer for inspection but are clearly part of the buffer itself during runtime, as you can see it affecting the result of rendering very clearly. Does this look like some familiar problem? Do you have advice on how to diagnose this issue if not? I have attached two images, one of the render result and one of the saved depth buffer. I have also included a snippet of my code that handles depth testing:
[![enter image description here](https://i.sstatic.net/URthK.png)](https://i.sstatic.net/URthK.png)

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

```
if(mat_min(zs) < 0.0 || mat_max(zs) > 1.0)
{ return; }
// Exit if vertex is outside of depth range ^
...
double zpc_inv = bary.data[0] / zcs.data[0] + bary.data[1] / zcs.data[1] + bary.data[2] / zcs.data[2];
double zpc = 1.0 / zpc_inv;
double upc = bary.data[1] * zpc / zcs.data[1];
double vpc = bary.data[2] * zpc / zcs.data[2];
double wpc = 1.0 - upc - vpc;
bary = mat_row(3, wpc, upc, vpc);
// Calculate new perspective-correct barycentric coordinates ^
double z = mat_lincomb(zs, bary).data[0];
double buf_z = depthbuf[y * frame->width + x];
// Calculate depth from said coords ^
if(z > buf_z)
{
    ...
    depthbuf[y * frame->width + x] = z;
}
// Draw if depth is suitable ^

```

EDIT: Based on an answer given here, I decided to do some experimentation with bounds. The artefacting is somehow caused by pixels which should have invalid bounds passing bounds checks. By changins some `<=` and `>=` into `<` and `>`, I tightened the bounds on what is considered a "valid" barycentric coord for shading and it helped significantly but did not eliminate the problem entirely.

**Tags:** 3d, rasterizer, depth-map, bitmap-graphics

> **Comments:**
> **username_1**: I would test, when that problem shows up. Does this appear when only rendering the background?  

---

## 1 answers

### Answer by username_2 on 2023-07-09. Score: 0 | Accepted answer

I actually can't get enough information from the description and the variable names are... confusing to me. Also, I can't recall formulae similar to those in your question, so I can only make a guess, as I think it actually looks like ray-intersection op in ray tracing. I am not sure whether it would be the case of yours.

Could it be something wrong with round off error? I know normally if it is so, the artifacts can be seen almost everywhere, but I do remember to have seen some rendering results partially spattered with round-off artifacts. It is basically like the following figures. I notice that there seems to be regular stripes in the artifacts, which looks familiar to me, as I've encountered similar artifacts in my own renderer:

| Without roundoff protection | With roundoff protection |
| --- | --- |
| [enter image description here](https://i.sstatic.net/roC9G.png) | [enter image description here](https://i.sstatic.net/1agt6.png) |

I see that in your code:

```cpp
if(z > buf_z)
{
    ...
    depthbuf[y * frame->width + x] = z;
}

```

which seems to lack a bound check (necessary?) and a round-off error protection like this:

```python
for mesh_idx in range(start_id, tri_num + start_id):
    p1 = self.prims[mesh_idx, 0]
    v1 = self.precom_vec[mesh_idx, 0]
    v2 = self.precom_vec[mesh_idx, 1]
    mat = ti.Matrix.cols([v1, v2, -ray]).inverse()
    u, v, t = mat @ (start_p - p1)
    if u >= 0 and v >= 0 and u + v <= 1.0:
        if t > 1e-4 and t < min_depth:      # round-off error protection, a small value like 1e-4 here
            min_depth = t

```

For the code above, if I replace 1e-4 with 0 then there will be artifacts. So I think maybe you can try adding round-off error protection in your code.

> **Comments:**
> **username_0**: My variable names are admittedly bad and I forgot to include all checks in the code I posted. Sorry. The code my function is from takes vertex data for a tri, loops over the pixels in its AABB, skips any pixels outside the tri or the view (by checking a mix of transformed vertex coords and barycentric coords), recalculates perspective correct barycentric coords for any pixels inside the tri, and shades those. So all necessary bounds checking should have been done by the time I get to that block where I compare a pixel's screenspace z-value to the screenspace z-values in the buffer.  

---

