From 82c55b39999a8710fd95c2afa96f039c3a258149 Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Mon, 13 Apr 2026 02:24:30 +0800 Subject: [PATCH] docs: rebuild main light shadow repair plan --- .../MainLight方向光阴影修复计划_2026-04-13.md | 227 ++++++++++++++++++ 1 file changed, 227 insertions(+) create mode 100644 docs/plan/MainLight方向光阴影修复计划_2026-04-13.md diff --git a/docs/plan/MainLight方向光阴影修复计划_2026-04-13.md b/docs/plan/MainLight方向光阴影修复计划_2026-04-13.md new file mode 100644 index 00000000..f2942d4c --- /dev/null +++ b/docs/plan/MainLight方向光阴影修复计划_2026-04-13.md @@ -0,0 +1,227 @@ +# MainLight 方向光阴影修复计划 + +日期: `2026-04-13` + +## 1. 文档定位 + +这份文档是基于当前仓库代码状态重新整理的版本,用来承接 MainLight 单张方向光阴影的后续修复工作。 + +需要明确: + +- 这不是对之前已删除计划文件的逐字恢复。 +- 这是一份按当前实现状态、最近两次提交和现有阴影链路重新整理的执行计划。 +- 当前目标不是上级联阴影,而是先把单张 MainLight 阴影做到可用。 + +## 2. 当前问题定义 + +当前 MainLight 阴影已经具备从规划、投射到接收采样的完整闭环,但实际效果仍然不可用,核心问题有两个: + +1. 自阴影过重,表面出现明显 acne。 +2. 阴影边缘呈现大块锯齿,采样质量不足。 + +当前阶段暂不解决: + +- 级联阴影 +- 点光 / 聚光阴影 +- 阴影时域稳定与降噪的完整方案 +- 多光源阴影编排 + +## 3. 当前阴影链路梳理 + +当前单张 MainLight 阴影主链如下: + +`SceneRenderRequestPlanner` +-> `DirectionalShadowRenderPlan` +-> `CameraRenderer` +-> `ShadowCaster Pass` +-> `RenderSceneData::lighting.mainDirectionalShadow` +-> `BuiltinForwardPipeline` +-> `forward-lit.shader / Toon.shader` + +关键代码位置: + +- 规划层 + - `engine/include/XCEngine/Rendering/Planning/SceneRenderRequestPlanner.h` + - `engine/src/Rendering/Planning/Internal/DirectionalShadowPlanning.cpp` +- 请求与运行时数据 + - `engine/include/XCEngine/Rendering/Planning/CameraRenderRequest.h` + - `engine/include/XCEngine/Rendering/FrameData/RenderSceneData.h` + - `engine/src/Rendering/Execution/CameraRenderer.cpp` +- ShadowCaster 消费 bias + - `engine/include/XCEngine/Rendering/Passes/BuiltinDepthStylePassBase.h` + - `engine/src/Rendering/Passes/BuiltinDepthStylePassBaseResources.cpp` + - `engine/assets/builtin/shaders/shadow-caster.shader` +- 接收端采样 + - `engine/src/Rendering/Pipelines/BuiltinForwardPipeline.cpp` + - `engine/assets/builtin/shaders/forward-lit.shader` + - `project/Assets/Shaders/Toon.shader` + +## 4. 已完成阶段 + +### Phase 0:阴影参数契约正式化 + +已完成,目标是先把原来散落在不同位置的 shadow 参数收成正式数据契约。 + +对应提交: + +- `2ee74e7` `rendering: formalize main light shadow params` + +完成结果: + +- MainLight shadow 的 map metrics / sampling 数据有了明确结构。 +- 规划层到运行时数据链路不再依赖匿名 float 参数拼装。 + +### Phase 1:bias 设置正式化并接入 ShadowCaster + +已完成,目标是把 caster bias 和 receiver bias 的职责拆清楚,并让 ShadowCaster 真正消费运行时设置。 + +对应提交: + +- `1d6f2e2` `rendering: formalize main light shadow bias settings` + +完成结果: + +- 新增 `DirectionalShadowSamplingSettings` +- 新增 `DirectionalShadowCasterBiasSettings` +- planner 能输出 sampling / caster bias 默认值 +- `ShadowCaster` pass 不再依赖 shader 内部写死的 `Offset` +- forward / toon 接收端继续消费统一的 shadow sampling contract + +## 5. 根因判断 + +### 5.1 自阴影严重的根因 + +当前 acne 的根因不是单一问题,而是以下几项叠加: + +1. caster bias 与 receiver bias 原先没有清晰契约,调参入口混乱。 +2. receiver 端 normal bias 和 depth bias 默认值没有经过系统标定。 +3. caster 端深度偏移之前由 shader 写死,无法和场景尺度、shadow map texel 尺度统一调整。 + +### 5.2 阴影锯齿严重的根因 + +当前接收端虽然已经做了一个固定 3x3 手写采样,但效果仍然偏糙,原因主要是: + +1. 当前仍然是单张 shadow map,分辨率预算有限。 +2. 阴影采样核是最基础的固定 3x3 box,没有更平滑的权重设计。 +3. `BuiltinForwardPipeline` 里的 shadow sampler 目前仍是 point sampler。 +4. 当前还没有专门面向“单张 MainLight 阴影可用性”的 filter 参数设计。 + +### 5.3 当前不应优先处理的方向 + +以下方向现在都不是第一优先级: + +- 直接上级联阴影 +- 直接引入更复杂的多光源阴影系统 +- 先大改 planner 架构 + +原因很简单:如果当前单张阴影的 bias 和 filter 基线都没有站稳,上级方案只会把问题放大。 + +## 6. 下一阶段执行顺序 + +## Phase 2:建立可用的 bias 基线 + +这是下一步最高优先级。 + +目标: + +- 明显压住自阴影 acne +- 不引入明显 peter-panning +- 让不同材质和几何体至少达到“能看”的单张阴影结果 + +本阶段只调这四个核心参数: + +- `DirectionalShadowCasterBiasSettings.depthBiasFactor` +- `DirectionalShadowCasterBiasSettings.depthBiasUnits` +- `DirectionalShadowSamplingSettings.receiverDepthBias` +- `DirectionalShadowSamplingSettings.normalBiasScale` + +执行要点: + +1. 先以默认值为基线做小步调参,不再混用 shader 内固定 offset。 +2. 先看 caster bias 是否足以压掉大面积 acne,再看 receiver bias 是否还需要补偿。 +3. `normalBiasScale` 只用于削减掠射角表面 acne,不能把它当成主修复手段。 +4. 调参顺序优先保证“角色和常见静态模型表面不脏”,再控制阴影悬浮。 + +验收标准: + +- 球、立方体、角色模型等常见几何体上没有大片自阴影脏斑。 +- 接触阴影没有整体漂浮一截。 +- forward-lit 与 toon 两条接收路径结果一致性不回退。 + +## Phase 3:升级单张阴影采样质量 + +这个阶段才开始处理“大块锯齿”。 + +目标: + +- 让当前单张 MainLight shadow 的边缘从“块状锯齿”变成“有限预算下可接受的软化边缘” + +优先处理项: + +1. 升级当前固定 3x3 box 采样,不再停留在最基础平均核。 +2. 明确是否继续走跨后端一致的手写 PCF,还是为 comparison sampler 单独补后端支持。 +3. 如果继续保持跨后端一致性优先,则先做更好的手写 PCF 核,再评估 comparison sampler。 + +本阶段建议的最小落地方案: + +- 先保留单张 shadow map +- 先保留当前主链结构 +- 把 receiver 端阴影采样从固定 3x3 平均核升级为更稳定的 PCF 核 +- 如有必要,再补 `filterRadiusInTexels` 一类的正式参数 + +验收标准: + +- 阴影边缘不再呈现明显的 1-bit 台阶块状感。 +- 角色和场景静态物体阴影边缘的可读性明显提升。 +- 不因为滤波升级导致阴影整体发灰或漏光严重。 + +## Phase 4:单张方向光阴影稳定性收口 + +在 bias 和 filter 达到可用以后,再收口稳定性问题。 + +目标: + +- 降低相机轻微移动时的 shadow crawl / shimmering + +重点项: + +1. 审查当前 shadow camera 拟合结果是否需要 texel snapping。 +2. 审查 ortho bounds 与 focus point 的稳定性。 +3. 重新评估 `boundsPadding` / `minDepthPadding` / `minDepthRange` 的默认值是否过保守或过激进。 + +说明: + +这一阶段仍然是“单张 MainLight 阴影修好”,不是进入级联阴影。 + +## Phase 5:为后续级联阴影预留演进点 + +只有前面几个阶段都稳定后,才进入这一阶段。 + +目标: + +- 让当前单张 MainLight 阴影实现不阻塞未来 CSM 演进 + +需要预留但暂不展开的点: + +- split 数据结构 +- 每级 shadow map / sampler / matrix contract +- 接收端 cascade 选择逻辑 +- 级联间过渡和稳定化 + +## 7. 推荐的提交切分 + +后续建议按下面的提交粒度推进: + +1. `rendering: tune main light shadow bias defaults` +2. `rendering: improve main light shadow receiver filtering` +3. `rendering: stabilize single-map directional shadow fitting` + +## 8. 当前结论 + +当前正确的下一步不是“直接做级联阴影”,而是: + +1. 先把 bias 默认值标定到可用区间。 +2. 再把当前接收端采样升级成真正可用的单张 shadow filter。 +3. 最后再处理单张阴影稳定性。 + +只有这三步完成,当前 MainLight 阴影才算真正脱离“占位实现”。