Modifying depth offset creates texture artefacts

Hi all,

I’m trying to undo shadow acne this way:


This does remove the acne, but the problem is it introduces a new issue. There are artefacts that pop up at certain points in the texture of the model. Barring the use of a custom shader, is there a way to fix shadow acne without incurring these artefacts?

Thanks in advance.

Perhaps this old forum-post might be helpful?

1 Like

That’s interesting, but what commands are supposed to remove acne without leading to texture artefacts? Would it be these:

       extantState = self.worldLightNp.node().getInitialState()
       tempNP = NodePath(PandaNode("temporary NP"))
       # NB This next line!
       tempNP.setDepthWrite(True, 1)

Because the acne persists when using them.

In that case, it might help to see your light/shadow-related code: it may be that there’s something that in there that’s producing such persistent shadow-acne.

Just to be clear, the shadow acne is fixed as indicated in the original post:


However, this creates, artefacts that have nothing to do with the shadow, on the texture of the model.

The light/shadow code is just direct:

       plight = PointLight('plight')
       plight.setColor((0.5, 0.5, 0.5, 1))
       plight.setShadowCaster(True, 512,512)
       plnp = render.attachNewNode(plight)

That’s it.

You shouldn’t set the depth offset on everything. Set it only on the light initial state. Do it similar to the setDepthWrite code you’ve shown in the earlier comment, except with setDepthOffset.

1 Like

Without seeing these artefacts, I am somewhat guessing here, but my guess is that they’re not actually “texture” artefacts, as such. Rather, I would guess that you’re seeing depth-fighting, in which two or more surfaces are rendered at very similar depths. This causes one surface to render “in front” in some pixels and the other surface to render “in front” in other pixels, and which is rendered where to change as the view shifts.

But yes, as rdb says, setting a depth-offset on the entire scene is likely not an ideal solution. Hence my focussing on the shadow issue: I’d rather that be solved in a way that doesn’t then cause further problems.

This worked properly:

       extantState = self.pntNodeKontroller.node().getInitialState()
       tempNP = NodePath(PandaNode("temporary NP"))

Well, scouring the forum showed that what was being recommended to fix shadow acne was the command in my original post. I should say, that this is a rather obscure way of fixing the issue and since shadow acne is so common, it’d be nice if the manual were updated to reflect this solution.

Thank you so much to the both of you, but now, who should I credit with solving this? You both contributed to solving it…

This is the marked solution, but with full credit to @Thaumaturge and @rdb for solving it.

1 Like

I would say to mark your own most-recent post just above as the solution–after all, it is the one that demonstrates the fix, and thus seems likely to be the most useful to other devs who may come after.

That’s true, done.

1 Like