diff --git a/Engine/src/Renderer/SceneRenderer.cpp b/Engine/src/Renderer/SceneRenderer.cpp index 4b573b2..7dce399 100644 --- a/Engine/src/Renderer/SceneRenderer.cpp +++ b/Engine/src/Renderer/SceneRenderer.cpp @@ -31,9 +31,14 @@ namespace Engine namespace { - // 相机裁剪范围(与 BuildFrame 中 GetProjection 的参数一致) + // 相机裁剪范围(UE 编辑器视口语义:near = 10cm;far 拉远到 + // "无限"级——UE 的 far clip 默认就是不裁剪,深度精度由 near 主导, + // far 取多大都不损近处精度)。阴影距离独立(UE DirectionalLight + // 的 shadow distance 同构):级联分割只覆盖 kShadowDistance, + // 更远无阴影,避免级联跟着 far 拉爆近处阴影分辨率 constexpr f32 kCameraNear = 0.1f; - constexpr f32 kCameraFar = 100.0f; + constexpr f32 kCameraFar = 10000.0f; + constexpr f32 kShadowDistance = 100.0f; // 实用分割插值因子(0=均匀,1=对数;0.6 是业界常用值) constexpr f32 kCascadeLambda = 0.6f; @@ -170,11 +175,12 @@ namespace Engine constexpr u32 N = kMaxCascades; // ---- 1. 实用分割:均匀与对数分割按 λ 插值(视图深度,正值)---- + //(分割覆盖 [near, kShadowDistance];kCameraFar 只管主投影裁剪) f32 splits[N]; for (u32 i = 1; i <= N; ++i) { const f32 t = static_cast(i) / N; - const f32 uniform = kCameraNear + (kCameraFar - kCameraNear) * t; - const f32 log = kCameraNear * glm::pow(kCameraFar / kCameraNear, t); + const f32 uniform = kCameraNear + (kShadowDistance - kCameraNear) * t; + const f32 log = kCameraNear * glm::pow(kShadowDistance / kCameraNear, t); splits[i - 1] = glm::mix(uniform, log, kCascadeLambda); } for (u32 c = 0; c < N; ++c) { @@ -199,6 +205,10 @@ namespace Engine for (u32 c = 0; c < N; ++c) { const f32 d0 = (c == 0) ? kCameraNear : splits[c - 1]; const f32 d1 = splits[c]; + // 视图深度 → 视锥棱边参数:棱边上 z_view 线性(near/far 角点 + // 都在各自平面上),farC 反投影自主投影 far 面,故 t 相对 + // kCameraFar 归一;splits 只覆盖 [near, kShadowDistance], + // t 必然远小于 1 → 自然截出阴影范围内的切片 const f32 t0 = (d0 - kCameraNear) / (kCameraFar - kCameraNear); const f32 t1 = (d1 - kCameraNear) / (kCameraFar - kCameraNear); @@ -285,7 +295,7 @@ namespace Engine const f32 aspect = static_cast(targetExtent.width) / static_cast(targetExtent.height); ubo.view = camera->GetView(*camTransform); - ubo.proj = camera->GetProjection(aspect, 0.1f, 100.0f); + ubo.proj = camera->GetProjection(aspect, kCameraNear, kCameraFar); // 未抖动投影:velocity 的当前帧 clip 位置用它(抖动不能进 velocity) ubo.projNoJitter = ubo.proj;