Texture map variants

Hello,
I’m trying to figure out how to create a texture map variant across a crowd of characters.
For example I have 100 characters each wearing a hat. The hat is assigned a USDPreviewmaterial with a texture wired into the diffuseColor
The texture path is something like: …/textures/hat.1.tif

say I have 30 different hat maps (i.e. hat.1.tif → hat.30.tif)

I want to perform an ‘over’ in my stage, to assign/vary which character gets which hat colour map.
I can do this semi-manually at the moment, by creating a separate material for each map. and then the over will set the specific material for that character.
But that means 30 individual materials(3 x shader node) per map - which is obviously quite cumbersome over a real shaded character with loads of material parts

is there a way to override the texture map, to use something more traditional in CG like a primvar, to read in / override the map? eg: …/textures/hat.<hat_map>.tif
I tried doing:
over “mtl/usdpreviewmaterial/usduvtexture1” {
asset inputs:file = @/textures/hat2.tif@
}

but that isnt working (I cant target the usduvtexture1 shader)

thanks

For a texture /path/to/texture/hat.1.tif
Set the primvar like this.
asset primvars:txcolor = @/path/to/texture/hat.1.tif@
and then use a UsdPrimvarReader node or some user attribute reader node to fetch the txcolor primvar and plug it to the texture filename.


This way, they all use the same material but the texture can vary per agent.
The name of the primvar txcolor has no importance, you can use whatever you like.
Not all renderers support this workflow. It’s a bit more complicated if you need UDIMs.
This does not work with MaterialX at the moment.

1 Like

Does Storm allow supplying texture file path from asset primvar into UsdUVTexture shader in latest USD version? I’m trying it out but not sure if my setup is wrong or is it simply not supported yet. I’d use it for supplying different textures to a pointInstancer so that I could replace current solution of using multiple prototypes that have material overrides with simple texture paths primvar array.

texture filename inputs are considered non-connectable (i.e. “interfaceOnly”), and therefore cannot be directly driven by a primvar (although some Hydra render delegates may have decided to support it, it is off-spec).

This is one of the key issues meant to be addressed by our upcoming project for “primvar substitutions in assetPaths”, whose goal is to provide such functionality in a way that can be guaranteed to happen outside of the shading network runtime execution (i.e. by Hydra itself).

Until that project lands, the best you can do is:
a) Instance the Material in your asset
b) define the texture input on the Material prim itself, which drives the UsdUVTexture input
c) In the asset root prim, create those 30 variants, each of which just overrides those three properties on the Material prim… or maybe you make a variantSet per texture that needs overriding? I know that’s pretty gross, though.

1 Like

I often use this when it should also run with RealityKit:

  1. Create 30 Materials using different texture sets.
  2. class the master character (so it doesn’t render) and keep out the material binding
  3. reference this class for all instances and over the material binding by one of your 30