mirror of
https://github.com/JulianGro/overte.git
synced 2025-05-05 10:07:43 +02:00
Merge pull request #15827 from raveenajain/nitpick_shadows
BUGZ 598: nitpick tests failing due to shadow issue
This commit is contained in:
commit
45ffa2bb1f
7 changed files with 131 additions and 19 deletions
|
@ -89,6 +89,14 @@ float Light::getShadowsBiasScale() const {
|
||||||
return _shadowsBiasScale;
|
return _shadowsBiasScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Light::setBiasInput(float bias) {
|
||||||
|
_biasInput = bias;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Light::getBiasInput() const {
|
||||||
|
return _biasInput;
|
||||||
|
}
|
||||||
|
|
||||||
void Light::setColor(const Color& color) {
|
void Light::setColor(const Color& color) {
|
||||||
_lightSchemaBuffer.edit().irradiance.color = color;
|
_lightSchemaBuffer.edit().irradiance.color = color;
|
||||||
updateLightRadius();
|
updateLightRadius();
|
||||||
|
|
|
@ -112,6 +112,9 @@ public:
|
||||||
void setShadowsBiasScale(const float scale);
|
void setShadowsBiasScale(const float scale);
|
||||||
float getShadowsBiasScale() const;
|
float getShadowsBiasScale() const;
|
||||||
|
|
||||||
|
void setBiasInput(float bias);
|
||||||
|
float getBiasInput() const;
|
||||||
|
|
||||||
void setOrientation(const Quat& orientation);
|
void setOrientation(const Quat& orientation);
|
||||||
const glm::quat& getOrientation() const { return _transform.getRotation(); }
|
const glm::quat& getOrientation() const { return _transform.getRotation(); }
|
||||||
|
|
||||||
|
@ -200,6 +203,7 @@ protected:
|
||||||
|
|
||||||
float _shadowsMaxDistance{ 40.0f };
|
float _shadowsMaxDistance{ 40.0f };
|
||||||
float _shadowsBiasScale{ 1.0f };
|
float _shadowsBiasScale{ 1.0f };
|
||||||
|
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();
|
||||||
|
|
0
libraries/render-utils/src/LightStage.cpp
Normal file → Executable file
0
libraries/render-utils/src/LightStage.cpp
Normal file → Executable file
0
libraries/render-utils/src/LightStage.h
Normal file → Executable file
0
libraries/render-utils/src/LightStage.h
Normal file → Executable file
94
libraries/render-utils/src/RenderShadowTask.cpp
Normal file → Executable file
94
libraries/render-utils/src/RenderShadowTask.cpp
Normal file → Executable file
|
@ -56,7 +56,6 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende
|
||||||
auto fadeEffect = DependencyManager::get<FadeEffect>();
|
auto fadeEffect = DependencyManager::get<FadeEffect>();
|
||||||
initZPassPipelines(*shapePlumber, state, fadeEffect->getBatchSetter(), fadeEffect->getItemUniformSetter());
|
initZPassPipelines(*shapePlumber, state, fadeEffect->getBatchSetter(), fadeEffect->getItemUniformSetter());
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto setupOutput = task.addJob<RenderShadowSetup>("ShadowSetup", input);
|
const auto setupOutput = task.addJob<RenderShadowSetup>("ShadowSetup", input);
|
||||||
const auto queryResolution = setupOutput.getN<RenderShadowSetup::Output>(1);
|
const auto queryResolution = setupOutput.getN<RenderShadowSetup::Output>(1);
|
||||||
const auto shadowFrame = setupOutput.getN<RenderShadowSetup::Output>(3);
|
const auto shadowFrame = setupOutput.getN<RenderShadowSetup::Output>(3);
|
||||||
|
@ -318,18 +317,78 @@ RenderShadowSetup::RenderShadowSetup() :
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderShadowSetup::configure(const Config& configuration) {
|
void RenderShadowSetup::configure(const Config& configuration) {
|
||||||
setConstantBias(0, configuration.constantBias0);
|
distanceTriggeredByConfig = _globalMaxDistance != configuration.globalMaxDistance;
|
||||||
setSlopeBias(0, configuration.slopeBias0);
|
biasTriggeredByConfig = _biasInput != configuration.biasInput;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
setConstantBias(0, constant0);
|
||||||
|
setSlopeBias(0, slope0);
|
||||||
|
|
||||||
#if SHADOW_CASCADE_MAX_COUNT > 1
|
#if SHADOW_CASCADE_MAX_COUNT > 1
|
||||||
setConstantBias(1, configuration.constantBias1);
|
setConstantBias(1, constant1);
|
||||||
setSlopeBias(1, configuration.slopeBias1);
|
setConstantBias(2, constant2);
|
||||||
setConstantBias(2, configuration.constantBias2);
|
setConstantBias(3, constant3);
|
||||||
setSlopeBias(2, configuration.slopeBias2);
|
|
||||||
setConstantBias(3, configuration.constantBias3);
|
setSlopeBias(1, slope1);
|
||||||
setSlopeBias(3, configuration.slopeBias3);
|
setSlopeBias(2, slope2);
|
||||||
|
setSlopeBias(3, slope3);
|
||||||
#endif
|
#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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderShadowSetup::calculateBiases() {
|
||||||
|
// slope scaling values derived from ratio between original constantBias and slopeBias pairs
|
||||||
|
const std::array<float, 4> SLOPE_SCALES = {{ 2.7f, 3.0f, 3.7f, 3.5f }};
|
||||||
|
const float CONVERT_BIAS = 100.0f;
|
||||||
|
const float MIN_SCALE_DIVISOR = 0.5f;
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
std::array<float, 4> localConstants;
|
||||||
|
std::array<float, 4> localSlopes;
|
||||||
|
float scaleFactor = 1.0f;
|
||||||
|
|
||||||
|
for (int i = 0; i < SHADOW_CASCADE_MAX_COUNT; i++) {
|
||||||
|
scaleFactor = convertedBias * (cacasdeDistances[0] / glm::max(MIN_SCALE_DIVISOR, cacasdeDistances[i + 4])) * inverseResolution;
|
||||||
|
localConstants[i] = cacasdeDistances[i] * scaleFactor;
|
||||||
|
localSlopes[i] = cacasdeDistances[i] * scaleFactor * SLOPE_SCALES[i];
|
||||||
|
setConstantBias(i, localConstants[i]);
|
||||||
|
setSlopeBias(i, localSlopes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RenderShadowSetup::setConstantBias(int cascadeIndex, float value) {
|
void RenderShadowSetup::setConstantBias(int cascadeIndex, float value) {
|
||||||
_bias[cascadeIndex]._constant = value * value * value * 0.004f;
|
_bias[cascadeIndex]._constant = value * value * value * 0.004f;
|
||||||
}
|
}
|
||||||
|
@ -368,14 +427,29 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, c
|
||||||
if (!_globalShadowObject) {
|
if (!_globalShadowObject) {
|
||||||
_globalShadowObject = std::make_shared<LightStage::Shadow>(currentKeyLight, SHADOW_CASCADE_COUNT);
|
_globalShadowObject = std::make_shared<LightStage::Shadow>(currentKeyLight, SHADOW_CASCADE_COUNT);
|
||||||
}
|
}
|
||||||
|
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);
|
||||||
|
|
||||||
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) {
|
||||||
|
|
32
libraries/render-utils/src/RenderShadowTask.h
Normal file → Executable file
32
libraries/render-utils/src/RenderShadowTask.h
Normal file → Executable 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,9 +73,11 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
CullFunctor _cullFunctor;
|
CullFunctor _cullFunctor;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const float DEFAULT_BIAS_INPUT = 0.5f;
|
||||||
|
const float DEFAULT_MAX_DISTANCE = 40.0f;
|
||||||
|
|
||||||
class RenderShadowSetupConfig : public render::Job::Config {
|
class RenderShadowSetupConfig : public render::Job::Config {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(float constantBias0 MEMBER constantBias0 NOTIFY dirty)
|
Q_PROPERTY(float constantBias0 MEMBER constantBias0 NOTIFY dirty)
|
||||||
|
@ -87,7 +88,12 @@ class RenderShadowSetupConfig : public render::Job::Config {
|
||||||
Q_PROPERTY(float slopeBias1 MEMBER slopeBias1 NOTIFY dirty)
|
Q_PROPERTY(float slopeBias1 MEMBER slopeBias1 NOTIFY dirty)
|
||||||
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 globalMaxDistance MEMBER globalMaxDistance NOTIFY dirty)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
float biasInput{ DEFAULT_BIAS_INPUT };
|
||||||
|
float globalMaxDistance{ DEFAULT_MAX_DISTANCE };
|
||||||
|
|
||||||
float constantBias0{ 0.15f };
|
float constantBias0{ 0.15f };
|
||||||
float constantBias1{ 0.15f };
|
float constantBias1{ 0.15f };
|
||||||
|
@ -114,7 +120,6 @@ public:
|
||||||
void run(const render::RenderContextPointer& renderContext, const Input& input, Output& output);
|
void run(const render::RenderContextPointer& renderContext, const Input& input, Output& output);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
ViewFrustumPointer _cameraFrustum;
|
ViewFrustumPointer _cameraFrustum;
|
||||||
ViewFrustumPointer _coarseShadowFrustum;
|
ViewFrustumPointer _coarseShadowFrustum;
|
||||||
struct {
|
struct {
|
||||||
|
@ -125,8 +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::array<float, 8> cacasdeDistances; // 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 calculateBiases();
|
||||||
};
|
};
|
||||||
|
|
||||||
class RenderShadowCascadeSetup {
|
class RenderShadowCascadeSetup {
|
||||||
|
|
2
libraries/render-utils/src/Shadow.slh
Normal file → Executable file
2
libraries/render-utils/src/Shadow.slh
Normal file → Executable file
|
@ -63,7 +63,7 @@ ShadowSampleOffsets evalShadowFilterOffsets(vec4 position) {
|
||||||
coords.y += (index & 2) >> 1;
|
coords.y += (index & 2) >> 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Offset for efficient PCF, see http://http.developer.nvidia.com/GPUGems/gpugems_ch11.html
|
// Offset for efficient PCF, see https://developer.nvidia.com/gpugems/GPUGems/gpugems_ch11.html
|
||||||
ivec2 offset = coords & ivec2(1,1);
|
ivec2 offset = coords & ivec2(1,1);
|
||||||
offset.y = (offset.x+offset.y) & 1;
|
offset.y = (offset.x+offset.y) & 1;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue