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:
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?
My solution was to first load the material into the stage and then assigning it to the prim:
We will have some material workflow updates coming to a future version of Replicator that will help with adding materials to a scene, applying them and examples of editing their properties.
For others who might be coming here in the future, we have and will be adding material example scripts here.
Thank you, looking forward to it.