Moved cascade frustum pre-computation to single ShadowSetup job

This commit is contained in:
Olivier Prat 2018-01-31 11:55:46 +01:00
parent f344e44d26
commit 3fa2babec2
3 changed files with 128 additions and 49 deletions

View file

@ -213,7 +213,7 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende
initZPassPipelines(*shapePlumber, state);
}
task.addJob<RenderShadowSetup>("ShadowSetup");
const auto coarseFrustum = task.addJob<RenderShadowSetup>("ShadowSetup");
for (auto i = 0; i < SHADOW_CASCADE_MAX_COUNT; i++) {
char jobName[64];
@ -243,7 +243,31 @@ void RenderShadowTask::configure(const Config& configuration) {
// Task::configure(configuration);
}
void RenderShadowSetup::run(const render::RenderContextPointer& renderContext) {
RenderShadowSetup::RenderShadowSetup() :
_coarseShadowFrustum{ std::make_shared<ViewFrustum>() } {
}
void RenderShadowSetup::configure(const Config& configuration) {
setConstantBias(0, configuration.constantBias0);
setConstantBias(1, configuration.constantBias1);
setConstantBias(2, configuration.constantBias2);
setConstantBias(3, configuration.constantBias3);
setSlopeBias(0, configuration.slopeBias0);
setSlopeBias(1, configuration.slopeBias1);
setSlopeBias(2, configuration.slopeBias2);
setSlopeBias(3, configuration.slopeBias3);
}
void RenderShadowSetup::setConstantBias(int cascadeIndex, float value) {
_bias[cascadeIndex]._constant = value * value * value * 0.004f;
}
void RenderShadowSetup::setSlopeBias(int cascadeIndex, float value) {
_bias[cascadeIndex]._slope = value * value * value * 0.01f;
}
void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, Output& output) {
auto lightStage = renderContext->_scene->getStage<LightStage>();
assert(lightStage);
// Cache old render args
@ -252,12 +276,46 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext) {
const auto globalShadow = lightStage->getCurrentKeyShadow();
if (globalShadow) {
globalShadow->setKeylightFrustum(args->getViewFrustum(), SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR);
}
}
auto firstCascadeFrustum = globalShadow->getCascade(0).getFrustum();
unsigned int cascadeIndex;
_coarseShadowFrustum->setPosition(firstCascadeFrustum->getPosition());
_coarseShadowFrustum->setOrientation(firstCascadeFrustum->getOrientation());
void RenderShadowCascadeSetup::configure(const Config& configuration) {
_fixedBias = configuration.fixedBias * configuration.fixedBias * configuration.fixedBias * 0.004f;
_slopeBias = configuration.slopeBias * configuration.slopeBias * configuration.slopeBias * 0.01f;
// Adjust each cascade frustum
for (cascadeIndex = 0; cascadeIndex < globalShadow->getCascadeCount(); ++cascadeIndex) {
auto& bias = _bias[cascadeIndex];
globalShadow->setKeylightCascadeFrustum(cascadeIndex, args->getViewFrustum(),
SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR,
bias._constant, bias._slope);
}
// Now adjust coarse frustum bounds
auto left = glm::dot(firstCascadeFrustum->getFarTopLeft(), firstCascadeFrustum->getRight());
auto right = glm::dot(firstCascadeFrustum->getFarTopRight(), firstCascadeFrustum->getRight());
auto top = glm::dot(firstCascadeFrustum->getFarTopLeft(), firstCascadeFrustum->getUp());
auto bottom = glm::dot(firstCascadeFrustum->getFarBottomRight(), firstCascadeFrustum->getUp());
auto near = firstCascadeFrustum->getNearClip();
auto far = firstCascadeFrustum->getFarClip();
for (cascadeIndex = 1; cascadeIndex < globalShadow->getCascadeCount(); ++cascadeIndex) {
auto cascadeLeft = glm::dot(firstCascadeFrustum->getFarTopLeft(), firstCascadeFrustum->getRight());
auto cascadeRight = glm::dot(firstCascadeFrustum->getFarTopRight(), firstCascadeFrustum->getRight());
auto cascadeTop = glm::dot(firstCascadeFrustum->getFarTopLeft(), firstCascadeFrustum->getUp());
auto cascadeBottom = glm::dot(firstCascadeFrustum->getFarBottomRight(), firstCascadeFrustum->getUp());
auto cascadeNear = firstCascadeFrustum->getNearClip();
auto cascadeFar = firstCascadeFrustum->getFarClip();
left = glm::min(left, cascadeLeft);
right = glm::max(right, cascadeRight);
bottom = glm::min(bottom, cascadeBottom);
top = glm::max(top, cascadeTop);
near = glm::min(near, cascadeNear);
far = glm::max(far, cascadeFar);
}
_coarseShadowFrustum->setProjection(glm::ortho<float>(left, right, bottom, top, near, far));
_coarseShadowFrustum->calculate();
output = _coarseShadowFrustum;
} else {
output = nullptr;
}
}
void RenderShadowCascadeSetup::run(const render::RenderContextPointer& renderContext, Outputs& output) {
@ -273,9 +331,6 @@ void RenderShadowCascadeSetup::run(const render::RenderContextPointer& renderCon
if (globalShadow && _cascadeIndex<globalShadow->getCascadeCount()) {
output.edit1() = ItemFilter::Builder::visibleWorldItems().withTypeShape().withOpaque().withoutLayered();
globalShadow->setKeylightCascadeFrustum(_cascadeIndex, args->getViewFrustum(), SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR,
_fixedBias, _slopeBias);
// Set the keylight render args
args->pushViewFrustum(*(globalShadow->getCascade(_cascadeIndex).getFrustum()));
args->_renderMode = RenderArgs::SHADOW_RENDER_MODE;

View file

@ -17,6 +17,8 @@
#include <render/CullTask.h>
#include "Shadows_shared.slh"
class ViewFrustum;
class RenderShadowMap {
@ -53,43 +55,64 @@ public:
void configure(const Config& configuration);
};
class RenderShadowSetup {
public:
using JobModel = render::Job::Model<RenderShadowSetup>;
RenderShadowSetup() {}
void run(const render::RenderContextPointer& renderContext);
};
class RenderShadowCascadeSetupConfig : public render::Job::Config {
class RenderShadowSetupConfig : public render::Job::Config {
Q_OBJECT
Q_PROPERTY(float fixedBias MEMBER fixedBias NOTIFY dirty)
Q_PROPERTY(float slopeBias MEMBER slopeBias NOTIFY dirty)
Q_PROPERTY(float constantBias0 MEMBER constantBias0 NOTIFY dirty)
Q_PROPERTY(float constantBias1 MEMBER constantBias1 NOTIFY dirty)
Q_PROPERTY(float constantBias2 MEMBER constantBias2 NOTIFY dirty)
Q_PROPERTY(float constantBias3 MEMBER constantBias3 NOTIFY dirty)
Q_PROPERTY(float slopeBias0 MEMBER slopeBias0 NOTIFY dirty)
Q_PROPERTY(float slopeBias1 MEMBER slopeBias1 NOTIFY dirty)
Q_PROPERTY(float slopeBias2 MEMBER slopeBias2 NOTIFY dirty)
Q_PROPERTY(float slopeBias3 MEMBER slopeBias3 NOTIFY dirty)
public:
float fixedBias{ 0.15f };
float slopeBias{ 0.55f };
float constantBias0{ 0.15f };
float constantBias1{ 0.15f };
float constantBias2{ 0.15f };
float constantBias3{ 0.15f };
float slopeBias0{ 0.55f };
float slopeBias1{ 0.55f };
float slopeBias2{ 0.55f };
float slopeBias3{ 0.55f };
signals:
void dirty();
};
class RenderShadowSetup {
public:
using Output = ViewFrustumPointer;
using Config = RenderShadowSetupConfig;
using JobModel = render::Job::ModelO<RenderShadowSetup, Output, Config>;
RenderShadowSetup();
void configure(const Config& configuration);
void run(const render::RenderContextPointer& renderContext, Output& output);
private:
ViewFrustumPointer _coarseShadowFrustum;
struct {
float _constant;
float _slope;
} _bias[SHADOW_CASCADE_MAX_COUNT];
void setConstantBias(int cascadeIndex, float value);
void setSlopeBias(int cascadeIndex, float value);
};
class RenderShadowCascadeSetup {
public:
using Outputs = render::VaryingSet3<RenderArgs::RenderMode, render::ItemFilter, float>;
using Config = RenderShadowCascadeSetupConfig;
using JobModel = render::Job::ModelO<RenderShadowCascadeSetup, Outputs, Config>;
using JobModel = render::Job::ModelO<RenderShadowCascadeSetup, Outputs>;
RenderShadowCascadeSetup(unsigned int cascadeIndex) : _cascadeIndex{ cascadeIndex } {}
void configure(const Config& configuration);
void run(const render::RenderContextPointer& renderContext, Outputs& output);
private:
unsigned int _cascadeIndex;
float _fixedBias{ 0.1f };
float _slopeBias{ 0.1f };
};
class RenderShadowCascadeTeardown {

View file

@ -18,6 +18,7 @@ Column {
id: root
spacing: 8
property var viewConfig: Render.getConfig("RenderMainView.DrawViewFrustum");
property var shadowConfig : Render.getConfig("RenderMainView.ShadowSetup");
property var shadow0Config: Render.getConfig("RenderMainView.DrawShadowFrustum0");
property var shadow1Config: Render.getConfig("RenderMainView.DrawShadowFrustum1");
property var shadow2Config: Render.getConfig("RenderMainView.DrawShadowFrustum2");
@ -80,34 +81,34 @@ Column {
}
}
ConfigSlider {
label: qsTr("Cascade 0 fixed bias")
label: qsTr("Cascade 0 constant bias")
integral: false
config: Render.getConfig("RenderMainView.ShadowCascadeSetup0")
property: "fixedBias"
config: shadowConfig
property: "constantBias0"
max: 1.0
min: 0.0
}
ConfigSlider {
label: qsTr("Cascade 1 fixed bias")
label: qsTr("Cascade 1 constant bias")
integral: false
config: Render.getConfig("RenderMainView.ShadowCascadeSetup1")
property: "fixedBias"
config: shadowConfig
property: "constantBias1"
max: 1.0
min: 0.0
}
ConfigSlider {
label: qsTr("Cascade 2 fixed bias")
label: qsTr("Cascade 2 constant bias")
integral: false
config: Render.getConfig("RenderMainView.ShadowCascadeSetup2")
property: "fixedBias"
config: shadowConfig
property: "constantBias2"
max: 1.0
min: 0.0
}
ConfigSlider {
label: qsTr("Cascade 3 fixed bias")
label: qsTr("Cascade 3 constant bias")
integral: false
config: Render.getConfig("RenderMainView.ShadowCascadeSetup3")
property: "fixedBias"
config: shadowConfig
property: "constantBias3"
max: 1.0
min: 0.0
}
@ -115,32 +116,32 @@ Column {
ConfigSlider {
label: qsTr("Cascade 0 slope bias")
integral: false
config: Render.getConfig("RenderMainView.ShadowCascadeSetup0")
property: "slopeBias"
config: shadowConfig
property: "slopeBias0"
max: 1.0
min: 0.0
}
ConfigSlider {
label: qsTr("Cascade 1 slope bias")
integral: false
config: Render.getConfig("RenderMainView.ShadowCascadeSetup1")
property: "slopeBias"
config: shadowConfig
property: "slopeBias1"
max: 1.0
min: 0.0
}
ConfigSlider {
label: qsTr("Cascade 2 slope bias")
integral: false
config: Render.getConfig("RenderMainView.ShadowCascadeSetup2")
property: "slopeBias"
config: shadowConfig
property: "slopeBias2"
max: 1.0
min: 0.0
}
ConfigSlider {
label: qsTr("Cascade 3 slope bias")
integral: false
config: Render.getConfig("RenderMainView.ShadowCascadeSetup3")
property: "slopeBias"
config: shadowConfig
property: "slopeBias3"
max: 1.0
min: 0.0
}