modify shadow config via single bias

This commit is contained in:
raveenajain 2019-06-24 11:03:10 -07:00
parent 55ebfc0789
commit f0660ba381
4 changed files with 46 additions and 27 deletions

View file

@ -203,7 +203,7 @@ protected:
float _shadowsMaxDistance{ 40.0f }; float _shadowsMaxDistance{ 40.0f };
float _shadowsBiasScale{ 1.0f }; float _shadowsBiasScale{ 1.0f };
float _biasInput{ 0.3f }; // gives default constant and slope values float _biasInput{ 0.23f }; // gives default constant and slope values
bool _castShadows{ false }; bool _castShadows{ false };
void updateLightRadius(); void updateLightRadius();

View file

@ -151,7 +151,6 @@ LightStage::Shadow::Shadow(graphics::LightPointer light, unsigned int cascadeCou
if (light) { if (light) {
setMaxDistance(light->getShadowsMaxDistance()); setMaxDistance(light->getShadowsMaxDistance());
setBiasInput(light->getBiasInput());
} }
} }

View file

@ -327,20 +327,30 @@ void RenderShadowSetup::configure(const Config& configuration) {
float slope1 = configuration.slopeBias1; float slope1 = configuration.slopeBias1;
float slope2 = configuration.slopeBias2; float slope2 = configuration.slopeBias2;
float slope3 = configuration.slopeBias3; float slope3 = configuration.slopeBias3;
// based on external bias input
if (prevBiasInput != configuration.biasInput) {
prevBiasInput = configuration.biasInput;
_biasInput = configuration.biasInput;
constant0 = (cacasdeDepths[0] / resolution) * _biasInput; // based on external bias input
constant1 = (cacasdeDepths[1] / resolution) * _biasInput; if (_biasInput != configuration.biasInput || _globalMaxDistance != configuration.globalMaxDistance) {
constant2 = (cacasdeDepths[2] / resolution) * _biasInput * 1.1f; _biasInput = configuration.biasInput;
constant3 = (cacasdeDepths[3] / resolution) * _biasInput * 1.3f; _globalMaxDistance = configuration.globalMaxDistance;
slope0 = constant0 * 2.7f;
slope1 = constant1 * 3.0f; // bias is relative to resolution
slope2 = constant2 * 3.7f; int resolutionScale = 1024 / resolution;
slope3 = constant3 * 3.3f; _biasInput *= (100.0f / resolutionScale);
float furtherScale = 1.0f;
furtherScale = cacasdeDistances[0] / cacasdeDistances[5];
constant0 = (cacasdeDistances[1] / resolution) * _biasInput * furtherScale;
constant1 = (cacasdeDistances[1] / resolution) * _biasInput * furtherScale;
slope0 = (cacasdeDistances[1] / resolution) * _biasInput * furtherScale * 2.5f;
slope1 = (cacasdeDistances[1] / resolution) * _biasInput * furtherScale * 2.75f;
furtherScale = cacasdeDistances[0] / cacasdeDistances[6];
constant2 = (cacasdeDistances[2] / resolution) * _biasInput * furtherScale;
slope2 = (cacasdeDistances[2] / resolution) * _biasInput * furtherScale * 3.75f;
furtherScale = cacasdeDistances[0] / cacasdeDistances[7];
constant3 = (cacasdeDistances[3] / resolution) * _biasInput * furtherScale;
slope3 = (cacasdeDistances[3] / resolution) * _biasInput * furtherScale * 3.75f;
} }
setConstantBias(0, constant0); setConstantBias(0, constant0);
@ -357,11 +367,18 @@ void RenderShadowSetup::configure(const Config& configuration) {
#endif #endif
} }
// cap constant and slope at 1 to prevent peter panning
void RenderShadowSetup::setConstantBias(int cascadeIndex, float value) { void RenderShadowSetup::setConstantBias(int cascadeIndex, float value) {
if (value > 1.0f) {
value = 1.0f;
}
_bias[cascadeIndex]._constant = value * value * value * 0.004f; _bias[cascadeIndex]._constant = value * value * value * 0.004f;
} }
void RenderShadowSetup::setSlopeBias(int cascadeIndex, float value) { void RenderShadowSetup::setSlopeBias(int cascadeIndex, float value) {
if (value > 1.0f) {
value = 1.0f;
}
_bias[cascadeIndex]._slope = value * value * value * 0.001f; _bias[cascadeIndex]._slope = value * value * value * 0.001f;
} }
@ -378,6 +395,7 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, c
output.edit3() = _shadowFrameCache; output.edit3() = _shadowFrameCache;
const auto currentKeyLight = lightStage->getCurrentKeyLight(lightFrame); const auto currentKeyLight = lightStage->getCurrentKeyLight(lightFrame);
setBiasInput(currentKeyLight->getBiasInput());
if (!lightingModel->isShadowEnabled() || !currentKeyLight || !currentKeyLight->getCastShadows()) { if (!lightingModel->isShadowEnabled() || !currentKeyLight || !currentKeyLight->getCastShadows()) {
renderContext->taskFlow.abortTask(); renderContext->taskFlow.abortTask();
return; return;
@ -398,6 +416,7 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, c
resolution = _globalShadowObject->MAP_SIZE; resolution = _globalShadowObject->MAP_SIZE;
_globalShadowObject->setLight(currentKeyLight); _globalShadowObject->setLight(currentKeyLight);
_globalShadowObject->setKeylightFrustum(args->getViewFrustum(), SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR); _globalShadowObject->setKeylightFrustum(args->getViewFrustum(), SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR);
_globalShadowObject->setMaxDistance(_globalMaxDistance);
auto& firstCascade = _globalShadowObject->getCascade(0); auto& firstCascade = _globalShadowObject->getCascade(0);
auto& firstCascadeFrustum = firstCascade.getFrustum(); auto& firstCascadeFrustum = firstCascade.getFrustum();
@ -405,7 +424,6 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, c
// Adjust each cascade frustum // Adjust each cascade frustum
const auto biasScale = currentKeyLight->getShadowsBiasScale(); const auto biasScale = currentKeyLight->getShadowsBiasScale();
setBiasInput(currentKeyLight->getBiasInput());
for (cascadeIndex = 0; cascadeIndex < _globalShadowObject->getCascadeCount(); ++cascadeIndex) { for (cascadeIndex = 0; cascadeIndex < _globalShadowObject->getCascadeCount(); ++cascadeIndex) {
auto& bias = _bias[cascadeIndex]; auto& bias = _bias[cascadeIndex];
_globalShadowObject->setKeylightCascadeFrustum(cascadeIndex, args->getViewFrustum(), _globalShadowObject->setKeylightCascadeFrustum(cascadeIndex, args->getViewFrustum(),
@ -426,8 +444,10 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, c
auto bottom = glm::dot(farBottomRight, firstCascadeFrustum->getUp()); auto bottom = glm::dot(farBottomRight, firstCascadeFrustum->getUp());
auto near = firstCascadeFrustum->getNearClip(); auto near = firstCascadeFrustum->getNearClip();
auto far = firstCascadeFrustum->getFarClip(); auto far = firstCascadeFrustum->getFarClip();
cacasdeDepths[0] = far;
cacasdeDistances[0] = _globalShadowObject->getCascade(0).getMaxDistance();
cacasdeDistances[4] = _globalShadowObject->getCascade(0).getMinDistance();
for (cascadeIndex = 1; cascadeIndex < _globalShadowObject->getCascadeCount(); ++cascadeIndex) { for (cascadeIndex = 1; cascadeIndex < _globalShadowObject->getCascadeCount(); ++cascadeIndex) {
auto& cascadeFrustum = _globalShadowObject->getCascade(cascadeIndex).getFrustum(); auto& cascadeFrustum = _globalShadowObject->getCascade(cascadeIndex).getFrustum();
@ -446,7 +466,9 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, c
top = glm::max(top, cascadeTop); top = glm::max(top, cascadeTop);
near = glm::min(near, cascadeNear); near = glm::min(near, cascadeNear);
far = glm::max(far, cascadeFar); far = glm::max(far, cascadeFar);
cacasdeDepths[cascadeIndex] = far;
cacasdeDistances[cascadeIndex] = _globalShadowObject->getCascade(cascadeIndex).getMaxDistance();
cacasdeDistances[cascadeIndex + 4] = _globalShadowObject->getCascade(cascadeIndex).getMinDistance();
} }
_coarseShadowFrustum->setPosition(firstCascadeFrustum->getPosition()); _coarseShadowFrustum->setPosition(firstCascadeFrustum->getPosition());

View file

@ -50,7 +50,6 @@ signals:
class RenderShadowTask { class RenderShadowTask {
public: public:
// There is one AABox per shadow cascade // There is one AABox per shadow cascade
using CascadeBoxes = render::VaryingArray<AABox, SHADOW_CASCADE_MAX_COUNT>; using CascadeBoxes = render::VaryingArray<AABox, SHADOW_CASCADE_MAX_COUNT>;
using Input = render::VaryingSet2<LightStage::FramePointer, LightingModelPointer>; using Input = render::VaryingSet2<LightStage::FramePointer, LightingModelPointer>;
@ -74,7 +73,6 @@ public:
}; };
CullFunctor _cullFunctor; CullFunctor _cullFunctor;
}; };
class RenderShadowSetupConfig : public render::Job::Config { class RenderShadowSetupConfig : public render::Job::Config {
@ -88,10 +86,11 @@ class RenderShadowSetupConfig : public render::Job::Config {
Q_PROPERTY(float slopeBias2 MEMBER slopeBias2 NOTIFY dirty) Q_PROPERTY(float slopeBias2 MEMBER slopeBias2 NOTIFY dirty)
Q_PROPERTY(float slopeBias3 MEMBER slopeBias3 NOTIFY dirty) Q_PROPERTY(float slopeBias3 MEMBER slopeBias3 NOTIFY dirty)
Q_PROPERTY(float biasInput MEMBER biasInput NOTIFY dirty) Q_PROPERTY(float biasInput MEMBER biasInput NOTIFY dirty)
Q_PROPERTY(float globalMaxDistance MEMBER globalMaxDistance NOTIFY dirty)
public: public:
float biasInput{ 0.23f };
float biasInput { 0.3f }; float globalMaxDistance{ 40 };
float constantBias0{ 0.15f }; float constantBias0{ 0.15f };
float constantBias1{ 0.15f }; float constantBias1{ 0.15f };
@ -116,14 +115,13 @@ public:
RenderShadowSetup(); RenderShadowSetup();
void configure(const Config& configuration); void configure(const Config& configuration);
void run(const render::RenderContextPointer& renderContext, const Input& input, Output& output); void run(const render::RenderContextPointer& renderContext, const Input& input, Output& output);
float _biasInput; float _biasInput;
float prevBiasInput { _biasInput }; float _globalMaxDistance;
int resolution { 1024 }; int resolution{ 1024 };
QVector<float> cacasdeDepths = QVector<float>(4); QVector<float> cacasdeDistances = QVector<float>(8); // 4 max then 4 min distances
private: private:
ViewFrustumPointer _cameraFrustum; ViewFrustumPointer _cameraFrustum;
ViewFrustumPointer _coarseShadowFrustum; ViewFrustumPointer _coarseShadowFrustum;
struct { struct {