Switched to 4 cascades for key light and working on a better distribution

This commit is contained in:
Olivier Prat 2017-12-05 18:57:04 +01:00
parent c0ca7a129d
commit e16b427ab6
2 changed files with 15 additions and 8 deletions

View file

@ -23,7 +23,7 @@ const glm::mat4 LightStage::Shadow::_biasMatrix{
0.5, 0.5, 0.5, 1.0 }; 0.5, 0.5, 0.5, 1.0 };
const int LightStage::Shadow::MAP_SIZE = 1024; const int LightStage::Shadow::MAP_SIZE = 1024;
const unsigned int LightStage::SUN_SHADOW_CASCADE_COUNT{ 3 }; const unsigned int LightStage::SUN_SHADOW_CASCADE_COUNT{ 4 };
const LightStage::Index LightStage::INVALID_INDEX { render::indexed_container::INVALID_INDEX }; const LightStage::Index LightStage::INVALID_INDEX { render::indexed_container::INVALID_INDEX };
LightStage::LightStage() { LightStage::LightStage() {

View file

@ -240,26 +240,33 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, O
const auto nearClip = args->getViewFrustum().getNearClip(); const auto nearClip = args->getViewFrustum().getNearClip();
const auto farClip = args->getViewFrustum().getFarClip(); const auto farClip = args->getViewFrustum().getFarClip();
static const float HIGH_CASCADE_MAX_DISTANCE = 20.0f; // TODO : these parameters should be exposed to the user as part of the light entity parameters, no?
static const auto HIGH_CASCADE_MAX_DISTANCE = 40.0f;
static const auto LOW_CASCADE_MAX_DISTANCE = 1.5f;
// Power distribution. Lower the steepness to 1.0 for a more linear distribution or increase it for a
// tighter distribution around the view position.
static const auto CASCADE_DISTRIBUTION_STEEPNESS = 3.0f;
float maxCascadeDistance = HIGH_CASCADE_MAX_DISTANCE; float maxCascadeDistance = HIGH_CASCADE_MAX_DISTANCE;
float minCascadeDistance = nearClip; float minCascadeDistance = nearClip;
float shadowOverlapDistance = 0.0f; float shadowOverlapDistance = 0.0f;
if (globalShadow->getCascadeCount() > 1) { if (globalShadow->getCascadeCount() > 1) {
static const float LOW_CASCADE_MAX_DISTANCE = 3.0f; const auto deltaCascadeMaxDistance = (HIGH_CASCADE_MAX_DISTANCE - LOW_CASCADE_MAX_DISTANCE);
const float cascadeLevelScale = powf(HIGH_CASCADE_MAX_DISTANCE / LOW_CASCADE_MAX_DISTANCE, 1.0f / (globalShadow->getCascadeCount() - 1)); const auto maxAlpha = powf(_cascadeIndex / float(globalShadow->getCascadeCount() - 1), CASCADE_DISTRIBUTION_STEEPNESS);
const auto minAlpha = powf(std::max<float>(_cascadeIndex-1, 0) / float(globalShadow->getCascadeCount() - 1), CASCADE_DISTRIBUTION_STEEPNESS);
maxCascadeDistance = HIGH_CASCADE_MAX_DISTANCE / powf(cascadeLevelScale, globalShadow->getCascadeCount() - 1 - _cascadeIndex); maxCascadeDistance = LOW_CASCADE_MAX_DISTANCE + deltaCascadeMaxDistance * maxAlpha;
minCascadeDistance = maxCascadeDistance / cascadeLevelScale; minCascadeDistance = LOW_CASCADE_MAX_DISTANCE + deltaCascadeMaxDistance * minAlpha;
} }
shadowOverlapDistance = (maxCascadeDistance - minCascadeDistance) / 4.0f;
maxCascadeDistance += shadowOverlapDistance;
if (_cascadeIndex == 0) { if (_cascadeIndex == 0) {
minCascadeDistance = nearClip; minCascadeDistance = nearClip;
} else { } else {
minCascadeDistance = std::max(minCascadeDistance, nearClip); minCascadeDistance = std::max(minCascadeDistance, nearClip);
} }
shadowOverlapDistance = (maxCascadeDistance - minCascadeDistance) / 3.0f;
maxCascadeDistance += shadowOverlapDistance;
maxCascadeDistance = std::min(maxCascadeDistance, farClip); maxCascadeDistance = std::min(maxCascadeDistance, farClip);
globalShadow->setKeylightFrustum(_cascadeIndex, args->getViewFrustum(), minCascadeDistance, maxCascadeDistance, globalShadow->setKeylightFrustum(_cascadeIndex, args->getViewFrustum(), minCascadeDistance, maxCascadeDistance,
shadowOverlapDistance, HIGH_CASCADE_MAX_DISTANCE, SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR); shadowOverlapDistance, HIGH_CASCADE_MAX_DISTANCE, SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR);