Files
XCEngine/docs/used/Renderer下一阶段_方向光阴影与光照闭环计划_完成归档_2026-04-05.md

14 KiB
Raw Blame History

Renderer 下一阶段:方向光阴影与光照闭环计划

日期:2026-04-04

1. 阶段背景

当前 shader / material / rendering 主线已经完成了这一阶段应有的基础闭环:

  • Shader 已具备 properties / passes / resources / backend variants 运行时契约
  • Material 已具备 schema 驱动的属性、纹理、常量布局与 pass resource binding plan
  • SceneRenderer / CameraRenderer / BuiltinForwardPipeline 已经打通
  • ObjectId / DepthOnly / ShadowCaster 已具备独立 pass 与 request 骨架
  • 三后端 D3D12 / OpenGL / Vulkan 的当前渲染集成测试已全绿

但这仍然只是“能稳定出图的基础 forward renderer”还不是“能承担引擎默认场景渲染”的完整运行时。
下一阶段不应该优先做 render graph,也不应该先追求更复杂的编辑器功能,而应该把当前 renderer 推进成一个真正可用的默认前向渲染器。

这一阶段的主线目标只有一句话:

把当前 renderer 从“无阴影的基础出图器”推进到“具备方向光、阴影、基础多光源闭环,并可稳定承接 Scene/Game 视图”的运行时渲染器。

2. 为什么下一步是这个

当前代码结构已经说明了下一阶段的最短主路径:

  • RenderSceneExtractor 里已经有 RenderLightingData.mainDirectionalLight
  • BuiltinForwardPipeline 已经在 per-object constants 中消费主方向光方向和颜色
  • CameraRenderRequest 已经有 shadowCaster / depthOnly / objectId request
  • BuiltinShadowCasterPass / BuiltinDepthOnlyPass 已经存在

也就是说:

  1. 光照数据通路已经有最小入口
  2. 阴影 pass 的执行骨架已经有了
  3. 缺的是把这些骨架真正接成 frame 级闭环

如果这时跳去做 render graph,只会把尚未收紧的运行时逻辑包上一层更复杂的调度壳。
如果这时去做更复杂的 editor 特效也是在建立在“runtime lighting 还不完整”的地基上。

所以本阶段应当严格沿着 Unity 风格的自然演进路径推进:

  1. 先把默认前向运行时补完整
  2. 再谈更高层调度与优化

3. 与 Unity 式架构的对齐原则

本阶段继续遵循现有总设计,不偏离 RHI -> Renderer -> Editor/Runtime 这条主分层:

  • RHI 只负责统一 GPU 抽象,不承载场景渲染逻辑
  • Renderer 负责场景提取、光照数据组织、shadow/depth/object-id/forward 等 pass 执行
  • Editor 只是 renderer 的宿主与附加 overlay/pass 使用方,不拥有独立的一套 runtime 渲染逻辑

与 Unity 对齐时,要注意以下边界:

  • 阴影图、主光照、相机渲染请求,这些属于 runtime renderer 的正式能力
  • grid、outline、gizmo、icon这些属于 editor 专属叠加能力
  • editor 需要复用 renderer但不能反向污染 runtime 主链

因此这一阶段做的方向光阴影、基础多光源、GameView/SceneView 统一接入,都是正式主线。
GPU picking、editor outline、gizmo 美术化这些,都不应抢主线优先级。

4. 当前真实现状

从当前代码看renderer 已具备但尚未闭环的点如下。

4.1 已经具备的能力

  • SceneRenderer 已支持多 camera request、camera stack、surface render area
  • CameraRenderer 已支持 pre -> shadowCaster -> depthOnly -> main pipeline -> objectId -> post
  • BuiltinForwardPipeline 已支持 ForwardLit / Unlit 的统一 shader/material contract
  • BuiltinObjectIdPass 已正式接入 object-id 渲染路径
  • BuiltinDepthOnlyPass / BuiltinShadowCasterPass 已经具备 pass 级执行能力
  • RenderSceneExtractor 已能提取主方向光

4.2 尚未闭环的能力

  • 阴影图尚未由 SceneRenderer/CameraRenderer 正式规划、分配、执行与回收
  • forward 主通道尚未消费 shadow map 结果
  • 光照仍停留在“单主方向光最小数据”,没有正式多光源提交模型
  • shadow request 目前更像通用 hook而不是 renderer 自动生成的正式帧请求
  • 缺少以“阴影正确性”为目标的正式集成测试场景
  • 缺少以“多光源正确性”为目标的正式集成测试场景

4.3 这意味着什么

当前 renderer 的问题已经不再是“架构没有”,而是:

架构有了,但 runtime lighting/shadow 这条主业务链尚未贯通。

5. 本阶段总体目标

本阶段拆成四个连续目标:

  1. 建立正式的方向光阴影闭环
  2. 建立正式的前向多光源数据通路
  3. 统一 SceneView / GameView 对 runtime renderer 的使用方式
  4. 为下一阶段的 post-process 与 renderer 扩展收紧边界

