Mesh z-fighting to itself

Hi all.
I have a mesh which deformed in shader by Sine function to simulate waves. So, I got an artifacts of self z-fighting.

Maybe I should in the shader (somehow) calculate depth for each modified vertex?

Wow that looks good. I dont know how to fix it though. sorry…

Looks like I found roots of the problem(

And what was it?

I had a similar problem with a landscape mesh that was z-fighting with itself. The solution was to adjust the Depth Write setting to “Force Enable”.

This is not called z-fighting. z-fighting is about two or more surfaces that are located at the same depth value and when the GPU looks up the depth buffer you get random results (some pass some fail) which results in the typical mixed meshes patterns.

The issue here is that a transparent shader was used with a mesh that has self overlap. This generally does not work very well. Transparent / alpha blended meshes need to be rendered from back to front in order to appear correctly. Things behind transparent triangles need to be already in the frame buffer in order to mix correctly.

A single mesh has the issue that the triangles within the same mesh are rendered in the order they appear in the index buffer. This order within the same mesh does never change. As a result if the mesh has self overlapping areas, depending on the view direction you get various artifacts. If a normal transparent shader is used (depth test enabled, depth write disabled), the mesh is rendered after all opaque geometry. However here it’s possible that the triangles closer to the camera are rendered first while the ones in the back are rendered last. This causes a wrong color mixing as in essence the triangles in the back are rendered on top of the ones in the front.

The solution that @jtrupiano suggested does not really fix the issue. A transparent shader that does write to the depth buffer can magically hide parts behind the closer triangles, if those triangles has been rendered first. That’s because when you write to the depth buffer, no geometry further away can be drawn at this point afterwards. However if the view direction is from the other side, you would again see the proper layering of the self overlapping triangles.

Unity does sort all transparent geometry from back to front. However Unity can only do this on a per-object basis and not on a per triangle basis. Even a per triangle basis can not be enough as It is possible to have a circular layering as shown in this article with the red, green and blue bars. Those are impossible to draw in the correct order without splitting at least one of the bars into two parts. Proper depth sorting is one of the hardest problems that does not really have an easy solution.

Some of the mentioned workarounds may work in some cases or at least produce artifacts which are acceptable / not really noticable. However it certainly does not solve all potential issues with transparent geometry.