From 8415dff3075e5556f4f669e084f0b2847b9c0f1f Mon Sep 17 00:00:00 2001 From: Haroon Qureshi Date: Fri, 17 Apr 2026 01:58:27 -0700 Subject: [PATCH] Merge Material into Renderable. Allows the Renderable to update its own MaterialInstances whenever Material textures or parameters are modified. Each Renderable now also knows how it is intended to be used (i.e. scene objects or ux) which allows it to correctly pick the underlying filament::Material to use. PiperOrigin-RevId: 901161990 Change-Id: Ic280731d39c272c50d6ad100cec7116e683cbc79 --- .../filament/assets/unlit_segmentation.mat | 4 +- .../filament/filament/imgui_bridge.cc | 15 +- .../filament/filament/material.cc | 109 ++++--------- src/experimental/filament/filament/material.h | 104 +++++-------- .../filament/filament/renderable.cc | 144 +++++++++++++++++- .../filament/filament/renderable.h | 36 ++++- .../filament/filament/scene_geom_util.cc | 97 ++---------- .../filament/filament/scene_view.cc | 10 +- 8 files changed, 252 insertions(+), 267 deletions(-) diff --git a/src/experimental/filament/assets/unlit_segmentation.mat b/src/experimental/filament/assets/unlit_segmentation.mat index 359bb319..b57aca03 100644 --- a/src/experimental/filament/assets/unlit_segmentation.mat +++ b/src/experimental/filament/assets/unlit_segmentation.mat @@ -17,13 +17,13 @@ material { shadingModel : unlit, culling: none, parameters : [ - { type : float4, name : BaseColorFactor } + { type : float4, name : SegmentationColor } ] } fragment { void material(inout MaterialInputs material) { prepareMaterial(material); - material.baseColor = materialParams.BaseColorFactor; + material.baseColor = materialParams.SegmentationColor; } } diff --git a/src/experimental/filament/filament/imgui_bridge.cc b/src/experimental/filament/filament/imgui_bridge.cc index 7337a5b0..f5553ea8 100644 --- a/src/experimental/filament/filament/imgui_bridge.cc +++ b/src/experimental/filament/filament/imgui_bridge.cc @@ -23,7 +23,6 @@ #include #include #include -#include "experimental/filament/filament/draw_mode.h" #include "experimental/filament/filament/material.h" #include "experimental/filament/filament/mesh.h" #include "experimental/filament/filament/renderable.h" @@ -242,11 +241,10 @@ void ImguiBridge::Update() { renderable->UpdateMesh(0, mesh, index_offset, command.ElemCount); } - Material::Textures textures; + MaterialTextures textures; textures.color = textures_[command.GetTexID()].get(); - renderable->GetMaterial().UpdateTextures(textures); - Material::Params properties; + MaterialParams properties; properties.scissor[0] = command.ClipRect.x; properties.scissor[1] = height - command.ClipRect.w; properties.scissor[2] = command.ClipRect.z - command.ClipRect.x; @@ -260,7 +258,7 @@ void ImguiBridge::Update() { properties.scissor[2] = width; properties.scissor[3] = height; } - renderable->GetMaterial().UpdateParams(properties); + renderable->UpdateMaterial(properties, textures); index_offset += command.ElemCount; ++renderable_index; @@ -271,15 +269,10 @@ void ImguiBridge::Update() { void ImguiBridge::PrepareRenderables(int count) { while (renderables_.size() < count) { auto& r = renderables_.emplace_back( - std::make_unique(object_mgr_)); + std::make_unique(Renderable::Usage::Ux, object_mgr_)); r->SetCastShadows(false); r->SetReceiveShadows(false); r->SetBlendOrder(static_cast(renderables_.size())); - - Material& material = r->GetMaterial(); - DrawMode mode = DrawMode::Color; - material.SetMaterial(mode, object_mgr_->GetMaterial(ObjectManager::kUnlitUi)); - r->SetMaterialInstance(material.GetMaterialInstance(mode)); scene_view_->AddToUxScene(r.get()); } while (renderables_.size() > count) { diff --git a/src/experimental/filament/filament/material.cc b/src/experimental/filament/filament/material.cc index 2e274f93..6522bd31 100644 --- a/src/experimental/filament/filament/material.cc +++ b/src/experimental/filament/filament/material.cc @@ -20,104 +20,54 @@ #include #include #include -#include "experimental/filament/filament/draw_mode.h" #include "experimental/filament/filament/texture.h" #include "experimental/filament/filament/object_manager.h" namespace mujoco { -Material::Material(ObjectManager* object_mgr) - : object_mgr_(object_mgr) { -} - -Material::~Material() noexcept { - for (int i = 0; i < kNumDrawModes; ++i) { - if (instances_[i]) { - GetEngine()->destroy(instances_[i]); - } - } -} - -void Material::SetMaterial(DrawMode mode, filament::Material* material) { - const int index = static_cast(mode); - if (instances_[index]) { - const filament::Material* current_material = - instances_[index]->getMaterial(); - if (current_material == material) { - return; - } - - GetEngine()->destroy(instances_[index]); - instances_[index] = nullptr; - } - if (material) { - instances_[index] = material->createInstance(); - UpdateMaterialInstances(); - } -} - -filament::MaterialInstance* Material::GetMaterialInstance(DrawMode mode) { - return instances_[static_cast(mode)]; -} - -void Material::UpdateParams(const Params& params) { - params_ = params; - UpdateMaterialInstances(); -} - -void Material::UpdateTextures(const Textures& textures) { - textures_ = textures; - UpdateMaterialInstances(); -} - -void Material::UpdateMaterialInstances() { - filament::MaterialInstance* instance = - instances_[static_cast(DrawMode::Color)]; - if (instance == nullptr) { - return; - } - - if (params_.scissor[2] != 0 && params_.scissor[3] != 0) { - instance->setScissor(params_.scissor[0], params_.scissor[1], - params_.scissor[2], params_.scissor[3]); +void UpdateMaterialInstance(filament::MaterialInstance* instance, + const MaterialParams& params, + const MaterialTextures& textures, + ObjectManager* object_mgr) { + if (params.scissor[2] != 0 && params.scissor[3] != 0) { + instance->setScissor(params.scissor[0], params.scissor[1], + params.scissor[2], params.scissor[3]); } const filament::Material* material = instance->getMaterial(); if (material->hasParameter("BaseColorFactor")) { instance->setParameter("BaseColorFactor", filament::RgbaType::sRGB, - params_.color); + params.color); + } + if (material->hasParameter("SegmentationColor")) { + instance->setParameter("SegmentationColor", filament::RgbaType::LINEAR, + params.segmentation_color); } if (material->hasParameter("EmissiveFactor")) { - instance->setParameter("EmissiveFactor", params_.emissive); + instance->setParameter("EmissiveFactor", params.emissive); } if (material->hasParameter("SpecularFactor")) { - instance->setParameter("SpecularFactor", params_.specular); + instance->setParameter("SpecularFactor", params.specular); } if (material->hasParameter("GlossinessFactor")) { - instance->setParameter("GlossinessFactor", params_.glossiness); + instance->setParameter("GlossinessFactor", params.glossiness); } if (material->hasParameter("MetallicFactor")) { instance->setParameter("MetallicFactor", - params_.metallic >= 0 ? params_.metallic : 1.0f); + params.metallic >= 0 ? params.metallic : 1.0f); } if (material->hasParameter("RoughnessFactor")) { instance->setParameter("RoughnessFactor", - params_.roughness >= 0 ? params_.roughness : 1.0f); + params.roughness >= 0 ? params.roughness : 1.0f); } if (material->hasParameter("UvScale")) { - instance->setParameter("UvScale", params_.uv_scale); + instance->setParameter("UvScale", params.uv_scale); } if (material->hasParameter("UvOffset")) { - instance->setParameter("UvOffset", params_.uv_offset); + instance->setParameter("UvOffset", params.uv_offset); } if (material->hasParameter("Reflectance")) { - instance->setParameter("Reflectance", params_.reflectance); - } - - const int segmentation_index = static_cast(DrawMode::Segmentation); - if (instances_[segmentation_index]) { - instances_[segmentation_index]->setParameter("BaseColorFactor", - params_.segmentation_color); + instance->setParameter("Reflectance", params.reflectance); } // All textures use the same default sampler. @@ -135,19 +85,20 @@ void Material::UpdateMaterialInstances() { if (texture != nullptr) { instance->setParameter(name, texture->GetFilamentTexture(), sampler); } else { - instance->setParameter(name, object_mgr_->GetFallbackTexture(role), sampler); + instance->setParameter(name, object_mgr->GetFallbackTexture(role), + sampler); } } }; - TrySetTexture("BaseColor", textures_.color, mjTEXROLE_RGB); - TrySetTexture("Normal", textures_.normal, mjTEXROLE_NORMAL); - TrySetTexture("Metallic", textures_.metallic, mjTEXROLE_METALLIC); - TrySetTexture("Roughness", textures_.roughness, mjTEXROLE_ROUGHNESS); - TrySetTexture("Occlusion", textures_.occlusion, mjTEXROLE_OCCLUSION); - TrySetTexture("ORM", textures_.orm, mjTEXROLE_ORM); - TrySetTexture("Emissive", textures_.emissive, mjTEXROLE_EMISSIVE); - TrySetTexture("Reflection", textures_.reflection, mjTEXROLE_USER); + TrySetTexture("BaseColor", textures.color, mjTEXROLE_RGB); + TrySetTexture("Normal", textures.normal, mjTEXROLE_NORMAL); + TrySetTexture("Metallic", textures.metallic, mjTEXROLE_METALLIC); + TrySetTexture("Roughness", textures.roughness, mjTEXROLE_ROUGHNESS); + TrySetTexture("Occlusion", textures.occlusion, mjTEXROLE_OCCLUSION); + TrySetTexture("ORM", textures.orm, mjTEXROLE_ORM); + TrySetTexture("Emissive", textures.emissive, mjTEXROLE_EMISSIVE); + TrySetTexture("Reflection", textures.reflection, mjTEXROLE_USER); } } // namespace mujoco diff --git a/src/experimental/filament/filament/material.h b/src/experimental/filament/filament/material.h index cf5854f6..339b5b5b 100644 --- a/src/experimental/filament/filament/material.h +++ b/src/experimental/filament/filament/material.h @@ -20,82 +20,48 @@ #include #include #include -#include "experimental/filament/filament/draw_mode.h" #include "experimental/filament/filament/texture.h" #include "experimental/filament/filament/object_manager.h" namespace mujoco { -class Material { - public: - // The textures that can be assigned to the drawable's material. - struct Textures { - const Texture* color = nullptr; - const Texture* normal = nullptr; - const Texture* metallic = nullptr; - const Texture* roughness = nullptr; - const Texture* occlusion = nullptr; - const Texture* orm = nullptr; - const Texture* emissive = nullptr; - const Texture* reflection = nullptr; - }; - - // The parameters that can be applied to the drawable's material. - struct Params { - filament::math::float4 color = {1, 1, 1, 1}; - filament::math::float4 segmentation_color = {1, 1, 1, 1}; - filament::math::float2 tex_repeat = {1, 1}; - filament::math::float3 uv_scale = {1, 1, 1}; - filament::math::float3 uv_offset = {0, 0, 0}; - filament::math::float4 scissor = {0, 0, 0, 0}; - float specular = -1.0f; - float glossiness = -1.0f; - float metallic = -1.0f; - float roughness = -1.0f; - float emissive = -1.0f; - float reflectance = 0.0f; - bool tex_uniform = false; - bool reflective = false; - }; - - explicit Material(ObjectManager* object_mgr); - ~Material() noexcept; - - Material(const Material&) = delete; - Material& operator=(const Material&) = delete; - - // Assigns a material to the draw mode. - void SetMaterial(DrawMode mode, filament::Material* material); - - // Updates the parameters for the material. - void UpdateParams(const Params& params); - - // Updates the textures for the material. - void UpdateTextures(const Textures& textures); - - // Returns the current material parameters. - const Params& GetParams() const { return params_; } - - // Returns the current material textures. - const Textures& GetTextures() const { return textures_; } - - // Returns the material instance assigned to the draw mode. - filament::MaterialInstance* GetMaterialInstance(DrawMode mode); - - // Returns the filament Engine managing the material. - filament::Engine* GetEngine() const { return object_mgr_->GetEngine(); } - - private: - // Updates the material instances based on the currently set parameters and - // textures. - void UpdateMaterialInstances(); - - ObjectManager* object_mgr_; - filament::MaterialInstance* instances_[kNumDrawModes] = {nullptr}; - Params params_; - Textures textures_; +// The textures that can be assigned to the drawable's material. +struct MaterialTextures { + const Texture* color = nullptr; + const Texture* normal = nullptr; + const Texture* metallic = nullptr; + const Texture* roughness = nullptr; + const Texture* occlusion = nullptr; + const Texture* orm = nullptr; + const Texture* emissive = nullptr; + const Texture* reflection = nullptr; }; +// The parameters that can be applied to the drawable's material. +struct MaterialParams { + filament::math::float4 color = {1, 1, 1, 1}; + filament::math::float4 segmentation_color = {1, 1, 1, 1}; + filament::math::float2 tex_repeat = {1, 1}; + filament::math::float3 uv_scale = {1, 1, 1}; + filament::math::float3 uv_offset = {0, 0, 0}; + filament::math::float4 scissor = {0, 0, 0, 0}; + float specular = -1.0f; + float glossiness = -1.0f; + float metallic = -1.0f; + float roughness = -1.0f; + float emissive = -1.0f; + float reflectance = 0.0f; + bool tex_uniform = false; + bool reflective = false; +}; + +// Updates the material instances based on the currently set parameters and +// textures. +void UpdateMaterialInstance(filament::MaterialInstance* instance, + const MaterialParams& params, + const MaterialTextures& textures, + ObjectManager* object_mgr); + } // namespace mujoco #endif // MUJOCO_SRC_EXPERIMENTAL_FILAMENT_FILAMENT_MATERIAL_H_ diff --git a/src/experimental/filament/filament/renderable.cc b/src/experimental/filament/filament/renderable.cc index cf4857fa..6a3da110 100644 --- a/src/experimental/filament/filament/renderable.cc +++ b/src/experimental/filament/filament/renderable.cc @@ -14,26 +14,36 @@ #include "experimental/filament/filament/renderable.h" +#include #include #include #include +#include #include #include #include #include +#include "experimental/filament/filament/draw_mode.h" #include "experimental/filament/filament/material.h" #include "experimental/filament/filament/mesh.h" #include "experimental/filament/filament/object_manager.h" namespace mujoco { -Renderable::Renderable(ObjectManager* object_mgr) : material_(object_mgr) {} +Renderable::Renderable(Usage usage, ObjectManager* object_mgr) + : usage_(usage), object_mgr_(object_mgr) {} Renderable::~Renderable() noexcept { while (!entities_.empty()) { RemoveLastEntity(); } + for (int i = 0; i < kNumDrawModes; ++i) { + if (instances_[i] != nullptr) { + GetEngine()->destroy(instances_[i]); + instances_[i] = nullptr; + } + } } void Renderable::RemoveLastEntity() { @@ -103,8 +113,8 @@ void Renderable::AppendEntity(const MeshInfo& mesh_info) { } else { builder.culling(false); } - if (material_instance_) { - builder.material(0, material_instance_); + if (instances_[static_cast(draw_mode_)] != nullptr) { + builder.material(0, instances_[static_cast(draw_mode_)]); } builder.castShadows(cast_shadows_); builder.receiveShadows(receive_shadows_); @@ -191,15 +201,67 @@ void Renderable::RemoveFromScene(filament::Scene* scene) { assigned_scene_ = nullptr; } -void Renderable::SetMaterialInstance(filament::MaterialInstance* instance) { - if (instance != material_instance_) { +void Renderable::UpdateMaterial(const MaterialParams& params, + const MaterialTextures& textures) { + params_ = params; + textures_ = textures; + + AssignMaterial(DrawMode::Color, GetColorMaterialType()); + if (usage_ == Usage::SceneObject) { + AssignMaterial(DrawMode::Depth, ObjectManager::kUnlitDepth); + AssignMaterial(DrawMode::Segmentation, ObjectManager::kUnlitSegmentation); + } + + for (int i = 0; i < kNumDrawModes; ++i) { + if (instances_[i]) { + UpdateMaterialInstance(instances_[i], params_, textures_, object_mgr_); + } + } + SetDrawMode(draw_mode_); +} + +void Renderable::AssignMaterial(DrawMode mode, + ObjectManager::MaterialType material_type) { + const int index = static_cast(mode); + + filament::Material* material = object_mgr_->GetMaterial(material_type); + if (instances_[index]) { + if (instances_[index]->getMaterial() == material) { + // The correct material is already assigned, do nothing. + return; + } else { + GetEngine()->destroy(instances_[index]); + instances_[index] = nullptr; + } + } + if (material) { + instances_[index] = material->createInstance(); + } +} + +const MaterialParams& Renderable::GetMaterialParams() const { + return params_; +} + +const MaterialTextures& Renderable::GetMaterialTextures() const { + return textures_; +} + +void Renderable::SetDrawMode(DrawMode mode) { + // Only SceneObjects support non-color draw modes. + if (usage_ != Usage::SceneObject) { + mode = DrawMode::Color; + } + + filament::MaterialInstance* instance = instances_[static_cast(mode)]; + if (instance) { filament::RenderableManager& rm = GetEngine()->getRenderableManager(); for (utils::Entity& entity : entities_) { filament::RenderableManager::Instance ri = rm.getInstance(entity); rm.setMaterialInstanceAt(ri, 0, instance); } - material_instance_ = instance; } + draw_mode_ = mode; } std::uint8_t Renderable::SetLayerMask(std::uint8_t mask) { @@ -284,8 +346,74 @@ void Renderable::SetWireframe(bool wireframe) { } } -Material& Renderable::GetMaterial() { return material_; } -filament::Engine* Renderable::GetEngine() { return material_.GetEngine(); } +ObjectManager::MaterialType Renderable::GetColorMaterialType() const { + if (usage_ == Usage::DecorLines) { + return ObjectManager::kUnlitLine; + } else if (usage_ == Usage::Decor) { + return ObjectManager::kUnlitSegmentation; + } else if (usage_ == Usage::Ux) { + return ObjectManager::kUnlitUi; + } else if (textures_.orm) { + return ObjectManager::kPbrPacked; + } else if (textures_.metallic) { + return ObjectManager::kPbr; + } else if (textures_.roughness) { + return ObjectManager::kPbr; + } else if (params_.metallic >= 0) { + return ObjectManager::kPbr; + } else if (params_.roughness >= 0) { + return ObjectManager::kPbr; + } + + // Check to see if we're dealing with a mesh with texture coordinates. + // `data_id` is the id of the mesh in model (i.e. the geom has mesh + // geometry) and `mesh_texcoordadr` stores the address of the mesh uvs if + // it has them. + bool has_texcoords = false; + if (!meshes_.empty()) { + const auto attribs = meshes_[0].mesh->GetVertexAttributes(); + auto it = std::find(attribs.begin(), attribs.end(), + filament::VertexAttribute::UV0); + has_texcoords = (it != attribs.end()); + } + + if (textures_.color == nullptr) { + if (params_.color.a < 1.0f) { + return ObjectManager::kPhongColorFade; + } else if (params_.reflective) { + return ObjectManager::kPhongColorReflect; + } else { + return ObjectManager::kPhongColor; + } + } else if (textures_.color->GetFilamentTexture()->getTarget() == + filament::Texture::Sampler::SAMPLER_CUBEMAP) { + if (params_.color.a < 1.0f) { + return ObjectManager::kPhongCubeFade; + } else if (params_.reflective) { + return ObjectManager::kPhongCubeReflect; + } else { + return ObjectManager::kPhongCube; + } + } else if (has_texcoords) { + if (params_.color.a < 1.0f) { + return ObjectManager::kPhong2dUvFade; + } else if (params_.reflective) { + return ObjectManager::kPhong2dUvReflect; + } else { + return ObjectManager::kPhong2dUv; + } + } else { + if (params_.color.a < 1.0f) { + return ObjectManager::kPhong2dFade; + } else if (params_.reflective) { + return ObjectManager::kPhong2dReflect; + } else { + return ObjectManager::kPhong2d; + } + } +} + +filament::Engine* Renderable::GetEngine() { return object_mgr_->GetEngine(); } } // namespace mujoco diff --git a/src/experimental/filament/filament/renderable.h b/src/experimental/filament/filament/renderable.h index 5dc3b87f..dbe03498 100644 --- a/src/experimental/filament/filament/renderable.h +++ b/src/experimental/filament/filament/renderable.h @@ -21,6 +21,7 @@ #include #include #include +#include "experimental/filament/filament/draw_mode.h" #include "experimental/filament/filament/material.h" #include "experimental/filament/filament/mesh.h" #include "experimental/filament/filament/object_manager.h" @@ -37,11 +38,19 @@ namespace mujoco { // assigns the same material instance to all of them. class Renderable { public: + // How the material is to be used for rendering. + enum class Usage { + SceneObject, + Decor, + DecorLines, + Ux, + }; + // Default filament values for priority and layer mask. static constexpr std::uint8_t kDefaultPriority = 4; static constexpr std::uint8_t kDefaultLayerMask = 0x01; - explicit Renderable(ObjectManager* object_mgr); + Renderable(Usage usage, ObjectManager* object_mgr); ~Renderable() noexcept; Renderable(const Renderable&) = delete; @@ -95,10 +104,17 @@ class Renderable { void RemoveFromScene(filament::Scene* scene); // Sets the material instance for all managed entities. - void SetMaterialInstance(filament::MaterialInstance* material_instance); + void SetDrawMode(DrawMode mode); - // Returns the material for the renderables. - Material& GetMaterial(); + // Updates the parameters for the material. + void UpdateMaterial(const MaterialParams& params, + const MaterialTextures& textures); + + // Returns the current material parameters. + const MaterialParams& GetMaterialParams() const; + + // Returns the current material textures. + const MaterialTextures& GetMaterialTextures() const; // Returns the filament Engine managing the renderables. filament::Engine* GetEngine(); @@ -129,9 +145,17 @@ class Renderable { // Removes the last filament::Entity from the renderable. void RemoveLastEntity(); - Material material_; + void AssignMaterial(DrawMode mode, ObjectManager::MaterialType material_type); + + ObjectManager::MaterialType GetColorMaterialType() const; + + Usage usage_; + ObjectManager* object_mgr_; + filament::MaterialInstance* instances_[kNumDrawModes] = {nullptr}; + MaterialParams params_; + MaterialTextures textures_; + DrawMode draw_mode_ = DrawMode::Color; filament::Scene* assigned_scene_ = nullptr; - filament::MaterialInstance* material_instance_ = nullptr; std::vector entities_; std::vector meshes_; std::uint8_t priority_ = kDefaultPriority; diff --git a/src/experimental/filament/filament/scene_geom_util.cc b/src/experimental/filament/filament/scene_geom_util.cc index 3dba24d9..e60bacf4 100644 --- a/src/experimental/filament/filament/scene_geom_util.cc +++ b/src/experimental/filament/filament/scene_geom_util.cc @@ -31,7 +31,6 @@ #include #include #include -#include "experimental/filament/filament/draw_mode.h" #include "experimental/filament/filament/material.h" #include "experimental/filament/filament/math_util.h" #include "experimental/filament/filament/mesh.h" @@ -323,12 +322,10 @@ static void UpdateGeomMaterial(Renderable& renderable, const mjvGeom& geom, ObjectManager* object_mgr, const float headpos[3]) { const mjModel* model = model_objs->GetModel(); - Material& material = renderable.GetMaterial(); const bool use_segid_color = scene->flags[mjRND_IDCOLOR]; const bool enable_reflection = scene->flags[mjRND_REFLECTION]; - - Material::Params params; + MaterialParams params; params.color = ReadFloat4(geom.rgba); if (geom.type == mjGEOM_PLANE) { if (IsBehind(headpos, geom.pos, geom.mat)) { @@ -347,7 +344,7 @@ static void UpdateGeomMaterial(Renderable& renderable, const mjvGeom& geom, renderable.SetReceiveShadows(false); } - Material::Textures textures; + MaterialTextures textures; if (geom.matid >= 0) { textures.color = model_objs->GetTexture(geom.matid, mjTEXROLE_RGB); textures.normal = model_objs->GetTexture(geom.matid, mjTEXROLE_NORMAL); @@ -358,79 +355,6 @@ static void UpdateGeomMaterial(Renderable& renderable, const mjvGeom& geom, model_objs->GetTexture(geom.matid, mjTEXROLE_ROUGHNESS); textures.occlusion = model_objs->GetTexture(geom.matid, mjTEXROLE_OCCLUSION); - material.UpdateTextures(textures); - } - - ObjectManager::MaterialType material_type = ObjectManager::kNumMaterials; - if (geom.type == mjGEOM_LINE || geom.type == mjGEOM_LINEBOX) { - material_type = ObjectManager::kUnlitLine; - } else if (geom.category == mjCAT_DECOR) { - material_type = ObjectManager::kUnlitSegmentation; - } else { - bool material_assigned = false; - if (geom.matid >= 0) { - material_assigned = true; - if (textures.orm) { - material_type = ObjectManager::kPbrPacked; - } else if (textures.metallic) { - material_type = ObjectManager::kPbr; - } else if (textures.roughness) { - material_type = ObjectManager::kPbr; - } else if (model->mat_metallic[geom.matid] >= 0) { - material_type = ObjectManager::kPbr; - } else if (model->mat_roughness[geom.matid] >= 0) { - material_type = ObjectManager::kPbr; - } else { - material_assigned = false; - } - } - - if (!material_assigned) { - // Check to see if we're dealing with a mesh with texture coordinates. - // `data_id` is the id of the mesh in model (i.e. the geom has mesh - // geometry) and `mesh_texcoordadr` stores the address of the mesh uvs if - // it has them. - bool has_texcoords = false; - if ((geom.type == mjGEOM_MESH || geom.type == mjGEOM_SDF) && - geom.dataid >= 0 && model->mesh_texcoordadr[geom.dataid / 2] >= 0) { - has_texcoords = true; - } - - if (textures.color == nullptr) { - if (params.color.a < 1.0f) { - material_type = ObjectManager::kPhongColorFade; - } else if (params.reflective) { - material_type = ObjectManager::kPhongColorReflect; - } else { - material_type = ObjectManager::kPhongColor; - } - } else if (textures.color->GetFilamentTexture()->getTarget() == - filament::Texture::Sampler::SAMPLER_CUBEMAP) { - if (params.color.a < 1.0f) { - material_type = ObjectManager::kPhongCubeFade; - } else if (params.reflective) { - material_type = ObjectManager::kPhongCubeReflect; - } else { - material_type = ObjectManager::kPhongCube; - } - } else if (has_texcoords) { - if (params.color.a < 1.0f) { - material_type = ObjectManager::kPhong2dUvFade; - } else if (params.reflective) { - material_type = ObjectManager::kPhong2dUvReflect; - } else { - material_type = ObjectManager::kPhong2dUv; - } - } else { - if (params.color.a < 1.0f) { - material_type = ObjectManager::kPhong2dFade; - } else if (params.reflective) { - material_type = ObjectManager::kPhong2dReflect; - } else { - material_type = ObjectManager::kPhong2d; - } - } - } } params.reflectance = geom.reflectance; @@ -532,20 +456,21 @@ static void UpdateGeomMaterial(Renderable& renderable, const mjvGeom& geom, params.emissive *= model_objs->GetEmissiveMultiplier(); params.specular *= model_objs->GetSpecularMultiplier(); params.glossiness *= model_objs->GetShininessMultiplier(); - material.UpdateParams(params); - material.SetMaterial(DrawMode::Color, object_mgr->GetMaterial(material_type)); - material.SetMaterial(DrawMode::Depth, - object_mgr->GetMaterial(ObjectManager::kUnlitDepth)); - material.SetMaterial( - DrawMode::Segmentation, - object_mgr->GetMaterial(ObjectManager::kUnlitSegmentation)); + renderable.UpdateMaterial(params, textures); } std::unique_ptr CreateGeomRenderable( const mjvGeom& geom, const mjvScene* scene, ObjectManager* object_mgr, ModelObjects* model_objs, const float headpos[3]) { - auto renderable = std::make_unique(object_mgr); + Renderable::Usage usage = Renderable::Usage::SceneObject; + if (geom.type == mjGEOM_LINE || geom.type == mjGEOM_LINEBOX) { + usage = Renderable::Usage::DecorLines; + } else if (geom.category == mjCAT_DECOR) { + usage = Renderable::Usage::Decor; + } + + auto renderable = std::make_unique(usage, object_mgr); // The order of these calls is important. e.g. We need to create the filament // renderable entities before we can set their transform. diff --git a/src/experimental/filament/filament/scene_view.cc b/src/experimental/filament/filament/scene_view.cc index 1f4c4009..d6832f6f 100644 --- a/src/experimental/filament/filament/scene_view.cc +++ b/src/experimental/filament/filament/scene_view.cc @@ -208,7 +208,7 @@ void SceneView::RemoveFromScene(Light* light) { void SceneView::AddToScene(Renderable* renderable) { if (renderables_.insert(renderable).second) { renderable->AddToScene(scene_); - if (renderable->GetMaterial().GetParams().reflective) { + if (renderable->GetMaterialParams().reflective) { AddReflectiveRenderable(renderable); } } @@ -261,8 +261,7 @@ void SceneView::Render(filament::Renderer* renderer, SetupCamera(request.camera, viewport, camera_); for (auto& iter : renderables_) { - Material& material = iter->GetMaterial(); - iter->SetMaterialInstance(material.GetMaterialInstance(request.draw_mode)); + iter->SetDrawMode(request.draw_mode); } filament::View* view = views_[static_cast(request.draw_mode)]; @@ -336,10 +335,9 @@ void SceneView::AddReflectiveRenderable(Renderable* renderable) { auto& target = reflect_targets_[index]; target->Prepare(viewport.width, viewport.height); - Material& material = renderable->GetMaterial(); - Material::Textures textures = material.GetTextures(); + MaterialTextures textures = renderable->GetMaterialTextures(); textures.reflection = target->GetColorTexture(); - material.UpdateTextures(textures); + renderable->UpdateMaterial(renderable->GetMaterialParams(), textures); } void SceneView::SetColorGradingOptions(const ColorGradingOptions& opts) {