From 78df2ae7fad866801dd77fdff47eddfafb5bb545 Mon Sep 17 00:00:00 2001 From: Google DeepMind Date: Tue, 24 Jun 2025 08:05:08 -0700 Subject: [PATCH] Add support mjcf emissive layer materials Mujoco supports emission as a constant coefficient, and emissive, an rgb texture. This cl supports the rgb emissive texture for usd. PiperOrigin-RevId: 775236677 Change-Id: I0e2ce1d9f68d79b6e9d2c28eecab22b2692f061c --- .../usd/plugins/mjcf/mujoco_to_usd.cc | 21 ++++++++++++++++++ .../usd/plugins/mjcf/mjcf_file_format_test.cc | 10 +++++++++ .../usd/plugins/mjcf/testdata/materials.xml | 2 ++ .../mjcf/testdata/textures/emissive.png | Bin 0 -> 6888 bytes 4 files changed, 33 insertions(+) create mode 100644 test/experimental/usd/plugins/mjcf/testdata/textures/emissive.png diff --git a/src/experimental/usd/plugins/mjcf/mujoco_to_usd.cc b/src/experimental/usd/plugins/mjcf/mujoco_to_usd.cc index da053e1c..6d559fa8 100644 --- a/src/experimental/usd/plugins/mjcf/mujoco_to_usd.cc +++ b/src/experimental/usd/plugins/mjcf/mujoco_to_usd.cc @@ -91,6 +91,7 @@ TF_DEFINE_PRIVATE_TOKENS(kTokens, ((inputsWrapS, "inputs:wrapS")) ((inputsWrapT, "inputs:wrapT")) ((inputsDiffuseColor, "inputs:diffuseColor")) + ((inputsEmissiveColor, "inputs:emissiveColor")) ((outputsRgb, "outputs:rgb")) ((outputsR, "outputs:r")) ((outputsG, "outputs:g")) @@ -794,6 +795,26 @@ class ModelWriter { } } + // Connect an emissive texture if specified. + if (mjTEXROLE_EMISSIVE < textures.size()) { + std::string emissive_texture_name = textures[mjTEXROLE_EMISSIVE]; + mjsTexture *emissive_texture = mjs_asTexture( + mjs_findElement(spec_, mjOBJ_TEXTURE, emissive_texture_name.c_str())); + if (emissive_texture) { + pxr::SdfPath emissive_attr = CreateAttributeSpec( + data_, preview_surface_shader_path, kTokens->inputsEmissiveColor, + pxr::SdfValueTypeNames->Color3f); + const std::vector emissive_map_output_attrs = + AddTextureShader(material_path, emissive_texture->file->c_str(), + pxr::TfToken("emissive"), uvmap_st_output_attr, + {kTokens->outputsRgb}); + if (emissive_map_output_attrs.size() == 1) { + AddAttributeConnection(data_, emissive_attr, + emissive_map_output_attrs[0]); + } + } + } + pxr::SdfPath diffuse_color_attr = CreateAttributeSpec( data_, preview_surface_shader_path, kTokens->inputsDiffuseColor, pxr::SdfValueTypeNames->Color3f); diff --git a/test/experimental/usd/plugins/mjcf/mjcf_file_format_test.cc b/test/experimental/usd/plugins/mjcf/mjcf_file_format_test.cc index 446f009e..41bd3ea3 100644 --- a/test/experimental/usd/plugins/mjcf/mjcf_file_format_test.cc +++ b/test/experimental/usd/plugins/mjcf/mjcf_file_format_test.cc @@ -192,6 +192,16 @@ TEST_F(MjcfSdfFileFormatPluginTest, TestMaterials) { stage, "/mesh_test/Materials/material_layered/orm_packed.inputs:file", pxr::SdfAssetPath("textures/orm.png")); + EXPECT_PRIM_VALID(stage, "/mesh_test/Materials/material_layered/emissive"); + ExpectAttributeHasConnection( + stage, + "/mesh_test/Materials/material_layered/" + "PreviewSurface.inputs:emissiveColor", + "/mesh_test/Materials/material_layered/emissive.outputs:rgb"); + ExpectAttributeEqual( + stage, "/mesh_test/Materials/material_layered/emissive.inputs:file", + pxr::SdfAssetPath("textures/emissive.png")); + EXPECT_PRIM_VALID(stage, "/mesh_test/Materials/material_metallic"); EXPECT_PRIM_VALID(stage, "/mesh_test/Materials/material_metallic/PreviewSurface"); diff --git a/test/experimental/usd/plugins/mjcf/testdata/materials.xml b/test/experimental/usd/plugins/mjcf/testdata/materials.xml index 175c3ec8..dfb869d4 100644 --- a/test/experimental/usd/plugins/mjcf/testdata/materials.xml +++ b/test/experimental/usd/plugins/mjcf/testdata/materials.xml @@ -3,6 +3,7 @@ + @@ -10,6 +11,7 @@ + 2d texture="diffuse" normal="normal" /> diff --git a/test/experimental/usd/plugins/mjcf/testdata/textures/emissive.png b/test/experimental/usd/plugins/mjcf/testdata/textures/emissive.png new file mode 100644 index 0000000000000000000000000000000000000000..8c244eca6405e36009a8cf885df2f6487315bbb2 GIT binary patch literal 6888 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 ZZg$RQK;>7N3*+AbFw{5Id!a+R{y$HZ@S6Yt literal 0 HcmV?d00001