move bias init from config to run

This commit is contained in:
raveenajain 2019-06-26 15:42:11 -07:00
parent bb5896c174
commit 534794d7ff
5 changed files with 119 additions and 62 deletions

View file

@ -89,7 +89,7 @@ float Light::getShadowsBiasScale() const {
return _shadowsBiasScale; return _shadowsBiasScale;
} }
void Light::setBiasInput(const float bias) { void Light::setBiasInput(float bias) {
_biasInput = bias; _biasInput = bias;
} }

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.23f }; // roughly gives default constant and slope values float _biasInput{ 0.5f }; // 0.23f will roughly give the default constant and slope values
bool _castShadows{ false }; bool _castShadows{ false };
void updateLightRadius(); void updateLightRadius();

View file

@ -92,8 +92,6 @@ public:
float getMaxDistance() const { return _maxDistance; } float getMaxDistance() const { return _maxDistance; }
void setMaxDistance(float value); void setMaxDistance(float value);
void setBiasInput(float value) { _biasInput = value; }
const graphics::LightPointer& getLight() const { return _light; } const graphics::LightPointer& getLight() const { return _light; }
gpu::TexturePointer map; gpu::TexturePointer map;
@ -112,7 +110,6 @@ public:
graphics::LightPointer _light; graphics::LightPointer _light;
float _maxDistance{ 0.0f }; float _maxDistance{ 0.0f };
float _biasInput{ 0.23f };
Cascades _cascades; Cascades _cascades;
UniformBufferView _schemaBuffer = nullptr; UniformBufferView _schemaBuffer = nullptr;

View file

