Primvar overrides for single and multiple level instancing

This is a question regarding primvar overrides for general prims vs instantiable prims.

This is a basic setup where we have primvar overrides authored at different levels of instancing, ranging from no instancing to two-level instancing.

#usda 1.0
(
    defaultPrim = "World"
    upAxis = "Y"
)
 
def Xform "assets"
{
    token visibility = "invisible"
 
    def Xform "cylinder" (
        # Uncomment line below for two-level instancing
        # instanceable = true
    )
    {
        def Cylinder "mesh_0"
        {
            double radius = 0.4
            uniform token[] xformOpOrder = ["xformOp:rotateXYZ"]
            double3 xformOp:rotateXYZ = (90, 0, 0)
        }
    }
 
    def Xform "sphere" (
        # Uncomment line below for two-level instancing
        # instanceable = true
    )
    {
        def Sphere "mesh"
        {
            double radius = 0.7
        }
    }
 
    def Xform "combined_asset" (
        # Uncomment line below for single level instancing
        # instanceable = true
    )
    {
        def Xform "xform"
        {
            def "cylinder" (
                prepend inherits = </assets/cylinder>
            )
            {
                color3f[] primvars:displayColor = [(0, 1, 0)]
            }
 
            def "sphere" (
                prepend inherits = </assets/sphere>
            )
            {
            }
        }
    }
}
 
def "World"
{
    def "combined_asset_0_0" (
        prepend references = </assets/combined_asset>
    )
    {
        double3 xformOp:translate = (0, 0, 0)
        uniform token[] xformOpOrder = ["xformOp:translate"]
    }
 
    def "combined_asset_0_1" (
        prepend references = </assets/combined_asset>
    )
    {
        double3 xformOp:translate = (0, 3, 0)
        uniform token[] xformOpOrder = ["xformOp:translate"]
    }
 
    def "combined_asset_1_0" (
        prepend references = </assets/combined_asset>
    )
    {
        color3f[] primvars:displayColor = [(1, 0, 0)]
        double3 xformOp:translate = (3, 0, 0)
        uniform token[] xformOpOrder = ["xformOp:translate"]
    }
 
    def "combined_asset_1_1" (
        prepend references = </assets/combined_asset>
    )
    {
        color3f[] primvars:displayColor = [(1, 0, 0)]
        double3 xformOp:translate = (3, 3, 0)
        uniform token[] xformOpOrder = ["xformOp:translate"]
    }
}

For the no-instancing setup, the overrides for an asset referencing another prim are applied only if the override isn’t present in the reference. This produces the image below.

However, when the references are converted to instances (by uncommenting the lines in the snippet), the behaviour of the overrides are not immediately clear.

The native GL delegate in usdview produces same result for single level instances, but renders the assets as white for two level instancing. This behaviour is different from the HdStorm delegate in Houdini, which produces the same result for all cases, ranging from no instancing to two level instancing.

(Splitting the question across replies as I cannot embed two images as a new user)

To add to the question, there also appears to be a different interpolation category for HdInstancer(OpenUSD/pxr/imaging/hd/enums.h at 822f0ae7fb51ae47c76b3254a87a4e655ee39153 · PixarAnimationStudios/OpenUSD · GitHub), which indicates this primvar is constant across all the instances created by the instancer. In which case, any primvar that is of interpolation instance must override the values authored on the referenced prim. This produces the different result as seen below:

What would be the right behaviour for primvar overrides for instances for all levels of nesting given the example? Is there an expectation that it has to match the same behaviour as the no instancing case? What is the expected behaviour for instance primvars in Hydra?

Thank you in advance for all the help.

Kind Regards,
Girish

Hi Girish,

Maybe this thread have some answers to your question(s): Do primvars apply inside Instances?

Cheers,
Paolo