mirror of
https://github.com/overte-org/overte.git
synced 2025-04-11 16:03:24 +02:00
move bias init from config to run
This commit is contained in:
parent
bb5896c174
commit
534794d7ff
5 changed files with 119 additions and 62 deletions
|
@ -89,7 +89,7 @@ float Light::getShadowsBiasScale() const {
|
|||
return _shadowsBiasScale;
|
||||
}
|
||||
|
||||
void Light::setBiasInput(const float bias) {
|
||||
void Light::setBiasInput(float bias) {
|
||||
_biasInput = bias;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue