diff --git a/src/core/config.h b/src/core/config.h index 62a18de..8d2c1bc 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -22,9 +22,9 @@ inline constexpr float kShadowCascadeRadiusMargin = 10.0f; inline constexpr float kShadowClipBaseRadius = 30.0f; // When using dynamic pullback, compute it from the covered XY range of each level. // pullback = max(kShadowClipPullbackMin, cover * kShadowClipPullbackFactor) -inline constexpr float kShadowClipPullbackFactor = 1.5f; // fraction of XY half-size behind center -inline constexpr float kShadowClipForwardFactor = 1.5f; // fraction of XY half-size in front of center for zFar -inline constexpr float kShadowClipPullbackMin = 10.0f; // lower bound on pullback so near levels don’t collapse +inline constexpr float kShadowClipPullbackFactor = 2.5f; // fraction of XY half-size behind center +inline constexpr float kShadowClipForwardFactor = 2.5f; // fraction of XY half-size in front of center for zFar +inline constexpr float kShadowClipPullbackMin = 160.0f; // lower bound on pullback so near levels don’t collapse // Additional Z padding for the orthographic frustum along light direction inline constexpr float kShadowClipZPadding = 40.0f; diff --git a/src/scene/vk_scene.cpp b/src/scene/vk_scene.cpp index d8f7ae9..2c10f45 100644 --- a/src/scene/vk_scene.cpp +++ b/src/scene/vk_scene.cpp @@ -110,6 +110,7 @@ void SceneManager::update_scene() // Clipmap shadow setup (directional). Each level i covers a square region // around the camera in the light's XY plane with radius R_i = R0 * 2^i. // The region center is snapped to the light-space texel grid for stability. + static const float kAheadBlend[kShadowCascadeCount] = {0.2f, 0.5f, 0.75f, 1.0f}; { const glm::mat4 invView = glm::inverse(view); const glm::vec3 camPos = glm::vec3(invView[3]); @@ -139,8 +140,10 @@ void SceneManager::update_scene() const float fu = glm::dot(camFwd, right); const float fv = glm::dot(camFwd, up); - const float u = glm::dot(camPos, right) + fu * ahead; - const float v = glm::dot(camPos, up) + fv * ahead; + const glm::vec3 aheadXY = right * (fu * ahead) + up * (fv * ahead); + + const float u = glm::dot(camPos + aheadXY, right) + fu * ahead; + const float v = glm::dot(camPos + aheadXY, up) + fv * ahead; const float texel = (2.0f * cover) / float(kShadowMapResolution); const float uSnapped = floorf(u / texel) * texel; @@ -148,7 +151,7 @@ void SceneManager::update_scene() const float du = uSnapped - u; const float dv = vSnapped - v; - const glm::vec3 center = camPos + right * du + up * dv; + const glm::vec3 center = camPos + aheadXY * kAheadBlend[ci] + right * du + up * dv; const float pullback = glm::max(kShadowClipPullbackMin, cover * kShadowClipPullbackFactor); const glm::vec3 eye = center - L * pullback;