How to modify the color of an Omnisurface material using Replicator

I would like to use Replicator to modify the color of the OmniSurface material. Specifically, each mesh in my scene has hundreds of different colors, and I need to use Replicator to continuously switch the material colors and render an image for each color.

However, I’ve encountered a problem: I’m using the OmniSurface material because it has the transmission property I need, and the entire simulation is built upon it, so I can’t switch to OmniPBR. When checking the Replicator API, I only found functions that support OmniPBR.

I’m wondering if these APIs can also be applied to OmniSurface, or if there’s another way to modify the color of OmniSurface materials?

I’ve discovered that modifying the omnisurface material can be achieved using the following code, provided you first create a list of all materials with different colors.

def get_shapes():

        shapes = rep.get.prims(semantics=[('class', 'cube'), ('class', 'sphere')])

        with shapes:

            rep.modify.material(material_paths)

        return shapes.node

However, there’s currently an issue: modify.material cannot render and output according to the material list’s sequence via distribution.sequence. Is there a way to resolve this?

Supplement:

1. rep.get.material did not retrieve the omnisurface material.
2. randomizer.color is not applicable; it defaults to assigning a PBR material.
3. rep.create.from_usd is not applicable; my scene file is very large.

rep.get.material failed to retrieve the ReplicatorItem and returned ‘omni.replicator.core.get.material’.

import omni.replicator.core as rep
import omni.kit.commands
import omni.kit.material.library
import asyncio
from pxr import Usd, UsdGeom, Gf, Sdf
from omni.isaac.core.utils.semantics import add_update_semantics, get_semantics


async def on_created(shader_prim: Usd.Prim, ref, tran):
    shader_prim.CreateAttribute('inputs:diffuse_reflection_weight', Sdf.ValueTypeNames.Float).Set(1)
    shader_prim.CreateAttribute('inputs:diffuse_reflection_color', Sdf.ValueTypeNames.Color3f).Set(Gf.Vec3f(ref, 0.0, 0.0))
    shader_prim.CreateAttribute('inputs:specular_reflection_weight', Sdf.ValueTypeNames.Float).Set(0.0)


# 创建闭包函数来捕获参数
def create_callback_leaf(ref, tran):
    def callback(prim):
        return asyncio.ensure_future(on_created(prim, ref, tran))
    return callback


with rep.new_layer():

    # Add Default Light
    distance_light = rep.create.light(rotation=(315, 0, 0), intensity=3000, light_type="distant")

    spheres = rep.create.sphere(semantics=[('class', 'sphere')], position=rep.distribution.uniform((-10,-10,-10), (10,10,10)), count=100)
    cube = rep.create.cube(semantics=[('class', 'cube')],  position=(2, 2, 1))
    plane = rep.create.plane(scale=10, visible=True)

    # Start creating materials
    stage = omni.usd.get_context().get_stage()
    for i in range(50):
        prim_name = 'OmniSurface' + str(i)
        ref = i+1/50
        tran = 0
        material_path = '/World/Looks/OmniSurface'+str(i)
        omni.kit.commands.execute('CreateAndBindMdlMaterialFromLibrary',
                                    mdl_name='OmniSurface.mdl',
                                    mtl_name='OmniSurface',
                                    prim_name=prim_name,
                                    on_created_fn=create_callback_leaf(ref, tran))
        material_prim = stage.GetPrimAtPath(material_path)
        add_update_semantics(material_prim, semantic_label='material', type_label='class')
        material = rep.get.material(semantics=[('class', 'material')])
        print(material)