mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 22:10:25 +02:00
Shadow task now uses LOD culling from main view task
This commit is contained in:
parent
445ffbd82f
commit
179aca2bf9
6 changed files with 60 additions and 8 deletions
|
@ -19,7 +19,7 @@
|
||||||
using RenderArgsPointer = std::shared_ptr<RenderArgs>;
|
using RenderArgsPointer = std::shared_ptr<RenderArgs>;
|
||||||
|
|
||||||
void MainRenderTask::build(JobModel& task, const render::Varying& inputs, render::Varying& outputs, render::CullFunctor cullFunctor, bool isDeferred) {
|
void MainRenderTask::build(JobModel& task, const render::Varying& inputs, render::Varying& outputs, render::CullFunctor cullFunctor, bool isDeferred) {
|
||||||
task.addJob<RenderShadowTask>("RenderShadowTask", render::ItemKey::TAG_BITS_1, render::ItemKey::TAG_BITS_1);
|
task.addJob<RenderShadowTask>("RenderShadowTask", cullFunctor, render::ItemKey::TAG_BITS_1, render::ItemKey::TAG_BITS_1);
|
||||||
const auto items = task.addJob<RenderFetchCullSortTask>("FetchCullSort", cullFunctor, render::ItemKey::TAG_BITS_1, render::ItemKey::TAG_BITS_1);
|
const auto items = task.addJob<RenderFetchCullSortTask>("FetchCullSort", cullFunctor, render::ItemKey::TAG_BITS_1, render::ItemKey::TAG_BITS_1);
|
||||||
assert(items.canCast<RenderFetchCullSortTask::Output>());
|
assert(items.canCast<RenderFetchCullSortTask::Output>());
|
||||||
if (!isDeferred) {
|
if (!isDeferred) {
|
||||||
|
|
|
@ -200,8 +200,8 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext, con
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderShadowTask::build(JobModel& task, const render::Varying& input, render::Varying& output, uint8_t tagBits, uint8_t tagMask) {
|
void RenderShadowTask::build(JobModel& task, const render::Varying& input, render::Varying& output, render::CullFunctor cameraCullFunctor, uint8_t tagBits, uint8_t tagMask) {
|
||||||
::CullFunctor cullFunctor = [this](const RenderArgs* args, const AABox& bounds) {
|
::CullFunctor shadowCullFunctor = [this](const RenderArgs* args, const AABox& bounds) {
|
||||||
return _cullFunctor(args, bounds);
|
return _cullFunctor(args, bounds);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -224,8 +224,14 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende
|
||||||
const auto selectionInputs = FetchSpatialSelection::Inputs(shadowSelection, shadowCasterFilter).asVarying();
|
const auto selectionInputs = FetchSpatialSelection::Inputs(shadowSelection, shadowCasterFilter).asVarying();
|
||||||
const auto shadowItems = task.addJob<FetchSpatialSelection>("FetchShadowSelection", selectionInputs);
|
const auto shadowItems = task.addJob<FetchSpatialSelection>("FetchShadowSelection", selectionInputs);
|
||||||
|
|
||||||
|
// Cull objects that are not visible in camera view. Hopefully the cull functor only performs LOD culling, not
|
||||||
|
// frustum culling or this will make shadow casters out of the camera frustum disappear.
|
||||||
|
const auto cameraFrustum = setupOutput.getN<RenderShadowSetup::Outputs>(2);
|
||||||
|
const auto applyFunctorInputs = ApplyCullFunctorOnItemBounds::Inputs(shadowItems, cameraFrustum).asVarying();
|
||||||
|
const auto culledShadowItems = task.addJob<ApplyCullFunctorOnItemBounds>("ShadowCullCamera", applyFunctorInputs, cameraCullFunctor);
|
||||||
|
|
||||||
// Sort
|
// Sort
|
||||||
const auto sortedPipelines = task.addJob<PipelineSortShapes>("PipelineSortShadow", shadowItems);
|
const auto sortedPipelines = task.addJob<PipelineSortShapes>("PipelineSortShadow", culledShadowItems);
|
||||||
const auto sortedShapes = task.addJob<DepthSortShapes>("DepthSortShadow", sortedPipelines, true);
|
const auto sortedShapes = task.addJob<DepthSortShapes>("DepthSortShadow", sortedPipelines, true);
|
||||||
|
|
||||||
render::Varying cascadeFrustums[SHADOW_CASCADE_MAX_COUNT] = {
|
render::Varying cascadeFrustums[SHADOW_CASCADE_MAX_COUNT] = {
|
||||||
|
@ -248,7 +254,7 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende
|
||||||
|
|
||||||
// CPU jobs: finer grained culling
|
// CPU jobs: finer grained culling
|
||||||
const auto cullInputs = CullShapeBounds::Inputs(sortedShapes, shadowFilter, antiFrustum).asVarying();
|
const auto cullInputs = CullShapeBounds::Inputs(sortedShapes, shadowFilter, antiFrustum).asVarying();
|
||||||
const auto culledShadowItemsAndBounds = task.addJob<CullShapeBounds>("CullShadowCascade", cullInputs, cullFunctor, RenderDetails::SHADOW);
|
const auto culledShadowItemsAndBounds = task.addJob<CullShapeBounds>("CullShadowCascade", cullInputs, shadowCullFunctor, RenderDetails::SHADOW);
|
||||||
|
|
||||||
// GPU jobs: Render to shadow map
|
// GPU jobs: Render to shadow map
|
||||||
sprintf(jobName, "RenderShadowMap%d", i);
|
sprintf(jobName, "RenderShadowMap%d", i);
|
||||||
|
@ -266,6 +272,7 @@ void RenderShadowTask::configure(const Config& configuration) {
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderShadowSetup::RenderShadowSetup() :
|
RenderShadowSetup::RenderShadowSetup() :
|
||||||
|
_cameraFrustum{ std::make_shared<ViewFrustum>() },
|
||||||
_coarseShadowFrustum{ std::make_shared<ViewFrustum>() } {
|
_coarseShadowFrustum{ std::make_shared<ViewFrustum>() } {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -297,6 +304,9 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, O
|
||||||
|
|
||||||
output.edit0() = args->_renderMode;
|
output.edit0() = args->_renderMode;
|
||||||
output.edit1() = glm::ivec2(0, 0);
|
output.edit1() = glm::ivec2(0, 0);
|
||||||
|
// Save main camera frustum
|
||||||
|
*_cameraFrustum = args->getViewFrustum();
|
||||||
|
output.edit2() = _cameraFrustum;
|
||||||
|
|
||||||
const auto globalShadow = lightStage->getCurrentKeyShadow();
|
const auto globalShadow = lightStage->getCurrentKeyShadow();
|
||||||
if (globalShadow) {
|
if (globalShadow) {
|
||||||
|
|
|
@ -50,7 +50,7 @@ public:
|
||||||
using JobModel = render::Task::Model<RenderShadowTask, Config>;
|
using JobModel = render::Task::Model<RenderShadowTask, Config>;
|
||||||
|
|
||||||
RenderShadowTask() {}
|
RenderShadowTask() {}
|
||||||
void build(JobModel& task, const render::Varying& inputs, render::Varying& outputs, uint8_t tagBits = 0x00, uint8_t tagMask = 0x00);
|
void build(JobModel& task, const render::Varying& inputs, render::Varying& outputs, render::CullFunctor cameraCullFunctor, uint8_t tagBits = 0x00, uint8_t tagMask = 0x00);
|
||||||
|
|
||||||
void configure(const Config& configuration);
|
void configure(const Config& configuration);
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ signals:
|
||||||
|
|
||||||
class RenderShadowSetup {
|
class RenderShadowSetup {
|
||||||
public:
|
public:
|
||||||
using Outputs = render::VaryingSet2<RenderArgs::RenderMode, glm::ivec2>;
|
using Outputs = render::VaryingSet3<RenderArgs::RenderMode, glm::ivec2, ViewFrustumPointer>;
|
||||||
using Config = RenderShadowSetupConfig;
|
using Config = RenderShadowSetupConfig;
|
||||||
using JobModel = render::Job::ModelO<RenderShadowSetup, Outputs, Config>;
|
using JobModel = render::Job::ModelO<RenderShadowSetup, Outputs, Config>;
|
||||||
|
|
||||||
|
@ -105,6 +105,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
ViewFrustumPointer _cameraFrustum;
|
||||||
ViewFrustumPointer _coarseShadowFrustum;
|
ViewFrustumPointer _coarseShadowFrustum;
|
||||||
struct {
|
struct {
|
||||||
float _constant;
|
float _constant;
|
||||||
|
|
|
@ -17,7 +17,9 @@
|
||||||
void RenderViewTask::build(JobModel& task, const render::Varying& input, render::Varying& output, render::CullFunctor cullFunctor, bool isDeferred, uint8_t tagBits, uint8_t tagMask) {
|
void RenderViewTask::build(JobModel& task, const render::Varying& input, render::Varying& output, render::CullFunctor cullFunctor, bool isDeferred, uint8_t tagBits, uint8_t tagMask) {
|
||||||
// auto items = input.get<Input>();
|
// auto items = input.get<Input>();
|
||||||
|
|
||||||
task.addJob<RenderShadowTask>("RenderShadowTask", tagBits, tagMask);
|
// Warning : the cull functor passed to the shadow pass should only be testing for LOD culling. If frustum culling
|
||||||
|
// is performed, then casters not in the view frustum will be removed, which is not what we wish.
|
||||||
|
task.addJob<RenderShadowTask>("RenderShadowTask", cullFunctor, tagBits, tagMask);
|
||||||
|
|
||||||
const auto items = task.addJob<RenderFetchCullSortTask>("FetchCullSort", cullFunctor, tagBits, tagMask);
|
const auto items = task.addJob<RenderFetchCullSortTask>("FetchCullSort", cullFunctor, tagBits, tagMask);
|
||||||
assert(items.canCast<RenderFetchCullSortTask::Output>());
|
assert(items.canCast<RenderFetchCullSortTask::Output>());
|
||||||
|
|
|
@ -389,6 +389,32 @@ void CullShapeBounds::run(const RenderContextPointer& renderContext, const Input
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ApplyCullFunctorOnItemBounds::run(const RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs) {
|
||||||
|
assert(renderContext->args);
|
||||||
|
assert(renderContext->args->hasViewFrustum());
|
||||||
|
RenderArgs* args = renderContext->args;
|
||||||
|
auto& inItems = inputs.get0();
|
||||||
|
auto& outItems = outputs;
|
||||||
|
auto inputFrustum = inputs.get1();
|
||||||
|
|
||||||
|
if (inputFrustum != nullptr) {
|
||||||
|
args->pushViewFrustum(*inputFrustum);
|
||||||
|
}
|
||||||
|
|
||||||
|
outItems.clear();
|
||||||
|
outItems.reserve(inItems.size());
|
||||||
|
|
||||||
|
for (auto& item : inItems) {
|
||||||
|
if (_cullFunctor(args, item.bound)) {
|
||||||
|
outItems.emplace_back(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inputFrustum != nullptr) {
|
||||||
|
args->popViewFrustum();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void FetchSpatialSelection::run(const RenderContextPointer& renderContext,
|
void FetchSpatialSelection::run(const RenderContextPointer& renderContext,
|
||||||
const Inputs& inputs, ItemBounds& outItems) {
|
const Inputs& inputs, ItemBounds& outItems) {
|
||||||
assert(renderContext->args);
|
assert(renderContext->args);
|
||||||
|
|
|
@ -140,6 +140,19 @@ namespace render {
|
||||||
void run(const RenderContextPointer& renderContext, const Inputs& inputs, ItemBounds& outItems);
|
void run(const RenderContextPointer& renderContext, const Inputs& inputs, ItemBounds& outItems);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ApplyCullFunctorOnItemBounds {
|
||||||
|
public:
|
||||||
|
using Inputs = render::VaryingSet2<ItemBounds, ViewFrustumPointer>;
|
||||||
|
using Outputs = ItemBounds;
|
||||||
|
using JobModel = Job::ModelIO<ApplyCullFunctorOnItemBounds, Inputs, Outputs>;
|
||||||
|
|
||||||
|
ApplyCullFunctorOnItemBounds(render::CullFunctor cullFunctor) : _cullFunctor(cullFunctor) {}
|
||||||
|
void run(const RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
render::CullFunctor _cullFunctor;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // hifi_render_CullTask_h;
|
#endif // hifi_render_CullTask_h;
|
Loading…
Reference in a new issue