0
\$\begingroup\$

I am making a procedurally generated voxel world made of blocks. Some of the blocks have non cubic shapes (ramps), and some of the blocks are transparent (water).

All the blocks are part of the same mesh. The mesh is made out of 2 sub-meshes, both using unity's standard shader, one with the opaque rendering mode, while the other uses the transparent mode.

I want to allow for the water block to render at the same location as a ramp block, with the water correctly appearing above the ground.

Here is an image of a ramp block next to a water block:

ramp next to a water block

When I combine them however, I get the following effect:

combined

I have set the transparent Shader to write to the Z-Buffer using:

meshRenderer.materials[1].SetInt("_ZWrite", 1);

(Otherwise only the water block is visible)

Here is my code for rendering the mesh:

filter.mesh.Clear();
filter.mesh.vertices = meshData.vertices.ToArray();

filter.mesh.subMeshCount = 2;
filter.mesh.SetTriangles(meshData.triangles.ToArray(), 0);
filter.mesh.SetTriangles(meshData.transparentTriangles.ToArray(), 1);

filter.mesh.uv = meshData.uv.ToArray();
filter.mesh.RecalculateNormals();

meshData.triangles contains the triangles of the opaque blocks, and meshData.transparentTriangles contains the triangles of the transparent blocks.

I have tried to slightly offset the water block, to avoid having 2 triangles at the exact same position, and that almost gives me the effect I want, except for some reason the opaque block becomes transparent, even though it's triangles are rendered by the opaque shader:

https:// i.stack.imgur.com/zlSKl .png

(The link is weird since it does not allow me to post a 3rd image link as I dont have enough reputation, please just remove the spaces)

Any help with solving the issue would be greatly appreciated.

Thank you.

\$\endgroup\$
  • \$\begingroup\$ This is a recipe for z-fighting. There are ways to mitigate it with biases and whatnot, but they're fiddly, not what I would call a robust solution. Your better bet is to adjust the mesh so that you don't get these overlaps in the first place - clipping the water tiles to the actual surface you want to render, and not including hidden polygons. As a bonus, this will tend to be more efficient for rendering too. \$\endgroup\$ – DMGregory Sep 10 '17 at 20:41
  • \$\begingroup\$ Yeah, I thought about that, but it would require a huge amount of fiddling. The mesh is manipulated manually in the code, which means the code has to place vertices, and add triangles and UVs. Since I have 3 ramp types, and each type can be rotated in 4 different directions, that means creating 12 different shapes for the water to take when overlapping the ramps, and each shape contains quite a lot of vertices to add manually... I thought maybe someone knows of a better solution. Perhaps using some custom shader? \$\endgroup\$ – user92748 Sep 10 '17 at 20:47
0
\$\begingroup\$

I solved it by placing the water block at the same position as the ramp block, but scaling the water block to be 99.9% of it's original size, which solved the z-fighting issue.

Here is how it looks:

solution

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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