其中优先级严格如下:

  1. Directional Light + Shadow Map
  2. Forward 多光源
  3. Scene/Game 视图统一使用正式 renderer 能力
  4. 补文档、补测试、清理旧临时路径

6. 分阶段实施计划

6.1 Phase A方向光阴影闭环

目标

让场景中的主方向光真正生成 shadow map并在主 forward pass 中被采样,形成跨三后端稳定一致的阴影结果。

具体工作

A1. 正式定义 shadow frame 数据模型

新增或收紧 renderer 内部数据结构,至少明确:

  • 主方向光是否需要阴影
  • shadow map 尺寸与格式
  • light-space view/projection 矩阵
  • shadow caster 渲染 surface
  • forward receiver 采样所需的阴影参数

这里的目标不是先做复杂 cascades而是先做单张 directional shadow map MVP。

A2. 由 renderer 自动生成 shadow caster request

不能继续依赖测试或上层调用者手工拼 shadowCaster request。
应由 SceneRendererCameraRenderer 在主 camera 渲染前自动生成:

  • 主方向光对应的 shadow camera data
  • shadow surface
  • clear flags
  • shadow pass 执行顺序

也就是说,要把“有 shadow pass 骨架”提升成“runtime renderer 正式调度 shadow pass”。

A3. 收紧 BuiltinShadowCasterPass

确认并补齐以下行为:

  • 只渲染 castShadows = true 的可见物体
  • 正确处理 section/material pass 选择
  • 只依赖 shadow caster 所需最小资源
  • 在三后端下都使用统一的深度输出语义

A4. 在 BuiltinForwardPipeline 中消费 shadow map

forward pass 至少补齐:

  • shadow map SRV 绑定
  • light-space position 计算
  • shadow compare
  • 基础 bias
  • 基础 PCF 或最小稳定采样

这一阶段不追求高级阴影质量,但必须追求:

  • 没有明显自阴影灾难
  • 没有跨后端严重不一致
  • 测试图可稳定固化 GT

A5. 增加阴影集成测试

新增至少一个正式场景:

  • tests/Rendering/integration/directional_shadow_scene

场景要求:

  • 至少包含一盏方向光
  • 至少包含一个会投影的物体
  • 至少包含一个接收阴影的地面或大平面
  • 阴影边界、方向、遮挡关系都足够稳定,适合 GT 比对

验收标准

  • 三后端都能稳定生成方向光阴影
  • forward pass 正式消费 shadow map
  • directional_shadow_scene 三后端 GT 全绿
  • 不破坏现有全部 rendering integration

6.2 Phase B前向多光源闭环

目标

把当前只支持主方向光的 lighting 数据模型,推进为可正式承接多个灯光的前向运行时。

具体工作

B1. 扩展 RenderLightingData

从当前的:

  • mainDirectionalLight

扩展到至少可描述:

  • main directional light
  • additional directional lights
  • point lights
  • spot lights

注意这里不一定一步到位做完整 Unity 灯光体系,但要保证数据模型不会很快被推翻。

B2. 明确本阶段多光源策略

当前阶段建议使用:

  • 单主方向光
  • 有上限的 additional lights
  • CPU 侧整理一份稳定 light list
  • GPU 侧通过常量缓冲或结构化数据提交

本阶段不做

  • clustered lighting
  • tiled lighting
  • deferred lighting

这是为了保证先把可验证的前向路径收紧。

B3. 扩展 forward shader/material contract

补齐多光源所需的 shader 输入:

  • additional light count
  • light position / direction / color / range / spot angle
  • shadowed main light 与 non-shadowed additional lights 的职责边界

要求仍沿用当前的 shader/material/pass contract不要回退成硬编码散乱常量。

B4. 新增多光源集成测试

新增至少两个场景:

  • multi_light_scene
  • spot_light_scene

场景目标:

  • 验证 point/spot 的衰减与照明范围
  • 验证 additional lights 会真实影响画面
  • 验证三后端输出保持一致

验收标准

  • RenderSceneExtractor 能提取正式多光源数据
  • BuiltinForwardPipeline 能消费多光源
  • 新增多光源场景三后端 GT 全绿
  • 方向光阴影能力不被破坏

6.3 Phase CSceneView / GameView runtime 接入收紧

目标

让 editor 的场景与游戏视图都建立在同一套 runtime renderer 能力上,而不是继续沿着临时 editor 路径分叉。

具体工作

C1. 明确 runtime pass 与 editor overlay pass 的边界

正式定义:

  • runtime 正式 passshadow caster、depth only、forward、object-id、offscreen copy 等
  • editor 附加 passgrid、outline、icon、gizmo 等

要求:

  • runtime pass 可脱离 editor 独立工作
  • editor pass 只能叠加,不能挟持 runtime 主流程

C2. GameView 走正式相机渲染请求

GameView 必须通过标准 CameraRenderRequest 驱动 renderer不能再依赖 editor 特殊逻辑直接拼接。

C3. SceneView 继续复用 renderer

SceneView 应:

  • 复用正式相机渲染链
  • 在其上叠加 editor overlay
  • 允许 object-id / outline / grid 等继续作为 editor 增量能力存在