@ -317,55 +317,94 @@ RenderShadowSetup::RenderShadowSetup() :
} }
void RenderShadowSetup::configure(const Config& configuration) { void RenderShadowSetup::configure(const Config& configuration) {
distanceTriggeredByConfig = _globalMaxDistance != configuration.globalMaxDistance;
biasTriggeredByConfig = _biasInput != configuration.biasInput;
// change shadow map based on distinct constant and slope values // go back to using the config's default bias values if a change to any of those is triggered
float constant0 = configuration.constantBias0; if (constant0 != configuration.constantBias0 || slope0 != configuration.slopeBias0 ||
float constant1 = configuration.constantBias1; constant1 != configuration.constantBias1 || slope1 != configuration.slopeBias1 ||
float constant2 = configuration.constantBias2; constant2 != configuration.constantBias2 || slope2 != configuration.slopeBias2 ||
float constant3 = configuration.constantBias3; constant3 != configuration.constantBias3 || slope3 != configuration.slopeBias3) {
float slope0 = configuration.slopeBias0; constant0 = configuration.constantBias0;
float slope1 = configuration.slopeBias1; slope0 = configuration.slopeBias0;
float slope2 = configuration.slopeBias2; constant1 = configuration.constantBias1;
float slope3 = configuration.slopeBias3; slope1 = configuration.slopeBias1;
constant2 = configuration.constantBias2;
slope2 = configuration.slopeBias2;
constant3 = configuration.constantBias3;
slope3 = configuration.slopeBias3;
changeInDefaultConfigValues = true;
distanceTriggeredByConfig = false;
biasTriggeredByConfig = false;
// based on external bias input setConstantBias(0, constant0);
if (_biasInput != configuration.biasInput || _globalMaxDistance != configuration.globalMaxDistance) { setSlopeBias(0, slope0);
_biasInput = configuration.biasInput;
_globalMaxDistance = configuration.globalMaxDistance;
// the bias is relative to resolution #if SHADOW_CASCADE_MAX_COUNT > 1
// to remain consistant with the constant and slope bias values, the biasInput setConstantBias(1, constant1);
// value is in the 0.0 - 1.0 range but needs to be scaled up for further calculations setConstantBias(2, constant2);
int resolutionScale = DEFAULT_RESOLUTION / resolution; setConstantBias(3, constant3);
_biasInput *= (100.0f / resolutionScale);
float scaleFactor = 1.0f;
scaleFactor = _biasInput * (cacasdeDistances[0] / glm::clamp(cacasdeDistances[5], 0.0001f, FLT_MAX)) / (float)resolution;
constant0 = cacasdeDistances[1] * scaleFactor;
constant1 = cacasdeDistances[1] * scaleFactor;
slope0 = cacasdeDistances[1] * scaleFactor * 2.5f;
slope1 = cacasdeDistances[1] * scaleFactor * 2.75f;
scaleFactor = _biasInput * (cacasdeDistances[0] / glm::clamp(cacasdeDistances[6], 0.0001f, FLT_MAX)) / (float)resolution; setSlopeBias(1, slope1);
constant2 = cacasdeDistances[2] * scaleFactor; setSlopeBias(2, slope2);
slope2 = cacasdeDistances[2] * scaleFactor * 3.75f; setSlopeBias(3, slope3);
#endif
scaleFactor = _biasInput * (cacasdeDistances[0] / glm::clamp(cacasdeDistances[7], 0.0001f, FLT_MAX)) / (float)resolution;
constant3 = cacasdeDistances[3] * scaleFactor;
slope3 = cacasdeDistances[3] * scaleFactor * 3.75f;
} }
// modify bias using single input and work in calculateBias()
if (distanceTriggeredByConfig) {
changeInDefaultConfigValues = false;
_globalMaxDistance = configuration.globalMaxDistance;
calculateBiases();
}
if (biasTriggeredByConfig) {
changeInDefaultConfigValues = false;
_biasInput = configuration.biasInput;
calculateBiases();
}
}
setConstantBias(0, constant0); void RenderShadowSetup::calculateBiases() {
setSlopeBias(0, slope0); // slope scaling values derived from ratio between original constantBias and slopeBias pairs
float SCALE_SLOPE_0 = 2.7f;
float SCALE_SLOPE_1 = 3.0f;
float SCALE_SLOPE_2 = 3.7f;
float SCALE_SLOPE_3 = 3.5f;
float CONVERT_BIAS = 100.0f;
// the bias is relative to resolution
// to remain consistent with the constant and slope bias values, the biasInput
// value is in the 0.0 - 1.0 range but needs to be scaled up for further calculations
float inverseResolution = 1.0f / (float)resolution;
int resolutionScale = DEFAULT_RESOLUTION * inverseResolution;
float convertedBias = _biasInput * (CONVERT_BIAS / resolutionScale);
float scaleFactor = 1.0f;
scaleFactor = convertedBias * (cacasdeDistances[0] / glm::clamp(cacasdeDistances[5], 0.0001f, FLT_MAX)) * inverseResolution;
float localConstant0 = cacasdeDistances[1] * scaleFactor;
float localConstant1 = cacasdeDistances[1] * scaleFactor;
float localSlope0 = cacasdeDistances[1] * scaleFactor * SCALE_SLOPE_0;
float localSlope1 = cacasdeDistances[1] * scaleFactor * SCALE_SLOPE_1;
scaleFactor = convertedBias * (cacasdeDistances[0] / glm::clamp(cacasdeDistances[6], 0.0001f, FLT_MAX)) * inverseResolution;
float localConstant2 = cacasdeDistances[2] * scaleFactor;
float localSlope2 = cacasdeDistances[2] * scaleFactor * SCALE_SLOPE_2;
scaleFactor = convertedBias * (cacasdeDistances[0] / glm::clamp(cacasdeDistances[7], 0.0001f, FLT_MAX)) * inverseResolution;
float localConstant3 = cacasdeDistances[3] * scaleFactor;
float localSlope3 = cacasdeDistances[3] * scaleFactor * SCALE_SLOPE_3;
setConstantBias(0, localConstant0);
setSlopeBias(0, localSlope0);
#if SHADOW_CASCADE_MAX_COUNT > 1 #if SHADOW_CASCADE_MAX_COUNT > 1
setConstantBias(1, constant1); setConstantBias(1, localConstant1);
setConstantBias(2, constant2); setConstantBias(2, localConstant2);
setConstantBias(3, constant3); setConstantBias(3, localConstant3);
setSlopeBias(1, slope1); setSlopeBias(1, localSlope1);
setSlopeBias(2, slope2); setSlopeBias(2, localSlope2);
setSlopeBias(3, slope3); setSlopeBias(3, localSlope3);
#endif #endif
} }
@ -393,7 +432,6 @@ 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;
@ -414,18 +452,32 @@ 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);
// if the max distance isn't altered externally, grab the value from the light
if (!distanceTriggeredByConfig && !biasTriggeredByConfig) {
_globalMaxDistance = currentKeyLight->getShadowsMaxDistance();
}
_globalShadowObject->setMaxDistance(_globalMaxDistance); _globalShadowObject->setMaxDistance(_globalMaxDistance);
auto& firstCascade = _globalShadowObject->getCascade(0); auto& firstCascade = _globalShadowObject->getCascade(0);
auto& firstCascadeFrustum = firstCascade.getFrustum(); auto& firstCascadeFrustum = firstCascade.getFrustum();
unsigned int cascadeIndex; unsigned int cascadeIndex;
for (cascadeIndex = 0; cascadeIndex < _globalShadowObject->getCascadeCount(); ++cascadeIndex) {
cacasdeDistances[cascadeIndex] = _globalShadowObject->getCascade(cascadeIndex).getMaxDistance();
cacasdeDistances[cascadeIndex + 4] = _globalShadowObject->getCascade(cascadeIndex).getMinDistance();
}
if (!biasTriggeredByConfig && !distanceTriggeredByConfig && !changeInDefaultConfigValues) {
setBiasInput(currentKeyLight->getBiasInput());
calculateBiases();
}
// Adjust each cascade frustum // Adjust each cascade frustum
const auto biasScale = currentKeyLight->getShadowsBiasScale(); const auto biasScale = currentKeyLight->getShadowsBiasScale();
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(),
SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR, SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR,
bias._constant, bias._slope * biasScale); bias._constant, bias._slope * biasScale);
} }
@ -443,9 +495,6 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, c
auto near = firstCascadeFrustum->getNearClip(); auto near = firstCascadeFrustum->getNearClip();
auto far = firstCascadeFrustum->getFarClip(); auto far = firstCascadeFrustum->getFarClip();
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();
@ -464,9 +513,6 @@ 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);
cacasdeDistances[cascadeIndex] = _globalShadowObject->getCascade(cascadeIndex).getMaxDistance();
cacasdeDistances[cascadeIndex + 4] = _globalShadowObject->getCascade(cascadeIndex).getMinDistance();
} }
_coarseShadowFrustum->setPosition(firstCascadeFrustum->getPosition()); _coarseShadowFrustum->setPosition(firstCascadeFrustum->getPosition());

