Search Unity

How to control the visibility of each submesh?

Discussion in 'General Graphics' started by kittycon, Mar 6, 2018.

  1. kittycon

    kittycon

    Joined:
    Jan 12, 2016
    Posts:
    15
    I hava a mesh with many submeshs, I need show same of them not all. It seems like the static batch, unity do it automatic, but i want control it manually with exist mesh. How can i do it?

    And if these submeshs use same material, any way to render it with one draw call? Just like static batch, but static batch will copy meshs, i want use exist mesh.
     
    Last edited: Mar 6, 2018
  2. MSplitz-PsychoK

    MSplitz-PsychoK

    Joined:
    May 16, 2015
    Posts:
    1,278
    To control visibility on a submesh, you can either use different materials (or material property blocks) on each submesh and control visibility through materials, or you can disable "Optimize Game Objects" in the "rig" tab in the Unity model import settings to have each submesh be a GameObject you can turn on and off.

    To draw multiple submeshes with one draw call, you must use static batching or dynamic batching, which (I think) must create a copy of your vertices in a new buffer.
     
  3. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Static batching draws each mesh renderer component as a separate draw call by calling an internal DrawMesh with triangle index ranges on a larger merged mesh. However, since each draw call of a static batch is using the same material and mesh there's no additional "set pass" calls which is the expensive part people mean when they refer to a "draw call". Strictly speaking static batched meshes aren't sub meshes at all.

    If multiple sub meshes of a single mesh renderer is using the same material then Unity can merge these into a single static mesh and draw them individually by drawing the vertex ranges separately, or merge them using dynamic batching. There isn't a way to do this the same way as static batching from script. The closest is to draw the mesh using manual DrawMesh calls and set which submesh to use, assuming each submesh has a different material index. However this will be a separate draw call & set pass for each submesh.

    Alternatively you could use Mesh.CombineMeshes during runtime to generate a new mesh to draw that is a manual batch of the submeshes. This is what dynamic batching does internally.

    Like @Gambit-MSplitz said, the easiest solution is to make each sub mesh an actual separate mesh object and mesh component and let Unity do it for you.
     
  4. kittycon

    kittycon

    Joined:
    Jan 12, 2016
    Posts:
    15
    Thanks for reply! I got some questions:
    1. I see ths static batch mesh has submeshs, and I thought submesh is just means the index range.
    upload_2018-3-7_10-16-19.png
    2. Maybe draw mesh by index ranges is exactly what I want, but i can't find any api for this, DrawMesh can only draw one submesh at a time.
     
  5. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    You're right. I was mistaking the difference between submeshes from material indices and submeshes due to bone count / indices limits which require splitting up the mesh into multiple unique meshes.

    Yep.
     
  6. kittycon

    kittycon

    Joined:
    Jan 12, 2016
    Posts:
    15
    So, static batch draw many submeshs in one draw call, and support hiding some of the them, thus unity can draw a subset of submeshs in one draw call. Is there a api to do this?
     
  7. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    No. As stated above, each submesh of a static batch is a separate draw call still. When skipping a submesh it just doesn't issue that draw call. When drawing multiple submeshes it draws each individually.

    DrawMesh is the closest you can get.