How to randomize only one material for multiple objects?

Hey there,

I want to randomize the materials of the floor tiles from the warehouse (warehouse_multiple_shelves.usd) example. Therefore I added some Materials from the materials tab to the scene which are then located at /Root/Looks/* . I want to choose just one material for all the floor Elements but I can’t find the right method to do so.

I am able to choose random Materials for every floor Element individually with the following method:

def randomize_floor_material():
        floorTiles = rep.randomizer.materials(materials=rep.get.material("/Root/Looks/*"), 
                     input_prims=rep.get.prims(path_pattern="/Root/SM_floor\d\d/SM_floor02"))
        return floorTiles.node

But I would like to be able to do something like this:

def randomize_floor_material():
        material = rep.get.material("/Root/Looks/*")
        floorTiles = rep.modify.attribute(name="material", value=material, input_prims= 
                     rep.get.prims(path_pattern="/Root/SM_floor\d\d/SM_floor02"))
        return floorTiles.node

But I don’t know how to get one random material from the rep.get.material method as it returns a rep.replicator.core.get.material and i can’t find the documentation on those objects. Is there any documentation on the rep.replicator.core.get.material Object and/or on the ReplicatorItem object to look things up?
Also the rep.modify.attribute(name="material", ...) method does not change the material of the Tiles. Maybe I did something wrong there.

Thanks in Advance.

First I would move all of the floor prims into a newly created Xform Prim:

image

Then I would try running this script:


import omni.replicator.core as rep

with rep.trigger.on_frame(num_frames=10):
	random_mat = rep.create.material_omnipbr(diffuse_texture=rep.distribution.choice(["omniverse://localhost/NVIDIA/Assets/Isaac/2022.2.0/Isaac/Materials/Textures/Patterns/nv_asphalt_yellow_weathered.jpg",
                    "omniverse://localhost/NVIDIA/Assets/Isaac/2022.2.0/Isaac/Materials/Textures/Patterns/nv_brick_grey.jpg",
                    "omniverse://localhost/NVIDIA/Assets/Isaac/2022.2.0/Isaac/Materials/Textures/Patterns/nv_tile_hexagonal_green_white.jpg",
                    "omniverse://localhost/NVIDIA/Assets/Isaac/2022.2.0/Isaac/Materials/Textures/Patterns/nv_wood_shingles_brown.jpg",
                    "omniverse://localhost/NVIDIA/Assets/Isaac/2022.2.0/Isaac/Materials/Textures/Patterns/nv_tile_hexagonal_various.jpg"]))
	with rep.get.xform("SM_floor"):
		rep.randomizer.materials(random_mat)

What this will do is change the material for SM_floor and apply it to all of it’s children. It is import to have rep.create.material_omnipbr inside of the trigger functionality to see the material change.

Also note that loading material textures can be a bit expensive, so if you have only a limited number of textures (as in you know you’ll be re-using them) and you’re going to be shuffling your training data before training, you can place that block under a separate trigger with a higher interval. That way your characters and camera randomize each frame but you minimize the number of time Kit has to load in a new texture.

Thank you very much for your fast reply.

I try to do this with materials from the Window/Browsers/Materials which I add to the stage. As they are better suited for what I need them and I want to randomly choose one material from a large number of materials which would be a lot of work to put them all in a list manually and as they may vary from stage to stage it would not be very efficient.

Isn’t there a possibility to do this with those materials? So to get a list of all the materials in the /Root/Looks/ folder from the stage. And then use the

with rep.get.xform("SM_floor"): 
    rep.randomizer.materials(rep.distribution.choice(materials_list))

Thanks for the hint. I also considered doing the material randomization not every frame but instead like every 100 Frames. I hope I understood it right how to do this (in pseudocode below). So that in the End it would look something like this:

# Get a list of all Materials from the /Root/Looks folder
materials_list = rep.get.material_paths("/Root/Looks/*")
# Randomize every Frame
with rep.trigger.on_frame(num_frames=1000):
    # Randomizing Camera, Objects, Lights here

# Randomize every 100 Frames
with rep.trigger.on_frame(num_frames=10, interval=100):
    with rep.get.xform(path_pattern="/Root/SM_floor"):
        material = rep.distribution.choice(materials_list)
        floorTiles = rep.randomizer.materials(materials=material)

Are there any updates on this topic? Because I am trying to use the Materials from Window/Browsers/Materials but i am not able to assign them via a Python Script? What is the reccomended way to do this?

If I assign the material like this:

I get the following error message and the rendering process stops ==> I have to stop the script manually:

Maybe there is a possibility to load a material to the stage via a script?