diff --git a/libraries/render-utils/src/RenderShadowTask.cpp b/libraries/render-utils/src/RenderShadowTask.cpp index 2e5b7132e4..02f6d70e43 100644 --- a/libraries/render-utils/src/RenderShadowTask.cpp +++ b/libraries/render-utils/src/RenderShadowTask.cpp @@ -264,7 +264,7 @@ void RenderShadowCascadeSetup::run(const render::RenderContextPointer& renderCon const auto globalShadow = lightStage->getCurrentKeyShadow(); if (globalShadow && _cascadeIndexgetCascadeCount()) { - output.edit1() = ItemFilter::Builder::visibleWorldItems().withTypeShape().withOpaque().withoutLayered(); + output.edit1() = ItemFilter::Builder::visibleWorldItems(0x08).withTypeShape().withOpaque().withoutLayered(); globalShadow->setKeylightCascadeFrustum(_cascadeIndex, args->getViewFrustum(), SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR); diff --git a/libraries/render-utils/src/RenderViewTask.cpp b/libraries/render-utils/src/RenderViewTask.cpp index dc6c66e058..434e069d28 100644 --- a/libraries/render-utils/src/RenderViewTask.cpp +++ b/libraries/render-utils/src/RenderViewTask.cpp @@ -14,7 +14,7 @@ #include "RenderDeferredTask.h" #include "RenderForwardTask.h" -void RenderViewTask::build(JobModel& task, const render::Varying& input, render::Varying& output, render::CullFunctor cullFunctor, bool isDeferred) { +void RenderViewTask::build(JobModel& task, const render::Varying& input, render::Varying& output, render::CullFunctor cullFunctor, bool isDeferred, uint8_t visibilityMask) { // auto items = input.get(); // Shadows use an orthographic projection because they are linked to sunlights @@ -30,7 +30,7 @@ void RenderViewTask::build(JobModel& task, const render::Varying& input, render: return true; }); - const auto items = task.addJob("FetchCullSort", cullFunctor); + const auto items = task.addJob("FetchCullSort", cullFunctor, visibilityMask); assert(items.canCast()); if (isDeferred) { diff --git a/libraries/render-utils/src/RenderViewTask.h b/libraries/render-utils/src/RenderViewTask.h index eb61f56eab..9c2bbe0281 100644 --- a/libraries/render-utils/src/RenderViewTask.h +++ b/libraries/render-utils/src/RenderViewTask.h @@ -23,7 +23,7 @@ public: RenderViewTask() {} - void build(JobModel& task, const render::Varying& inputs, render::Varying& outputs, render::CullFunctor cullFunctor, bool isDeferred); + void build(JobModel& task, const render::Varying& inputs, render::Varying& outputs, render::CullFunctor cullFunctor, bool isDeferred, uint8_t visibilityMask = 0xFF); }; diff --git a/libraries/render/src/render/Item.h b/libraries/render/src/render/Item.h index 77f5910b9e..c2f1312ec2 100644 --- a/libraries/render/src/render/Item.h +++ b/libraries/render/src/render/Item.h @@ -46,7 +46,10 @@ public: VIEW_SPACE, // Transformed in view space, and not in world space DYNAMIC, // Dynamic and bound will change unlike static item DEFORMED, // Deformed within bound, not solid - INVISIBLE, // Visible or not? could be just here to cast shadow + INVISIBLE0, // Visible or not in this mask index? + INVISIBLE1, // Visible or not in this mask index? + INVISIBLE2, // Visible or not in this mask index? + INVISIBLE3, // Visible or not in this mask index? SHADOW_CASTER, // Item cast shadows PICKABLE, // Item can be picked/selected LAYERED, // Item belongs to one of the layers different from the default layer @@ -57,6 +60,12 @@ public: }; typedef std::bitset Flags; + // VISIBLE MASK is defined from several bits in the Key. + // An Item can be visible in some mask bits and not other allowing for per view rendering + // Beware that the visibility mask is the oposite of what stored in the key vals. + const static uint8_t NUM_VISIBLE_MASK_INDICES{ 4 }; + const static uint8_t VISIBLE_MASK_ALL{ 0x0F }; + // The key is the Flags Flags _flags; @@ -82,7 +91,7 @@ public: Builder& withViewSpace() { _flags.set(VIEW_SPACE); return (*this); } Builder& withDynamic() { _flags.set(DYNAMIC); return (*this); } Builder& withDeformed() { _flags.set(DEFORMED); return (*this); } - Builder& withInvisible() { _flags.set(INVISIBLE); return (*this); } + Builder& withInvisible(uint8_t maskIndex = 0) { _flags.set(INVISIBLE0 + maskIndex); return (*this); } Builder& withShadowCaster() { _flags.set(SHADOW_CASTER); return (*this); } Builder& withPickable() { _flags.set(PICKABLE); return (*this); } Builder& withLayered() { _flags.set(LAYERED); return (*this); } @@ -111,8 +120,10 @@ public: bool isRigid() const { return !_flags[DEFORMED]; } bool isDeformed() const { return _flags[DEFORMED]; } - bool isVisible() const { return !_flags[INVISIBLE]; } - bool isInvisible() const { return _flags[INVISIBLE]; } + bool isVisible(uint8_t maskIndex) const { return !_flags[INVISIBLE0 + maskIndex]; } + bool isInvisible(uint8_t maskIndex) const { return _flags[INVISIBLE0 + maskIndex]; } + uint8_t getVisibleMask() const { return (~(_flags.to_ulong() >> INVISIBLE0) & VISIBLE_MASK_ALL);} + bool isVisibleMask(uint8_t mask) const { return getVisibleMask() & mask; } bool isShadowCaster() const { return _flags[SHADOW_CASTER]; } @@ -171,8 +182,18 @@ public: Builder& withRigid() { _value.reset(ItemKey::DEFORMED); _mask.set(ItemKey::DEFORMED); return (*this); } Builder& withDeformed() { _value.set(ItemKey::DEFORMED); _mask.set(ItemKey::DEFORMED); return (*this); } - Builder& withVisible() { _value.reset(ItemKey::INVISIBLE); _mask.set(ItemKey::INVISIBLE); return (*this); } - Builder& withInvisible() { _value.set(ItemKey::INVISIBLE); _mask.set(ItemKey::INVISIBLE); return (*this); } + Builder& withVisible(uint8_t maskIndex) { _value.reset(ItemKey::INVISIBLE0 + maskIndex); _mask.set(ItemKey::INVISIBLE0 + maskIndex); return (*this); } + Builder& withInvisible(uint8_t maskIndex) { _value.set(ItemKey::INVISIBLE0 + maskIndex); _mask.set(ItemKey::INVISIBLE0 + maskIndex); return (*this); } + Builder& withVisibilityMask(uint8_t mask) { + for (int i = 0; i < ItemKey::NUM_VISIBLE_MASK_INDICES; i++) { + if ((1 << i) && mask) { + withVisible(i); + } else { + withInvisible(i); + } + } + return (*this); + } Builder& withNoShadowCaster() { _value.reset(ItemKey::SHADOW_CASTER); _mask.set(ItemKey::SHADOW_CASTER); return (*this); } Builder& withShadowCaster() { _value.set(ItemKey::SHADOW_CASTER); _mask.set(ItemKey::SHADOW_CASTER); return (*this); } @@ -185,7 +206,7 @@ public: Builder& withNothing() { _value.reset(); _mask.reset(); return (*this); } // Convenient standard keys that we will keep on using all over the place - static Builder visibleWorldItems() { return Builder().withVisible().withWorldSpace(); } + static Builder visibleWorldItems(uint8_t visibilityMask) { return Builder().withVisibilityMask(visibilityMask).withWorldSpace(); } static Builder opaqueShape() { return Builder().withTypeShape().withOpaque().withWorldSpace(); } static Builder transparentShape() { return Builder().withTypeShape().withTransparent().withWorldSpace(); } static Builder light() { return Builder().withTypeLight(); } diff --git a/libraries/render/src/render/RenderFetchCullSortTask.cpp b/libraries/render/src/render/RenderFetchCullSortTask.cpp index d7294fa2bd..25c40ea7f7 100644 --- a/libraries/render/src/render/RenderFetchCullSortTask.cpp +++ b/libraries/render/src/render/RenderFetchCullSortTask.cpp @@ -17,12 +17,12 @@ using namespace render; -void RenderFetchCullSortTask::build(JobModel& task, const Varying& input, Varying& output, CullFunctor cullFunctor) { +void RenderFetchCullSortTask::build(JobModel& task, const Varying& input, Varying& output, CullFunctor cullFunctor, uint8_t visibilityMask) { cullFunctor = cullFunctor ? cullFunctor : [](const RenderArgs*, const AABox&){ return true; }; // CPU jobs: // Fetch and cull the items from the scene - const ItemFilter filter = ItemFilter::Builder::visibleWorldItems().withoutLayered(); + const ItemFilter filter = ItemFilter::Builder::visibleWorldItems(visibilityMask).withoutLayered(); const auto spatialFilter = render::Varying(filter); const auto spatialSelection = task.addJob("FetchSceneSelection", spatialFilter); const auto cullInputs = CullSpatialSelection::Inputs(spatialSelection, spatialFilter).asVarying(); diff --git a/libraries/render/src/render/RenderFetchCullSortTask.h b/libraries/render/src/render/RenderFetchCullSortTask.h index b25480ae3a..3e5ad2bad8 100644 --- a/libraries/render/src/render/RenderFetchCullSortTask.h +++ b/libraries/render/src/render/RenderFetchCullSortTask.h @@ -36,7 +36,7 @@ public: RenderFetchCullSortTask() {} - void build(JobModel& task, const render::Varying& inputs, render::Varying& outputs, render::CullFunctor cullFunctor); + void build(JobModel& task, const render::Varying& inputs, render::Varying& outputs, render::CullFunctor cullFunctor, uint8_t visibilityMask = 0xFF); }; #endif // hifi_RenderFetchCullSortTask_h