Shadow task now uses LOD culling from main view task

This commit is contained in:
Olivier Prat 2018-02-06 11:47:39 +01:00
parent 445ffbd82f
commit 179aca2bf9
6 changed files with 60 additions and 8 deletions

View file

@ -19,7 +19,7 @@
using RenderArgsPointer = std::shared_ptr<RenderArgs>;
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);
assert(items.canCast<RenderFetchCullSortTask::Output>());
if (!isDeferred) {

View file

@ -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) {
::CullFunctor cullFunctor = [this](const RenderArgs* args, const AABox& bounds) {
void RenderShadowTask::build(JobModel& task, const render::Varying& input, render::Varying& output, render::CullFunctor cameraCullFunctor, uint8_t tagBits, uint8_t tagMask) {
::CullFunctor shadowCullFunctor = [this](const RenderArgs* args, const AABox& 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 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
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);
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
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
sprintf(jobName, "RenderShadowMap%d", i);
@ -266,6 +272,7 @@ void RenderShadowTask::configure(const Config& configuration) {
}
RenderShadowSetup::RenderShadowSetup() :
_cameraFrustum{ 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.edit1() = glm::ivec2(0, 0);
// Save main camera frustum
*_cameraFrustum = args->getViewFrustum();
output.edit2() = _cameraFrustum;
const auto globalShadow = lightStage->getCurrentKeyShadow();
if (globalShadow) {

View file

@ -50,7 +50,7 @@ public:
using JobModel = render::Task::Model<RenderShadowTask, Config>;
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);
@ -95,7 +95,7 @@ signals:
class RenderShadowSetup {
public:
using Outputs = render::VaryingSet2<RenderArgs::RenderMode, glm::ivec2>;
using Outputs = render::VaryingSet3<RenderArgs::RenderMode, glm::ivec2, ViewFrustumPointer>;
using Config = RenderShadowSetupConfig;
using JobModel = render::Job::ModelO<RenderShadowSetup, Outputs, Config>;
@ -105,6 +105,7 @@ public:
private:
ViewFrustumPointer _cameraFrustum;
ViewFrustumPointer _coarseShadowFrustum;
struct {
float _constant;

View file

@ -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) {
// 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);
assert(items.canCast<RenderFetchCullSortTask::Output>());

View file

@ -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,
const Inputs& inputs, ItemBounds& outItems) {
assert(renderContext->args);

View file

@ -140,6 +140,19 @@ namespace render {
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;