Hiding triangles on a mesh (via shader? script?)

I’m creating a set of polygon-based effects (scripts) that can be applied to objects with mesh-related components. One thing I would like to do is hide/show certain polygons (triangles), to create effects such as random flickering of polygons and ability to hide polys by clicking on them.

A simple method that can work is to simply reconstruct the Mesh.triangles array without the vertices of the triangle to be hidden. I’d have to rebuild the Mesh.normals array as well in that case. The problem is however that calling this repeatedly would require constantly changing and recalculating the mesh, which hardly seems to be suitable for real-time effects such as the aforementioned random flickering, and would also screw up MeshCollider and InteractiveCloth behavior.

I have very little (if any) knowledge of shaders, but I’m guessing they are probably a better approach than scripting. What kind of shader would I use, and what would I supply it? For random on/off I’m assuming I can determine this in the shader, but for hiding specific triangles, is it possible to pass into the shader an array of triangle indices (as a 2D texture maybe)?

Thanks for any help.

I would simply reverse the winding order of the desired triangles: since most shaders use Cull Back, triangles facing the opposite side (with reversed winding order) are invisible:

function RevTriangle(numTriangle: int){
  var mesh : Mesh = GetComponent(MeshFilter).mesh;
  var triIndex = numTriangle * 3;
  // swap two vertex indexes in the tri:
  var tmp: int = mesh.triangles[triIndex];
  mesh.triangles[triIndex] = mesh.triangles[triIndex+1];
  mesh.triangles[triIndex+1] = tmp;
}

This method is simple, but may produce weird results when the camera moves in such a direction that makes the “invisible” triangles face it. Another possible solution (not tested!) could be to null the triangle: set all 3 triangle vertices to the same vertex index, so that the resulting triangle have zero area:

function EmptyTriangle(numTriangle: int){
  var mesh : Mesh = GetComponent(MeshFilter).mesh;
  var triIndex = numTriangle * 3;
  // make the three vertex equal to the first one:
  mesh.triangles[triIndex+1] = mesh.triangles[triIndex];
  mesh.triangles[triIndex+2] = mesh.triangles[triIndex];
}

I’ve not tested this alternative, but based solely in logic arguments it should work perfectly: all GPUs should handle correctly zero area triangles, since small far triangles eventually fall in this case.

Notice that none of the above alternatives change the vertices, uvs, normals etc. - only the desired triangles are affected, and even the triangle count remains the same, thus both are very fast.

Depending on how many triangles you have, you may want to construct submeshes, one per triangle (or group of them) you would be hiding, and then adjust the alpha (say) of the material corresponding to that submesh.

Simplies way is to mark vertex indexes, that you want to hide, make their vertex Color.a = 0, then use Particle Standard Surface shader, in cutout mode, or make any cutout shader use vertex Color alpha for hide117379-image-2018-05-22-00-11-392222.png

Use a mask with a cutout or transparent shader. I was going to write an envelopment system - using the normals of the “bottom most” mesh to cast a ray into the scene and if it came into contact with another face on a mesh within a certain distance (like a piece of clothing), it would hide the verts from which the ray was cast…but it then occurred to me that if the UVs are set up properly on your mesh, you should be able to provide a simple black/white mask in the opacity channel to cover areas of the mesh you want to hide…