From 88b8b584295428f2103e461947d6b81c489ba8f7 Mon Sep 17 00:00:00 2001 From: Haroon Qureshi Date: Thu, 21 May 2026 23:35:18 -0700 Subject: [PATCH] Add support for transparent PBR materials. PiperOrigin-RevId: 919477028 Change-Id: I75cc311fc73dd5fe26b72ba8d49fd421fda455e3 --- src/experimental/filament/CMakeLists.txt | 2 + .../assets/pbr_packed_transparent.mat | 53 ++++++++++++++++++ .../filament/assets/pbr_transparent.mat | 56 +++++++++++++++++++ .../filament/compat/scene_geom_util.cc | 1 + .../filament/filament/material.cc | 31 ++++++++-- .../filament/filament/object_manager.cc | 3 + .../filament/filament/object_manager.h | 2 + .../filament/render_context_filament.h | 3 + src/experimental/studio/live.js | 2 + 9 files changed, 148 insertions(+), 5 deletions(-) create mode 100644 src/experimental/filament/assets/pbr_packed_transparent.mat create mode 100644 src/experimental/filament/assets/pbr_transparent.mat diff --git a/src/experimental/filament/CMakeLists.txt b/src/experimental/filament/CMakeLists.txt index 7f5aac1d..0ba891b6 100644 --- a/src/experimental/filament/CMakeLists.txt +++ b/src/experimental/filament/CMakeLists.txt @@ -100,7 +100,9 @@ file(COPY set(MATC_EXECUTABLE matc) set(MATERIAL_FILES pbr.mat + pbr_transparent.mat pbr_packed.mat + pbr_packed_transparent.mat phong_2d_fade.mat phong_2d.mat phong_2d_reflect.mat diff --git a/src/experimental/filament/assets/pbr_packed_transparent.mat b/src/experimental/filament/assets/pbr_packed_transparent.mat new file mode 100644 index 00000000..88b0a003 --- /dev/null +++ b/src/experimental/filament/assets/pbr_packed_transparent.mat @@ -0,0 +1,53 @@ +// Copyright 2025 DeepMind Technologies Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +material { + name : pbr_packed_transparent, + shadingModel : lit, + flipUV: false, + blending: transparent, + parameters : [ + { type : sampler2d, name : BaseColor }, + { type : sampler2d, name : Opacity }, + { type : sampler2d, name : Normal }, + { type : sampler2d, name : ORM }, + { type : sampler2d, name : Emissive }, + { type : float4, name : BaseColorFactor }, + { type : float, name : MetallicFactor }, + { type : float, name : RoughnessFactor } + ], + requires : [ + uv0 + ] +} + +fragment { + void material(inout MaterialInputs material) { + vec2 uv = getUV0(); + + material.normal = texture(materialParams_Normal, uv).xyz * 2.0 - 1.0; + prepareMaterial(material); + + material.baseColor = materialParams.BaseColorFactor; + material.baseColor *= texture(materialParams_BaseColor, uv); + material.baseColor.a *= texture(materialParams_Opacity, uv).r; + material.ambientOcclusion = texture(materialParams_ORM, uv).r; + material.roughness = materialParams.RoughnessFactor; + material.roughness *= texture(materialParams_ORM, uv).g; + material.metallic = materialParams.MetallicFactor; + material.metallic *= texture(materialParams_ORM, uv).b; + material.emissive = texture(materialParams_Emissive, uv); + material.emissive.a = 1.0 - material.emissive.a; + } +} diff --git a/src/experimental/filament/assets/pbr_transparent.mat b/src/experimental/filament/assets/pbr_transparent.mat new file mode 100644 index 00000000..eb69d440 --- /dev/null +++ b/src/experimental/filament/assets/pbr_transparent.mat @@ -0,0 +1,56 @@ +// Copyright 2025 DeepMind Technologies Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +material { + name : pbr_transparent, + shadingModel : lit, + flipUV: false, + blending: transparent, + parameters : [ + { type : sampler2d, name : BaseColor }, + { type : sampler2d, name : Opacity }, + { type : sampler2d, name : Normal }, + { type : sampler2d, name : Occlusion }, + { type : sampler2d, name : Roughness }, + { type : sampler2d, name : Metallic }, + { type : sampler2d, name : Emissive }, + { type : float4, name : BaseColorFactor }, + { type : float, name : MetallicFactor }, + { type : float, name : RoughnessFactor } + + ], + requires : [ + uv0 + ] +} + +fragment { + void material(inout MaterialInputs material) { + vec2 uv = getUV0(); + + material.normal = texture(materialParams_Normal, uv).xyz * 2.0 - 1.0; + prepareMaterial(material); + + material.baseColor = materialParams.BaseColorFactor; + material.baseColor *= texture(materialParams_BaseColor, uv); + material.baseColor.a *= texture(materialParams_Opacity, uv).r; + material.ambientOcclusion = texture(materialParams_Occlusion, uv).r; + material.roughness = materialParams.RoughnessFactor; + material.roughness *= texture(materialParams_Roughness, uv).r; + material.metallic = materialParams.MetallicFactor; + material.metallic *= texture(materialParams_Metallic, uv).r; + material.emissive = texture(materialParams_Emissive, uv); + material.emissive.a = 1.0 - material.emissive.a; + } +} diff --git a/src/experimental/filament/compat/scene_geom_util.cc b/src/experimental/filament/compat/scene_geom_util.cc index 0d542ac2..a2c11a65 100644 --- a/src/experimental/filament/compat/scene_geom_util.cc +++ b/src/experimental/filament/compat/scene_geom_util.cc @@ -198,6 +198,7 @@ static void UpdateGeomMaterial(mjrRenderable* renderable, const mjvGeom& geom, }; material.color_texture = get_texture(mjTEXROLE_RGB); material.normal_texture = get_texture(mjTEXROLE_NORMAL); + material.opacity_texture = get_texture(mjTEXROLE_OPACITY); material.emissive_texture = get_texture(mjTEXROLE_EMISSIVE); material.orm_texture = get_texture(mjTEXROLE_ORM); material.metallic_texture = get_texture(mjTEXROLE_METALLIC); diff --git a/src/experimental/filament/filament/material.cc b/src/experimental/filament/filament/material.cc index b96f6f17..21a024db 100644 --- a/src/experimental/filament/filament/material.cc +++ b/src/experimental/filament/filament/material.cc @@ -38,15 +38,35 @@ ObjectManager::MaterialType GetMaterialType(const mjrMaterial& material, return ObjectManager::kUnlitDecor; } } else if (material.orm_texture) { - return ObjectManager::kPbrPacked; + if (material.opacity_texture) { + return ObjectManager::kPbrPackedTransparent; + } else { + return ObjectManager::kPbrPacked; + } } else if (material.metallic_texture) { - return ObjectManager::kPbr; + if (material.opacity_texture) { + return ObjectManager::kPbrPackedTransparent; + } else { + return ObjectManager::kPbr; + } } else if (material.roughness_texture) { - return ObjectManager::kPbr; + if (material.color[3] < 1.0f) { + return ObjectManager::kPbrTransparent; + } else { + return ObjectManager::kPbr; + } } else if (material.metallic >= 0) { - return ObjectManager::kPbr; + if (material.color[3] < 1.0f) { + return ObjectManager::kPbrTransparent; + } else { + return ObjectManager::kPbr; + } } else if (material.roughness >= 0) { - return ObjectManager::kPbr; + if (material.color[3] < 1.0f) { + return ObjectManager::kPbrTransparent; + } else { + return ObjectManager::kPbr; + } } // Check to see if we're dealing with a mesh with texture coordinates. @@ -163,6 +183,7 @@ void UpdateMaterialInstance(filament::MaterialInstance* instance, }; TrySetTexture("BaseColor", material.color_texture, mjTEXROLE_RGB); + TrySetTexture("Opacity", material.opacity_texture, mjTEXROLE_OPACITY); TrySetTexture("Normal", material.normal_texture, mjTEXROLE_NORMAL); TrySetTexture("Metallic", material.metallic_texture, mjTEXROLE_METALLIC); TrySetTexture("Roughness", material.roughness_texture, mjTEXROLE_ROUGHNESS); diff --git a/src/experimental/filament/filament/object_manager.cc b/src/experimental/filament/filament/object_manager.cc index 1816b627..47630bb6 100644 --- a/src/experimental/filament/filament/object_manager.cc +++ b/src/experimental/filament/filament/object_manager.cc @@ -55,6 +55,8 @@ ObjectManager::ObjectManager(filament::Engine* engine) : engine_(engine) { materials_[kPbr] = LoadMaterial(engine, "pbr.filamat"); materials_[kPbrPacked] = LoadMaterial(engine, "pbr_packed.filamat"); + materials_[kPbrTransparent] = LoadMaterial(engine, "pbr_transparent.filamat"); + materials_[kPbrPackedTransparent] = LoadMaterial(engine, "pbr_packed_transparent.filamat"); materials_[kPhong2d] = LoadMaterial(engine, "phong_2d.filamat"); materials_[kPhong2dFade] = LoadMaterial(engine, "phong_2d_fade.filamat"); materials_[kPhong2dReflect] = LoadMaterial(engine, "phong_2d_reflect.filamat"); @@ -97,6 +99,7 @@ ObjectManager::ObjectManager(filament::Engine* engine) fallback_textures_[mjTEXROLE_USER] = fallback_black_; fallback_textures_[mjTEXROLE_RGB] = fallback_white_; + fallback_textures_[mjTEXROLE_OPACITY] = fallback_white_; fallback_textures_[mjTEXROLE_OCCLUSION] = fallback_white_; fallback_textures_[mjTEXROLE_ROUGHNESS] = fallback_white_; fallback_textures_[mjTEXROLE_METALLIC] = fallback_black_; diff --git a/src/experimental/filament/filament/object_manager.h b/src/experimental/filament/filament/object_manager.h index 509b3505..05ce49d5 100644 --- a/src/experimental/filament/filament/object_manager.h +++ b/src/experimental/filament/filament/object_manager.h @@ -42,7 +42,9 @@ class ObjectManager { // ObjectManager. enum MaterialType { kPbr, + kPbrTransparent, kPbrPacked, + kPbrPackedTransparent, kPhong2d, kPhong2dFade, kPhong2dReflect, diff --git a/src/experimental/filament/render_context_filament.h b/src/experimental/filament/render_context_filament.h index 023cc62c..fcc587c9 100644 --- a/src/experimental/filament/render_context_filament.h +++ b/src/experimental/filament/render_context_filament.h @@ -627,6 +627,9 @@ struct mjrMaterial { // The texture containing the base color of the object. const mjrTexture* color_texture; + // The texture containing the opacity of the object. + const mjrTexture* opacity_texture; + // The normal map of the object. const mjrTexture* normal_texture; diff --git a/src/experimental/studio/live.js b/src/experimental/studio/live.js index c479f40f..8de5230f 100644 --- a/src/experimental/studio/live.js +++ b/src/experimental/studio/live.js @@ -57,7 +57,9 @@ var Module = { "assets/ibl.ktx", "assets/OpenSans-Regular.ttf", "assets/pbr.filamat", + "assets/pbr_transparent.filamat", "assets/pbr_packed.filamat", + "assets/pbr_packed_transparent.filamat", "assets/phong_2d_fade.filamat", "assets/phong_2d.filamat", "assets/phong_2d_reflect.filamat",