I’m writing a script to set and randomize the material/shader for any rigid body under DirectRLEnv. However I encounter 2 problems:
- The material I created is somehow invalid, and does not look like a complete one either. I get no idea how to create a valid and compelete one.
- I failed to bind the material with the prim after I create it.
Isaac Sim Version
5.0.0
Operating System
Ubuntu 22.04
GPU Information
- Model: NVIDIA GeForce RTX 5090
- Driver Version: 570.86.10
- nvcc Version: Build cuda_12.8.r12.8/compiler.35404655_0Topic Description
Detailed Description
My script can be concluded as below:
from isaaclab.envs import DirectRLEnv
import omni
from pxr import UsdShade,Sdf
from isaacsim.replicator.behavior.utils.scene_utils import create_mdl_material
import random
class MyEnv(DirectRLEnv):
def _setup_scene(self):
# unrelated code omitted
# 1. create material for my table
mtl_path = "my_path/mdl/Aluminum_Anodized.mdl"
prim_path = "/World/envs/env_0/RigidObjects/table/Looks"
material = create_mdl_material(
mtl_url=mtl_path, mtl_name="test_mtl", mtl_path=prim_path
)
# 2. randomization logic, e.g. on "diffuse_texture"
_texture_urls = [
"my_path/texture/wood_brown.png",
"my_path/texture/linen_gray.png",
"my_path/texture/concrete_gray.png",
]
shader_prim = omni.usd.get_shader_from_material(material, get_prim=True)
shader = UsdShade.Shader(shader_prim)
for shader_input in shader.GetInputs():
if "diffuse_texture" in shader_input.GetFullName():
diffuse_texture = random.choice(_texture_urls)
shader_input.Set(diffuse_texture)
# 3. bind material to prim
stage = omni.usd.get_context().get_stage()
prim = stage.GetPrimAtPath(prim_path)
UsdShade.MaterialBindingAPI(prim).Bind(
material, UsdShade.Tokens.strongerThanDescendants
)
# FYI:
# from isaacsim.replicator.behavior.utils.scene_utils import create_mdl_material
# https://github.com/isaac-sim/IsaacSim/blob/47d886f2858d1ceed556b21c88927aa67bc81c12/source/extensions/isaacsim.replicator.behavior/isaacsim/replicator/behavior/utils/scene_utils.py#L377
def create_mdl_material(mtl_url: str, mtl_name: str, mtl_path: str) -> UsdShade.Material:
"""Creates an MDL material at the given path with the specified URL and name."""
omni.kit.commands.execute("CreateMdlMaterialPrim", mtl_url=mtl_url, mtl_name=mtl_name, mtl_path=mtl_path)
stage = omni.usd.get_context().get_stage()
mtl_prim = stage.GetPrimAtPath(mtl_path)
shader = UsdShade.Shader(omni.usd.get_shader_from_material(mtl_prim, get_prim=True))
# Create various material inputs
shader.CreateInput("diffuse_texture", Sdf.ValueTypeNames.Asset)
shader.CreateInput("project_uvw", Sdf.ValueTypeNames.Bool)
shader.CreateInput("texture_scale", Sdf.ValueTypeNames.Float2)
shader.CreateInput("texture_rotate", Sdf.ValueTypeNames.Float)
return UsdShade.Material(mtl_prim)
Error Messages
[Error] [omni.hydra] Unable to find SdrShaderNode for prim: ‘/World/envs/env_0/RigidObjects/table/Looks/Shader’ with identifier: ‘9514733464790506132<table_material>’.
Screenshots or Videos
- If I manually bind the material onto my table prim in IsaacSim-Property-Material and Shader-Shader, it will turn RED:
-
The invalid and incomplete Shader somehow works with the value I give it, but it still looks incomplete:
-
Take a valid one for example, it seems to have more items:
Additional Information
Related Issues
I’ve read this: How to change properties of loaded material?. however the helpful links inside all turns invalid now.


