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.

I’ve resolved it—rep.modify.material(rep.distribution.sequence(material_paths)) accepts material paths, which I hadn’t noticed before. The code is as follows.

import omni.replicator.core as rep
import omni.kit.commands
import omni.kit.material.library
import asyncio
from pxr import Usd, Gf, Sdf


# 设定反射率参数else
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")

    sphere = rep.create.sphere(semantics=[('class', 'sphere')], position=(0, 1, 1))
    cube = rep.create.cube(semantics=[('class', 'cube')],  position=(2, 2, 1))
    plane = rep.create.plane(scale=10, visible=True)

    # 设定反射率参数leaf
    material_paths = []
    # 开始创建材质
    for i in range(50):
        prim_name = 'OmniSurface' + str(i)
        ref = (i+1)/50
        tran = 0
        material_paths.append('/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))

    def get_shapes_new():
        shapes = rep.get.prims(semantics=[('class', 'cube'), ('class', 'sphere')])
        with shapes:
            rep.modify.material(rep.distribution.sequence(material_paths))
        return shapes.node

    rep.randomizer.register(get_shapes_new)

    # Setup randomization
    with rep.trigger.on_frame(num_frames=50):
        rep.randomizer.get_shapes_new()
rep.orchestrator.run()
1 Like

thanks for reporting back with a solution snippet! i found it very useful.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.