Search Unity

Sub Objects ID ?

Discussion in 'Shaders' started by blackant, Nov 18, 2019.

  1. blackant

    blackant

    Joined:
    Jun 18, 2009
    Posts:
    529
    is it possible for a shader to get the object Sub-object ID and use it in the code to make FX ?

    i mean to be clear, when working in max or maya, object may be composed by multiple elements, wich may be refered as sub objects.

    lets say for exemple Box 1 and box 2 are attached into a single object
    so like we can manipulate vertices or faces in shaders, is it possible to do the same for elements who are composing it ?

    thanks
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,348
    There are two questions embedded in this.

    The first is "do shaders or Unity in general have a way of distinguishing between sub objects?" The answer to that is no.

    When Unity imports a model the resulting mesh data is a triangle strips broken up where any hard edge from normals, UVs, or vertex colors exist, resulting in the vertices being split on those edges. Something like a box will thus be 6 of these islands, but they're not numbered in any way as it's just a product of the way the mesh's vertices and triangle indices are stored. Once sent to the GPU, you can get the vertex ID (SV_VertexID) and triangle ID (SV_PrimativeID) in the vertex shader and fragment shader respectively, but again there's nothing about those islands, or the original sub objects retained. The one caveat is if your sub objects use a different material than the "base" object. In this case these are broken off as sub-meshes with their own material on the renderer component. As far as the GPU is concerned they're completely separate meshes with no relation to the parent, and I'm going to assume that's not the situation here.


    The second question is "is it possible to differentiate between sub objects in a shader?" The answer to that is yes!

    As explained above, there's nothing in Unity or on the GPU that differentiates between sub objects, but that doesn't mean you can't do a little extra work to make that happen. The easiest solution would be to give each sub object a different vertex color in Max or Maya. You can either do something like make the main body red, one sub object green, another blue, or just use a single channel and make the main body's red 0, one sub object's red 1/255, the second 2/255, etc. Unity's vertex colors are stored as a single byte per channel, so you need to use values that are steps of 1/255 or larger for the values to be retained. Then in the shader you can do something like this:
    Code (csharp):
    1. if (v.color.r >= _SubObject4Value)
    2. // do stuff
    3. else if (v.color.r >= _SubObject3Value)
    4. // do stuff
    5. else if (v.color.r >= _SubObject2Value)
    6. //etc
     
    blackant likes this.
  3. blackant

    blackant

    Joined:
    Jun 18, 2009
    Posts:
    529
    Excellent !
    thanks for your clear explications i love it !