diff --git a/src/experimental/filament/filament/drawable.cc b/src/experimental/filament/filament/drawable.cc index 53c91144..2db25b95 100644 --- a/src/experimental/filament/filament/drawable.cc +++ b/src/experimental/filament/filament/drawable.cc @@ -86,10 +86,20 @@ static bool IsBehind(const mjtNum* headpos, const float* pos, const float* mat) } Drawable::Drawable(ObjectManager* object_mgr, ModelObjects* model_objects, - const mjvGeom& geom) - : material_(object_mgr), + const mjvGeom& geom, + const Material::Textures* fallback_textures) + : material_(object_mgr->GetEngine()), model_objs_(model_objects), + object_mgr_(object_mgr), renderables_(object_mgr->GetEngine()) { + material_.SetMaterial( + Material::DrawMode::kDepth, + object_mgr_->GetMaterial(ObjectManager::kUnlitDepth)); + material_.SetMaterial( + Material::DrawMode::kSegmentation, + object_mgr_->GetMaterial(ObjectManager::kUnlitSegmentation)); + material_.SetFallbackTextures(fallback_textures); + if (geom.category == mjCAT_DECOR) { renderables_.SetCastShadows(false); renderables_.SetReceiveShadows(false); @@ -229,7 +239,9 @@ void Drawable::SetDrawMode(Material::DrawMode mode) { } void Drawable::UpdateReflectionTexture(const Texture* tex) { - material_.UpdateReflectionTexture(tex); + Material::Textures textures = material_.GetTextures(); + textures.reflection = tex; + material_.UpdateTextures(textures); } void Drawable::SetLayerMask(std::uint8_t mask) { @@ -353,6 +365,11 @@ void Drawable::SetTransform(const mjvGeom& geom) { } } +void Drawable::SetNormalMaterial(ObjectManager::MaterialType material_type) { + filament::Material* material = object_mgr_->GetMaterial(material_type); + material_.SetMaterial(Material::DrawMode::kNormal, material); +} + void Drawable::UpdateMaterial(const mjvGeom& geom, bool use_segid_color, bool enable_reflection, const mjtNum* headpos) { const mjModel* model = model_objs_->GetModel(); @@ -385,21 +402,21 @@ void Drawable::UpdateMaterial(const mjvGeom& geom, bool use_segid_color, } if (geom.type == mjGEOM_LINE || geom.type == mjGEOM_LINEBOX) { - material_.SetNormalMaterialType(ObjectManager::kUnlitLine); + SetNormalMaterial(ObjectManager::kUnlitLine); } else { bool material_assigned = false; if (geom.matid >= 0) { material_assigned = true; if (textures.orm) { - material_.SetNormalMaterialType(ObjectManager::kPbrPacked); + SetNormalMaterial(ObjectManager::kPbrPacked); } else if (textures.metallic) { - material_.SetNormalMaterialType(ObjectManager::kPbr); + SetNormalMaterial(ObjectManager::kPbr); } else if (textures.roughness) { - material_.SetNormalMaterialType(ObjectManager::kPbr); + SetNormalMaterial(ObjectManager::kPbr); } else if (model->mat_metallic[geom.matid] >= 0) { - material_.SetNormalMaterialType(ObjectManager::kPbr); + SetNormalMaterial(ObjectManager::kPbr); } else if (model->mat_roughness[geom.matid] >= 0) { - material_.SetNormalMaterialType(ObjectManager::kPbr); + SetNormalMaterial(ObjectManager::kPbr); } else { material_assigned = false; } @@ -418,36 +435,36 @@ void Drawable::UpdateMaterial(const mjvGeom& geom, bool use_segid_color, if (textures.color == nullptr) { if (color.a < 1.0f) { - material_.SetNormalMaterialType(ObjectManager::kPhongColorFade); + SetNormalMaterial(ObjectManager::kPhongColorFade); } else if (reflective_) { - material_.SetNormalMaterialType(ObjectManager::kPhongColorReflect); + SetNormalMaterial(ObjectManager::kPhongColorReflect); } else { - material_.SetNormalMaterialType(ObjectManager::kPhongColor); + SetNormalMaterial(ObjectManager::kPhongColor); } } else if (textures.color->GetFilamentTexture()->getTarget() == filament::Texture::Sampler::SAMPLER_CUBEMAP) { if (color.a < 1.0f) { - material_.SetNormalMaterialType(ObjectManager::kPhongCubeFade); + SetNormalMaterial(ObjectManager::kPhongCubeFade); } else if (reflective_) { - material_.SetNormalMaterialType(ObjectManager::kPhongCubeReflect); + SetNormalMaterial(ObjectManager::kPhongCubeReflect); } else { - material_.SetNormalMaterialType(ObjectManager::kPhongCube); + SetNormalMaterial(ObjectManager::kPhongCube); } } else if (has_texcoords) { if (color.a < 1.0f) { - material_.SetNormalMaterialType(ObjectManager::kPhong2dUvFade); + SetNormalMaterial(ObjectManager::kPhong2dUvFade); } else if (reflective_) { - material_.SetNormalMaterialType(ObjectManager::kPhong2dUvReflect); + SetNormalMaterial(ObjectManager::kPhong2dUvReflect); } else { - material_.SetNormalMaterialType(ObjectManager::kPhong2dUv); + SetNormalMaterial(ObjectManager::kPhong2dUv); } } else { if (color.a < 1.0f) { - material_.SetNormalMaterialType(ObjectManager::kPhong2dFade); + SetNormalMaterial(ObjectManager::kPhong2dFade); } else if (reflective_) { - material_.SetNormalMaterialType(ObjectManager::kPhong2dReflect); + SetNormalMaterial(ObjectManager::kPhong2dReflect); } else { - material_.SetNormalMaterialType(ObjectManager::kPhong2d); + SetNormalMaterial(ObjectManager::kPhong2d); } } } diff --git a/src/experimental/filament/filament/drawable.h b/src/experimental/filament/filament/drawable.h index 2f2dc81e..08956903 100644 --- a/src/experimental/filament/filament/drawable.h +++ b/src/experimental/filament/filament/drawable.h @@ -34,7 +34,7 @@ namespace mujoco { class Drawable { public: Drawable(ObjectManager* object_mgr, ModelObjects* model_objects, - const mjvGeom& geom); + const mjvGeom& geom, const Material::Textures* fallback_textures); ~Drawable() noexcept = default; Drawable(const Drawable&) = delete; @@ -79,12 +79,16 @@ class Drawable { // Updates the transform of the drawable for rendering. void SetTransform(const mjvGeom& geom); + // Sets the material for the drawable. + void SetNormalMaterial(ObjectManager::MaterialType material_type); + // Updates the material parameters of the drawable for rendering. void UpdateMaterial(const mjvGeom& geom, bool use_segid_color, bool enable_reflection, const mjtNum* headpos); Material material_; ModelObjects* model_objs_ = nullptr; + ObjectManager* object_mgr_ = nullptr; Renderables renderables_; bool reflective_ = false; filament::math::mat4 transform_; diff --git a/src/experimental/filament/filament/material.cc b/src/experimental/filament/filament/material.cc index aaf9c6ba..10538d28 100644 --- a/src/experimental/filament/filament/material.cc +++ b/src/experimental/filament/filament/material.cc @@ -19,45 +19,35 @@ #include #include #include -#include -#include "experimental/filament/filament/object_manager.h" #include "experimental/filament/filament/texture.h" namespace mujoco { -Material::Material(ObjectManager* object_mgr) : object_mgr_(object_mgr) { - instances_[kDepth] = - object_mgr_->GetMaterial(ObjectManager::kUnlitDepth)->createInstance(); - instances_[kSegmentation] = - object_mgr_->GetMaterial(ObjectManager::kUnlitSegmentation) - ->createInstance(); +Material::Material(filament::Engine* engine) + : engine_(engine) { } Material::~Material() noexcept { - filament::Engine* engine = object_mgr_->GetEngine(); for (int i = 0; i < kNumDrawModes; ++i) { if (instances_[i]) { - engine->destroy(instances_[i]); + engine_->destroy(instances_[i]); } } } -void Material::SetNormalMaterialType( - ObjectManager::MaterialType material_type) { - filament::Material* material = object_mgr_->GetMaterial(material_type); - - if (instances_[kNormal]) { +void Material::SetMaterial(DrawMode mode, filament::Material* material) { + if (instances_[mode]) { const filament::Material* current_material = - instances_[kNormal]->getMaterial(); + instances_[mode]->getMaterial(); if (current_material == material) { return; } - object_mgr_->GetEngine()->destroy(instances_[kNormal]); - instances_[kNormal] = nullptr; + engine_->destroy(instances_[mode]); + instances_[mode] = nullptr; } if (material) { - instances_[kNormal] = material->createInstance(); + instances_[mode] = material->createInstance(); UpdateMaterialInstances(); } } @@ -72,9 +62,8 @@ void Material::UpdateTextures(const Textures& textures) { UpdateMaterialInstances(); } -void Material::UpdateReflectionTexture(const Texture* tex) { - textures_.reflection = tex; - UpdateMaterialInstances(); +void Material::SetFallbackTextures(const Textures* fallback_textures) { + fallback_textures_ = fallback_textures; } void Material::UpdateMaterialInstances() { @@ -130,25 +119,32 @@ void Material::UpdateMaterialInstances() { filament::TextureSampler::MinFilter::LINEAR_MIPMAP_LINEAR); auto TrySetTexture = [&](const char* name, const Texture* texture, - mjtTextureRole role) { + const Texture* fallback) { if (material->hasParameter(name)) { if (texture) { instance->setParameter(name, texture->GetFilamentTexture(), sampler); - } else { - auto* fallback = object_mgr_->GetFallbackTexture(role); + } else if (fallback) { instance->setParameter(name, fallback->GetFilamentTexture(), 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, + fallback_textures_ ? fallback_textures_->color : nullptr); + TrySetTexture("Normal", textures_.normal, + fallback_textures_ ? fallback_textures_->normal : nullptr); + TrySetTexture("Metallic", textures_.metallic, + fallback_textures_ ? fallback_textures_->metallic : nullptr); + TrySetTexture("Roughness", textures_.roughness, + fallback_textures_ ? fallback_textures_->roughness : nullptr); + TrySetTexture("Occlusion", textures_.occlusion, + fallback_textures_ ? fallback_textures_->occlusion : nullptr); + TrySetTexture("ORM", textures_.orm, + fallback_textures_ ? fallback_textures_->orm : nullptr); + TrySetTexture("Emissive", textures_.emissive, + fallback_textures_ ? fallback_textures_->emissive : nullptr); + TrySetTexture("Reflection", textures_.reflection, + fallback_textures_ ? fallback_textures_->reflection : nullptr); } } // namespace mujoco diff --git a/src/experimental/filament/filament/material.h b/src/experimental/filament/filament/material.h index b717b9c4..03d0ffb8 100644 --- a/src/experimental/filament/filament/material.h +++ b/src/experimental/filament/filament/material.h @@ -20,7 +20,6 @@ #include #include #include -#include "experimental/filament/filament/object_manager.h" #include "experimental/filament/filament/texture.h" namespace mujoco { @@ -65,24 +64,29 @@ class Material { bool tex_uniform = false; }; - Material(ObjectManager* object_mgr); + explicit Material(filament::Engine* engine); ~Material() noexcept; Material(const Material&) = delete; Material& operator=(const Material&) = delete; // Assigns a material to the draw mode. - void SetNormalMaterialType(ObjectManager::MaterialType material_type); + void SetMaterial(DrawMode mode, filament::Material* material); - // Updates the material parameters of the drawable for rendering. + // Sets the fallback textures for the material. + void SetFallbackTextures(const Textures* fallback_textures); + + // Updates the parameters for the material. void UpdateParams(const Params& params); - // Updates the material textures of the drawable for rendering. + // Updates the textures for the material. void UpdateTextures(const Textures& textures); - // Update the reflection texture. We do this separately since the reflection - // texture needs to be rendered before it can be applied to the material. - void UpdateReflectionTexture(const Texture* tex); + // 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) { @@ -94,8 +98,9 @@ class Material { // textures. void UpdateMaterialInstances(); - ObjectManager* object_mgr_ = nullptr; + filament::Engine* engine_ = nullptr; filament::MaterialInstance* instances_[kNumDrawModes] = {nullptr}; + const Textures* fallback_textures_ = nullptr; Params params_; Textures textures_; }; diff --git a/src/experimental/filament/filament/scene_bridge.cc b/src/experimental/filament/filament/scene_bridge.cc index 6b445035..89a99bc0 100644 --- a/src/experimental/filament/filament/scene_bridge.cc +++ b/src/experimental/filament/filament/scene_bridge.cc @@ -139,6 +139,15 @@ SceneBridge::SceneBridge(ObjectManager* object_mgr, const mjModel* model, ReadElement(model, "filament.fallback.environment_light_intensity", fallback_environment_light_intensity_); + fallback_textures_.color = object_mgr_->GetFallbackTexture(mjTEXROLE_RGB); + fallback_textures_.normal = object_mgr_->GetFallbackTexture(mjTEXROLE_NORMAL); + fallback_textures_.metallic = object_mgr_->GetFallbackTexture(mjTEXROLE_METALLIC); + fallback_textures_.roughness = object_mgr_->GetFallbackTexture(mjTEXROLE_ROUGHNESS); + fallback_textures_.occlusion = object_mgr_->GetFallbackTexture(mjTEXROLE_OCCLUSION); + fallback_textures_.orm = object_mgr_->GetFallbackTexture(mjTEXROLE_ORM); + fallback_textures_.emissive = object_mgr_->GetFallbackTexture(mjTEXROLE_EMISSIVE); + fallback_textures_.reflection = object_mgr_->GetFallbackTexture(mjTEXROLE_USER); + // Create an empty/black indirect light to ensure that the skybox is oriented // to respect mujoco's Z-up convention. filament::IndirectLight* empty_ibl = @@ -313,8 +322,8 @@ void SceneBridge::Update(const mjrRect& viewport, const mjvScene* scene) { } } - auto drawable = - std::make_unique(object_mgr_, model_objects_.get(), *geom); + auto drawable = std::make_unique( + object_mgr_, model_objects_.get(), *geom, &fallback_textures_); drawable->Update(model_objects_->GetModel(), scene, *geom); scene_view_->AddToScene(drawable.get()); drawables_.push_back(std::move(drawable)); diff --git a/src/experimental/filament/filament/scene_bridge.h b/src/experimental/filament/filament/scene_bridge.h index a1e56796..e3d4917d 100644 --- a/src/experimental/filament/filament/scene_bridge.h +++ b/src/experimental/filament/filament/scene_bridge.h @@ -26,6 +26,7 @@ #include #include "experimental/filament/filament/drawable.h" #include "experimental/filament/filament/light.h" +#include "experimental/filament/filament/material.h" #include "experimental/filament/filament/model_objects.h" #include "experimental/filament/filament/object_manager.h" #include "experimental/filament/filament/scene_view.h" @@ -78,6 +79,7 @@ class SceneBridge { float fallback_head_light_intensity_ = 0.f; float fallback_scene_light_intensity_ = 80'000.f; float fallback_environment_light_intensity_ = 5'000.f; + Material::Textures fallback_textures_; }; } // namespace mujoco