Search Unity

Efficiently removing a triangle from the triangle array/buffer of a mesh at runtime

Discussion in 'General Graphics' started by lmakor, Jan 3, 2022.

  1. lmakor

    lmakor

    Joined:
    Oct 31, 2016
    Posts:
    23
    My problem is as follows:

    I am generating a quite large (10k+ vertices) mesh at runtime and need to adapt that mesh continuously at runtime, typically multiple times per second without dropping any frames (on mobile).
    Hence, performance is a big concern.

    What I am currently working on is being able to efficiently remove a triangle from the mesh - as in really just removing the 3 vertex indices from the Mesh.triangles array/buffer.
    Of course, updating the index array that I have in my C# program and then setting that array via Mesh.SetTriangles would work.
    But, removing the 3 indices of the triangle in question from my C#-side array requires copying all following indices (I don't want to do the swap&remove approach, because of optimizations in the order of the triangles).
    Furthermore, this would entail another copy when setting the array via Mesh.SetTriangles.

    What I am after is a way that does not require to copy the triangles array, but rather "disable" that triangle.
    However, AFAIK we cannot signal that a triangle in the mesh should not be rendered.
    Like, e.g. setting a non-existent vertex index is not allowed.

    This lead me to Unity's advanced Mesh API, especially Mesh.SetIndexBufferData, which AFAIK allows to update only parts of the triangle array/buffer.
    I am wondering whether this API allows to implement such a "disable a triangle" behaviour.

    So, my idea is to remove the triangle in question, by overriding the indices of that triangle with other values, that do not change the look of the mesh (except for removing said triangle).
    I came up with multiple options, but I am not sure what the implications of these options are (regarding performance or anything else really)

    1. Replace the 3 indices with the same index - i.e. just writing 0 in there, such that the triangle just represents a single point and is not rendered/not visible (not sure about consequences or whether that is even allowed)
    2. Replace the 3 indices with other indices of a valid triangle, such that that valid triangle then would be rendered twice, again I would hope that this would neither negatively affect the visuals nor performance (though I would need to check regarding stuff like z-fighting)
    3. Add 3 dummy vertices to the model, which are far outside the user's view and then just set the vertex indices to these 3 vertices - however, this would change the bounds of the overall mesh and probably interfere with culling and other optimizations, so I am not sure whether this is a good idea.

    So, I would be really glad if someone with more experience in graphics could give me some insights into what the best approach would be - be that one of my outlined solutions or something totally different.
     
  2. Predulus

    Predulus

    Joined:
    Feb 5, 2018
    Posts:
    90
    Bump! What did you end up doing? I need to do something similar.
     
  3. c0d3_m0nk3y

    c0d3_m0nk3y

    Joined:
    Oct 21, 2021
    Posts:
    675
    Things that come to mind
    - Discard the triangles in the vertex shader with a user-defined clip plane
    - Discard the triangles in the vertex shader by setting w to zero
    - Discard the triangles in a geometry shader
    - Use a compute shader to fill the index buffer (don't know if possible)