I am using the Hydra 2.0 framework and working on the instancing scene index.
It seems after few tests that if I want to instance 2 meshes with different material binding, it will create underneath 2 prototypes, each one instanciate one time.
My renderer allow to have a different material ans still using hardware instancing so creating 2 prototypes will disable this optimization.
First am I right or do I missed something ?
Second, is it something doable, to create only one prototype and with different material binding primvar ?
Currently, instances need to share a material binding. This is something we’re planning to address in OpenUSD, as we have various renderers that can and cannot vary material bindings per instance. There’s a straightforward technical path, but I don’t have a date yet.
For technical details, the choice to split instance domains based on material binding is a lightweight policy choice. For UsdImagingStageSceneIndex, this is encoded here:
… and for UsdimagingDelegate, here:
The only complication is that we’d need to add support for aggregating per-instance material bindings, following the pattern for (e.g.) aggregating per-instance transforms, which requires a new hydra schema and a bit of glue code. For Hydra Storm we’d also need a bit of code to un-aggregate instances based on material.
Hi @tomc ,
I still have a question regarding instancing in USD / Hydra. I’m using the HdInstancerTopologySchema which tells me which prototype is instanced and the instancelocation.
So basically, we are doing whole subtree instancing.
For example, I have a prototype that will be instanciated at World/Instance1. But it seems that both prims World/Instance1 and the instancer primvar (hydra:instanceTransform) hold the same information.
Indeed, for the prims World/Instance1, the xform holds the exact same transformation matrix as the HdPrimvarsSchema from the prototype with HdInstancerTokens->instanceTransforms. Is this something intended ? I mean, I was expecting the xform for World/Instance1 to be “identity.”
I ended up doing twice the transformation.
For drawing, hydra will loop through the “prototypes” array; grab the associated instance indices; and draw the given prototype the requested number of times with the requested indices into the instance primvar buffers. For example, if instancerTopology has the following:
prototypes = { /_Prototype_1/cube, /_Prototype_1/sphere }
instanceIndices = { [0,2], [1] }
… hydra will draw /_Prototype_1/cube twice with hydra:instanceTransform[0] and [2] respectively.
instanceLocations is not the location of the prototypes to be drawn, but rather the location of each instance of a prototype in the scene graph; this information is carried into hydra for picking & selection, collection resolution, and other path-dependent operations.
The concrete need for this is USD composition instancing. If you give prims /A and /B instanceable references to another prim /C from a different file, in USD the prims /A and /B will essentially just be pointers to a deduplicated copy of /C called /_Prototype_1. In Hydra, we transform this into something that looks like a point instancer: a new instancer prim /UsdPrototypes/foo. It will have a “prototypes” list solely of /_Prototype_1, instanceIndices of { [0,1] }, and per-instance primvars gathered from the instance locations (e.g. “hydra:instanceTransforms” will contain the transform matrices at /A and /B); and instanceLocations will be { /A, /B }.
It’s a bit confusing, even to us sometimes, but it’s efficient. Hope that clarifies!
Tom
Hi @tomc,
Thank you for your answer.
I forgot to tell you that I’m using the Hydra 2.0 framework and that I modified some scene index to NOT flattened the transform.
So, in the case of flattened transforms, I think that the instanceLocation is indeed not needed for the final world transform as it’s already in the hydra:instanceTransform but in my case, I need to know the instance location to compute the correct world transform. So I think my question is very specific because of the unflattening of the transform.
And I also think that in my case, the instanceLocation prim transform is the exact same as the hydra:instanceTransform. I just need to pick one or the other.