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;
}
void Light::setBiasInput(const float bias) {
void Light::setBiasInput(float bias) {
_biasInput = bias;
}

View file

@ -203,7 +203,7 @@ protected:
float _shadowsMaxDistance{ 40.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 };
void updateLightRadius();

View file

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

View file

@ -317,55 +317,94 @@ RenderShadowSetup::RenderShadowSetup() :
}
void RenderShadowSetup::configure(const Config& configuration) {
distanceTriggeredByConfig = _globalMaxDistance != configuration.globalMaxDistance;
biasTriggeredByConfig = _biasInput != configuration.biasInput;
// change shadow map based on distinct constant and slope values
float constant0 = configuration.constantBias0;
float constant1 = configuration.constantBias1;
float constant2 = configuration.constantBias2;
float constant3 = configuration.constantBias3;
float slope0 = configuration.slopeBias0;
float slope1 = configuration.slopeBias1;
float slope2 = configuration.slopeBias2;
float slope3 = configuration.slopeBias3;
// go back to using the config's default bias values if a change to any of those is triggered
if (constant0 != configuration.constantBias0 || slope0 != configuration.slopeBias0 ||
constant1 != configuration.constantBias1 || slope1 != configuration.slopeBias1 ||
constant2 != configuration.constantBias2 || slope2 != configuration.slopeBias2 ||
constant3 != configuration.constantBias3 || slope3 != configuration.slopeBias3) {
constant0 = configuration.constantBias0;
slope0 = configuration.slopeBias0;
constant1 = configuration.constantBias1;
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
if (_biasInput != configuration.biasInput || _globalMaxDistance != configuration.globalMaxDistance) {
_biasInput = configuration.biasInput;
_globalMaxDistance = configuration.globalMaxDistance;
setConstantBias(0, constant0);
setSlopeBias(0, slope0);
// the bias is relative to resolution
// to remain consistant 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
int resolutionScale = DEFAULT_RESOLUTION / resolution;
_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;
#if SHADOW_CASCADE_MAX_COUNT > 1
setConstantBias(1, constant1);
setConstantBias(2, constant2);
setConstantBias(3, constant3);
scaleFactor = _biasInput * (cacasdeDistances[0] / glm::clamp(cacasdeDistances[6], 0.0001f, FLT_MAX)) / (float)resolution;
constant2 = cacasdeDistances[2] * scaleFactor;
slope2 = cacasdeDistances[2] * scaleFactor * 3.75f;
scaleFactor = _biasInput * (cacasdeDistances[0] / glm::clamp(cacasdeDistances[7], 0.0001f, FLT_MAX)) / (float)resolution;
constant3 = cacasdeDistances[3] * scaleFactor;
slope3 = cacasdeDistances[3] * scaleFactor * 3.75f;
setSlopeBias(1, slope1);
setSlopeBias(2, slope2);
setSlopeBias(3, slope3);
#endif
}
// 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);
setSlopeBias(0, slope0);
void RenderShadowSetup::calculateBiases() {
// 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
setConstantBias(1, constant1);
setConstantBias(2, constant2);
setConstantBias(3, constant3);
setConstantBias(1, localConstant1);
setConstantBias(2, localConstant2);
setConstantBias(3, localConstant3);
setSlopeBias(1, slope1);
setSlopeBias(2, slope2);
setSlopeBias(3, slope3);
setSlopeBias(1, localSlope1);
setSlopeBias(2, localSlope2);
setSlopeBias(3, localSlope3);
#endif
}
@ -393,7 +432,6 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, c
output.edit3() = _shadowFrameCache;
const auto currentKeyLight = lightStage->getCurrentKeyLight(lightFrame);
setBiasInput(currentKeyLight->getBiasInput());
if (!lightingModel->isShadowEnabled() || !currentKeyLight || !currentKeyLight->getCastShadows()) {
renderContext->taskFlow.abortTask();
return;
@ -414,18 +452,32 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, c
resolution = _globalShadowObject->MAP_SIZE;
_globalShadowObject->setLight(currentKeyLight);
_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);
auto& firstCascade = _globalShadowObject->getCascade(0);
auto& firstCascadeFrustum = firstCascade.getFrustum();
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
const auto biasScale = currentKeyLight->getShadowsBiasScale();
for (cascadeIndex = 0; cascadeIndex < _globalShadowObject->getCascadeCount(); ++cascadeIndex) {
auto& bias = _bias[cascadeIndex];
_globalShadowObject->setKeylightCascadeFrustum(cascadeIndex, args->getViewFrustum(),
SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR,
_globalShadowObject->setKeylightCascadeFrustum(cascadeIndex, args->getViewFrustum(),
SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR,
bias._constant, bias._slope * biasScale);
}
@ -443,9 +495,6 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, c
auto near = firstCascadeFrustum->getNearClip();
auto far = firstCascadeFrustum->getFarClip();
cacasdeDistances[0] = _globalShadowObject->getCascade(0).getMaxDistance();
cacasdeDistances[4] = _globalShadowObject->getCascade(0).getMinDistance();
for (cascadeIndex = 1; cascadeIndex < _globalShadowObject->getCascadeCount(); ++cascadeIndex) {
auto& cascadeFrustum = _globalShadowObject->getCascade(cascadeIndex).getFrustum();
@ -464,9 +513,6 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, c
top = glm::max(top, cascadeTop);
near = glm::min(near, cascadeNear);
far = glm::max(far, cascadeFar);
cacasdeDistances[cascadeIndex] = _globalShadowObject->getCascade(cascadeIndex).getMaxDistance();
cacasdeDistances[cascadeIndex + 4] = _globalShadowObject->getCascade(cascadeIndex).getMinDistance();
}
_coarseShadowFrustum->setPosition(firstCascadeFrustum->getPosition());

View file

@ -75,7 +75,7 @@ public:
CullFunctor _cullFunctor;
};
const float DEFAULT_BIAS_INPUT = 0.23f;
const float DEFAULT_BIAS_INPUT = 0.5f;
const float DEFAULT_MAX_DISTANCE = 40.0f;
class RenderShadowSetupConfig : public render::Job::Config {
@ -119,12 +119,6 @@ public:
void configure(const Config& configuration);
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:
ViewFrustumPointer _cameraFrustum;
ViewFrustumPointer _coarseShadowFrustum;
@ -136,9 +130,29 @@ private:
LightStage::ShadowFrame::Object _globalShadowObject;
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 setSlopeBias(int cascadeIndex, float value);
void setBiasInput(float input) { _biasInput = input; }
void calculateBiases();
};
class RenderShadowCascadeSetup {