验收标准

  • SceneView 与 GameView 都走正式 renderer 主链
  • editor 专属 overlay 不污染 runtime pass
  • 不出现“editor 正常、runtime 不正常”或反之的分叉

6.4 Phase D收口与稳定性整理

目标

在新能力落地后,把这一阶段的测试、文档、边界彻底收紧。

具体工作

D1. 补齐测试矩阵

至少确保以下持续可跑:

  • shader_tests
  • material_tests
  • mesh_tests
  • rendering_unit_tests
  • 全部 tests/Rendering/integration

新增场景至少包括:

  • directional_shadow_scene
  • multi_light_scene
  • spot_light_scene

D2. 清理临时路径

逐项检查并收紧:

  • 是否仍有测试手工拼 shadow request
  • 是否仍有 runtime/editor 职责混用
  • 是否仍有与 shader/material contract 相冲突的旧 lighting 常量路径

D3. 文档归档

这一阶段结束后,应补一份阶段收口说明,并把过期计划归档到 docs/plan/used/

验收标准

  • 阴影、多光源、Scene/Game 接入均通过测试
  • 当前计划中的临时方案被收紧到清晰边界内
  • 下一阶段可以自然承接 skybox/post-process而不是继续补地基

7. 测试策略

这一阶段的测试必须比前一阶段更严格,因为它开始影响真正的场景表现。

7.1 单元测试

重点补以下测试:

  • RenderSceneExtractor 的多光源提取
  • shadow request 自动生成逻辑
  • shadow matrix / light camera 参数构建
  • forward shader resource binding 对 shadow map 的消费
  • additional lights 排序与裁剪规则

7.2 集成测试

必须新增:

  • directional_shadow_scene
  • multi_light_scene
  • spot_light_scene

保底回归集:

  • textured_quad_scene
  • unlit_scene
  • object_id_scene
  • backpack_scene
  • backpack_lit_scene
  • camera_stack_scene
  • transparent_material_scene
  • cull_material_scene
  • depth_sort_scene
  • material_state_scene
  • offscreen_scene

7.3 三后端要求

本阶段所有新增集成测试都必须同时覆盖:

  • D3D12
  • OpenGL
  • Vulkan

如果某一步只在单后端通过,不算完成。
这一阶段绝不接受“先在一个后端跑通,另外两个后面再补”的收口标准。

8. 明确不做

为了避免主线失控,这一阶段明确不做下面这些:

  • render graph
  • deferred renderer
  • clustered/tiled lighting
  • cascaded shadow maps
  • PCSS / VSM / EVSM 等高级阴影方案
  • post-process 大框架
  • shader graph
  • editor gizmo 的进一步美术化与交互打磨

这些都应该建立在“方向光阴影 + 基础多光源 + runtime renderer 稳定闭环”完成之后。

9. 风险点与处理策略

9.1 风险:阴影路径把 pass/resource contract 搞散

处理策略:

  • 阴影采样与 shadow caster 仍必须走正式 shader/material/pass contract
  • 不允许为了赶进度,在 pipeline 内重新堆一套散乱硬编码绑定

9.2 风险editor 需求重新污染 runtime 主线

处理策略:

  • SceneView 只复用 renderer
  • grid/outline/gizmo 始终作为 editor overlay
  • runtime 主链以 GameView/真实场景渲染为准

9.3 风险:三后端阴影精度差异导致 GT 不稳定

处理策略:

  • 第一版 shadow scene 场景构图应保守
  • 阈值控制应严格,但允许合理的小误差
  • 优先追求稳定一致,而不是追求复杂阴影表现

9.4 风险:多光源一步做太大

处理策略:

  • 先做“有限 additional lights 的前向提交”
  • 不提前引入 forward+ 或 deferred
  • 以可验证场景为主,不以理论最优为目标

10. 提交与执行节奏

这一阶段继续按“每一步可验证、每一步可提交”的节奏推进:

  1. 先做 Phase A 的数据模型与 shadow request 自动生成
  2. 测试通过后提交
  3. 再做 ShadowCaster -> Forward 的 shadow map 消费
  4. 测试通过后提交
  5. 再做 Phase B 的多光源数据模型与 shader 消费
  6. 测试通过后提交
  7. 最后做 Phase C / D 的接入收口与文档归档

每一步的“通过”都必须包含:

  • 至少相关 unit tests 通过
  • 至少相关 integration tests 通过
  • 如影响主线,必须补跑 rendering regression

11. 成功标准

本阶段完成时,应满足以下判断:

  • renderer 能正式生成并消费方向光阴影
  • renderer 能正式消费基础多光源
  • SceneView 与 GameView 都建立在统一 runtime renderer 主链上
  • editor overlay 与 runtime pass 边界清晰
  • rendering 测试体系在三后端下持续稳定

12. 一句话总结

下一阶段的核心不是“做更多花哨渲染功能”,而是:

把当前已经具备架构基础的 renderer推进成一个真正能承担默认场景渲染的 Unity 风格前向运行时。