View file

@ -75,7 +75,7 @@ public:
CullFunctor _cullFunctor; CullFunctor _cullFunctor;
}; };
const float DEFAULT_BIAS_INPUT = 0.23f; const float DEFAULT_BIAS_INPUT = 0.5f;
const float DEFAULT_MAX_DISTANCE = 40.0f; const float DEFAULT_MAX_DISTANCE = 40.0f;
class RenderShadowSetupConfig : public render::Job::Config { class RenderShadowSetupConfig : public render::Job::Config {
@ -119,12 +119,6 @@ public:
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);
const int DEFAULT_RESOLUTION = 1024;
float _biasInput{ DEFAULT_BIAS_INPUT };
float _globalMaxDistance{ DEFAULT_MAX_DISTANCE };
int resolution{ DEFAULT_RESOLUTION };
QVector<float> cacasdeDistances = QVector<float>(8); // 4 max then 4 min distances
private: private:
ViewFrustumPointer _cameraFrustum; ViewFrustumPointer _cameraFrustum;
ViewFrustumPointer _coarseShadowFrustum; ViewFrustumPointer _coarseShadowFrustum;
@ -136,9 +130,29 @@ private:
LightStage::ShadowFrame::Object _globalShadowObject; LightStage::ShadowFrame::Object _globalShadowObject;
LightStage::ShadowFramePointer _shadowFrameCache; LightStage::ShadowFramePointer _shadowFrameCache;
const int DEFAULT_RESOLUTION = 1024;
float _biasInput{ DEFAULT_BIAS_INPUT };
float _globalMaxDistance{ DEFAULT_MAX_DISTANCE };
int resolution{ DEFAULT_RESOLUTION };
// initialize with values from RenderShadowSetupConfig
float constant0{ 0.15f };
float constant1{ 0.15f };
float constant2{ 0.175f };
float constant3{ 0.2f };
float slope0{ 0.4f };
float slope1{ 0.45f };
float slope2{ 0.65f };
float slope3{ 0.7f };
bool changeInDefaultConfigValues{ false };
bool distanceTriggeredByConfig{ false };
bool biasTriggeredByConfig{ false };
std::vector<float> cacasdeDistances = std::vector<float>(8); // 4 max then 4 min distances
void setConstantBias(int cascadeIndex, float value); void setConstantBias(int cascadeIndex, float value);
void setSlopeBias(int cascadeIndex, float value); void setSlopeBias(int cascadeIndex, float value);
void setBiasInput(float input) { _biasInput = input; } void setBiasInput(float input) { _biasInput = input; }
void calculateBiases();
}; };
class RenderShadowCascadeSetup { class RenderShadowCascadeSetup {