0
$\begingroup$

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

enter image description here

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.

$\endgroup$
1
  • $\begingroup$ I would test, when that problem shows up. Does this appear when only rendering the background? $\endgroup$
    – Thomas
    Commented Jul 7, 2023 at 7:22

1 Answer 1

0
$\begingroup$

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 enter image description here

I see that in your code:

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:

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.

$\endgroup$
1
  • $\begingroup$ 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. $\endgroup$
    – sunsigil
    Commented Jul 10, 2023 at 16:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.