From b0c48ba846b07bd5c767bba65be59c532a210496 Mon Sep 17 00:00:00 2001 From: Haroon Qureshi Date: Wed, 18 Mar 2026 05:04:06 -0700 Subject: [PATCH] Planes should not receive shadows when rendered from behind. Also refactors Renderables a bit to allow for additional use-cases. PiperOrigin-RevId: 885527587 Change-Id: I4b17e097256de0356151a6d087bc01f11e3071b7 --- .../filament/filament/drawable.cc | 12 ++- src/experimental/filament/filament/drawable.h | 1 - .../filament/filament/renderables.cc | 78 +++++++++++-------- .../filament/filament/renderables.h | 30 ++++--- 4 files changed, 74 insertions(+), 47 deletions(-) diff --git a/src/experimental/filament/filament/drawable.cc b/src/experimental/filament/filament/drawable.cc index cfddafde..3350e59a 100644 --- a/src/experimental/filament/filament/drawable.cc +++ b/src/experimental/filament/filament/drawable.cc @@ -88,7 +88,8 @@ static bool IsBehind(const mjtNum* headpos, const float* pos, const float* mat) Drawable::Drawable(ObjectManager* object_mgr, const mjvGeom& geom) : material_(object_mgr), renderables_(object_mgr->GetEngine()) { if (geom.category == mjCAT_DECOR) { - renderables_.DisableShadows(); + renderables_.SetCastShadows(false); + renderables_.SetReceiveShadows(false); } switch ((mjtGeom)geom.type) { @@ -346,8 +347,13 @@ void Drawable::UpdateMaterial(const mjvGeom& geom, bool use_segid_color, const mjModel* model = object_mgr->GetModel(); float4 color = ReadFloat4(geom.rgba); - if (geom.type == mjGEOM_PLANE && IsBehind(headpos, geom.pos, geom.mat)) { - color[3] *= 0.3; + if (geom.type == mjGEOM_PLANE) { + if (IsBehind(headpos, geom.pos, geom.mat)) { + color[3] *= 0.3; + renderables_.SetReceiveShadows(false); + } else { + renderables_.SetReceiveShadows(true); + } } Material::Textures textures; diff --git a/src/experimental/filament/filament/drawable.h b/src/experimental/filament/filament/drawable.h index 9e97af81..66788580 100644 --- a/src/experimental/filament/filament/drawable.h +++ b/src/experimental/filament/filament/drawable.h @@ -51,7 +51,6 @@ class Drawable { // beginFrame/endFrame. void SetDrawMode(Material::DrawMode mode); - private: void AddMesh(int data_id); void AddHeightField(int hfield_id); diff --git a/src/experimental/filament/filament/renderables.cc b/src/experimental/filament/filament/renderables.cc index 77181077..0eeb0c87 100644 --- a/src/experimental/filament/filament/renderables.cc +++ b/src/experimental/filament/filament/renderables.cc @@ -14,6 +14,7 @@ #include "experimental/filament/filament/renderables.h" +#include #include #include @@ -107,8 +108,9 @@ utils::Entity Renderables::CreateEntity(const FilamentBuffers& buffers) { builder.boundingBox(buffers.bounds) .culling(false) .castShadows(cast_shadows_) - .receiveShadows(true) - .layerMask(1, visible_ ? 1 : 0) + .receiveShadows(receive_shadows_) + .layerMask(0xff, layer_mask_) + .priority(priority_) .screenSpaceContactShadows(true); builder.build(*engine_, entity); @@ -180,23 +182,47 @@ void Renderables::SetMaterialInstance( } } -void Renderables::Hide() { - if (visible_) { +void Renderables::SetLayerMask(std::uint8_t mask) { + if (mask != layer_mask_) { + layer_mask_ = mask; + filament::RenderableManager& rm = engine_->getRenderableManager(); for (utils::Entity& entity : entities_) { - rm.setLayerMask(rm.getInstance(entity), 1, 0); + rm.setLayerMask(rm.getInstance(entity), 0xff, layer_mask_); } - visible_ = false; } } -void Renderables::Show() { - if (!visible_) { +void Renderables::SetPriority(std::uint8_t priority) { + if (priority != priority_) { + priority_ = priority; + filament::RenderableManager& rm = engine_->getRenderableManager(); for (utils::Entity& entity : entities_) { - rm.setLayerMask(rm.getInstance(entity), 1, 1); + rm.setPriority(rm.getInstance(entity), priority_); + } + } +} + +void Renderables::SetCastShadows(bool cast_shadows) { + if (cast_shadows_ != cast_shadows) { + cast_shadows_ = cast_shadows; + + filament::RenderableManager& rm = engine_->getRenderableManager(); + for (utils::Entity& entity : entities_) { + rm.setCastShadows(rm.getInstance(entity), cast_shadows_); + } + } +} + +void Renderables::SetReceiveShadows(bool receive_shadows) { + if (receive_shadows_ != receive_shadows) { + receive_shadows_ = receive_shadows; + + filament::RenderableManager& rm = engine_->getRenderableManager(); + for (utils::Entity& entity : entities_) { + rm.setReceiveShadows(rm.getInstance(entity), receive_shadows_); } - visible_ = true; } } @@ -204,29 +230,19 @@ void Renderables::SetWireframe(bool wireframe) { static constexpr auto kWireframeType = filament::RenderableManager::PrimitiveType::LINES; - if (wireframe == wireframe_) { - return; - } - wireframe_ = wireframe; + if (wireframe != wireframe_) { + wireframe_ = wireframe; - filament::RenderableManager& rm = engine_->getRenderableManager(); - for (int i = 0; i < entities_.size(); ++i) { - utils::Entity& entity = entities_[i]; - FilamentBuffers& buffers = owned_buffers_[i].buffers; - rm.setGeometryAt(rm.getInstance(entity), 0, - wireframe ? kWireframeType : buffers.type, - buffers.vertex_buffer, buffers.index_buffer, 0, - buffers.index_buffer->getIndexCount()); + filament::RenderableManager& rm = engine_->getRenderableManager(); + for (int i = 0; i < entities_.size(); ++i) { + utils::Entity& entity = entities_[i]; + FilamentBuffers& buffers = owned_buffers_[i].buffers; + rm.setGeometryAt(rm.getInstance(entity), 0, + wireframe_ ? kWireframeType : buffers.type, + buffers.vertex_buffer, buffers.index_buffer, 0, + buffers.index_buffer->getIndexCount()); + } } } - -void Renderables::DisableShadows() { - filament::RenderableManager& rm = engine_->getRenderableManager(); - for (utils::Entity& entity : entities_) { - rm.setCastShadows(rm.getInstance(entity), false); - } - cast_shadows_ = false; -} - } // namespace mujoco diff --git a/src/experimental/filament/filament/renderables.h b/src/experimental/filament/filament/renderables.h index ddb13fb5..bd6b3602 100644 --- a/src/experimental/filament/filament/renderables.h +++ b/src/experimental/filament/filament/renderables.h @@ -15,8 +15,8 @@ #ifndef MUJOCO_SRC_EXPERIMENTAL_FILAMENT_FILAMENT_RENDERABLES_H_ #define MUJOCO_SRC_EXPERIMENTAL_FILAMENT_FILAMENT_RENDERABLES_H_ +#include #include -#include #include #include @@ -29,6 +29,10 @@ namespace mujoco { // Manages a collection of related filament Renderable Entities. class Renderables { public: + // Default filament values for priority and layer mask. + static constexpr std::uint8_t kDefaultPriority = 4; + static constexpr std::uint8_t kDefaultLayerMask = 0x01; + Renderables(filament::Engine* engine); ~Renderables() noexcept; @@ -53,16 +57,19 @@ class Renderables { int GetNumEntities() const { return entities_.size(); } // Hides all managed entities. - void Hide(); + void SetLayerMask(std::uint8_t mask); - // Shows all managed entities. - void Show(); - - // Returns true if the entities are visible. - bool IsVisible() const { return visible_; } + // Sets the priority of all managed entities. + void SetPriority(std::uint8_t priority); // Disables the renderables from casting shadows. - void DisableShadows(); + void SetCastShadows(bool cast_shadows); + + // Disables the renderables from receiving shadows. + void SetReceiveShadows(bool receive_shadows); + + // If true, forces all entities to be rendered as lines. + void SetWireframe(bool wireframe); // Adds all managed entities to the given filament Scene. void AddToScene(filament::Scene* scene); @@ -73,9 +80,6 @@ class Renderables { // Sets the material instance for all managed entities. void SetMaterialInstance(filament::MaterialInstance* material_instance); - // If true, forces all entities to be rendered as lines. - void SetWireframe(bool wireframe); - // Returns the filament Engine managing the entities in this collection. filament::Engine* GetEngine() { return engine_; } @@ -96,9 +100,11 @@ class Renderables { filament::MaterialInstance* material_instance_ = nullptr; std::vector entities_; std::vector owned_buffers_; - bool visible_ = true; + std::uint8_t priority_ = kDefaultPriority; + std::uint8_t layer_mask_ = kDefaultLayerMask; bool wireframe_ = false; bool cast_shadows_ = true; + bool receive_shadows_ = true; }; } // namespace mujoco