Files
XCEngine/docs/plan/NewEditor_3D渲染主链正式接入计划_2026-04-12.md

11 KiB
Raw Blame History

NewEditor 3D渲染主链正式接入计划

日期: 2026-04-12

1. 文档定位

这份计划替代此前那份偏宽泛的《NewEditor 对标旧 Editor 迁移重建计划》。

当前主线已经很明确:

  • new_editor 的 UI 基础壳已经足够继续往上承接。
  • 真正卡住后续重建编辑器的,不再是普通面板样式或 tab/dock 行为。
  • 当前最大的主阻塞,是 Scene / Game 还没有接上旧 editor 里已经跑通的真实 3D 渲染主链。

因此,接下来要先做的不是继续铺业务面板,而是:

  1. 先把 new_editor 的宿主渲染链补齐。
  2. 再把旧 editor 的 viewport/rendering 主链正式迁入 new_editor
  3. Scene / Game 真正稳定输出真实 3D 画面后,再继续后续编辑器业务迁移。

2. 当前事实与根因判断

2.1 旧 editor 当前的真实可用主链

editor 的 Scene/Game viewport 不是面板里临时拼的,它已经形成了明确主链:

Application -> D3D12WindowRenderer -> ViewportHostService -> SceneRenderer -> ViewportRenderTargets -> ImGui texture presentation

当前关键代码入口:

  • editor/src/Application.cpp
  • editor/src/Platform/D3D12WindowRenderer.h
  • editor/src/Viewport/ViewportHostService.h
  • editor/src/panels/SceneViewPanel.cpp
  • editor/src/panels/GameViewPanel.cpp

2.2 new_editor 当前的真实状态

new_editor 现在已经有:

  • XCEditor UI 基础层
  • Win32 + NativeRenderer 宿主层
  • Hierarchy / Inspector / Console / Project 这些 hosted content 面板外壳

Scene / Game 这条线并没有真正接上旧 editor 的 render path。

当前缺口是结构性的:

  1. new_editor/app/Shell/ProductShellAsset.cpp 里,scenegame 仍然只是 HostedContent,还没有切到正式的 ViewportShell 主线。
  2. new_editor/app/Workspace/ProductEditorWorkspace.cpp 里,没有真正的 viewport service owner也没有 scene/game render request 生命周期。
  3. new_editor/Host/NativeRenderer.h/.cpp 当前是 Direct2D/DirectWrite 宿主,只支持它自己的位图纹理路径。
  4. engine/include/XCEngine/UI/Types.h 虽然已经有 UITextureHandleKind::ShaderResourceView,但 NativeRenderer 目前并没有真正消费这类引擎 render target。

2.3 根因结论

当前问题的根因不是“Scene 面板还没抄过来”,而是:

  • new_editor 宿主层还没有与引擎 Rendering + RHI 建立正式的 viewport 纹理桥接。
  • XCEditor 的 viewport 壳层虽然已经存在,但 new_editor 还没把它真正接到 GPU viewport frame 上。

所以这件事必须从宿主渲染架构开始修,不能从面板层糊。

3. 不可违背的执行原则

3.1 根因优先

  • 禁止 CPU 截图回读后再贴回 UI。
  • 禁止用 PNG/中间 bitmap/调试贴图冒充正式 viewport 输出。
  • 禁止在 SceneGame 面板内部偷偷持有一套临时渲染路径。

3.2 旧 editor 只作为基线,不照搬 ImGui 壳

  • 要复用旧 editor 已经验证过的 render host、viewport service、render target、object id、overlay 这些真实主链能力。
  • 但不要把 ImGui panel 那一层硬抄到 new_editor
  • 迁移时要抽出“引擎桥接能力”,接回 XCEditor 的 viewport shell。

3.3 Scene/Game 必须统一走正式 viewport 子系统

  • SceneGame 不能继续当普通 hosted content 面板处理。
  • 它们必须切到同一套 ViewportShell -> ViewportService -> RenderTargets -> RenderFrame 路径。
  • Scene/Game 的差异只能体现在 camera / overlay / input policy不应该体现在宿主渲染基础设施层。

3.4 每阶段都能独立验证

每一阶段结束都必须满足:

  • 能编译 XCUIEditorApp
  • 能运行 exe
  • 能给出明确的人工检查点

4. 目标架构

4.1 new_editor 最终应形成的 viewport 主链

目标主链:

Win32 Application -> Host Window Renderer -> XCEditor ViewportShell -> ProductViewportHostService -> SceneRenderer -> RHI RenderTargets -> Viewport Texture Bridge -> XCEditor Compose -> Window Present

分层责任:

  • Host
    • 管窗口、swapchain、command queue、command list、descriptor heap、present
  • XCEditor
    • 管 viewport 壳层布局、top bar、bottom bar、input bridge、状态显示
  • new_editor/app/Viewport
    • 管 Scene/Game viewport 请求、render target 生命周期、editor scene camera、input 解释、selection/picking/overlay
  • Rendering + RHI
    • 管真正的 scene render requests 和 GPU 输出

4.2 宿主层方向

NativeRenderer 当前的 D2D-only HwndRenderTarget 不能作为长期正式宿主。

新的宿主方向应当是:

  • 以 D3D12/RHI swapchain 作为主呈现链
  • 在这个主呈现链上承接 XCEditor UI 组合与 engine viewport 纹理

关于 2D UI 绘制策略,允许按实际情况调整实现,但边界必须固定:

  • 可以保留 D2D/DWrite 作为 2D 绘制后端,但它只能作为从属 UI compositor不能继续做整个窗口的唯一主呈现链
  • 如果 D2D 与 D3D12 的互操作复杂度失控,就切换为更直接的 GPU UI compositor
  • 无论选择哪条实现路径,都不能回退到 CPU 回读/贴图绕路

5. 执行阶段

阶段 A: 宿主渲染基础设施对齐

目标:

  • 先把 new_editor 宿主从“D2D-only 窗口绘制器”升级为“真正的窗口 render host”

主要工作:

  1. new_editor/Host 下建立正式的 window renderer
  2. 对齐旧 editor/src/Platform/D3D12WindowRenderer.h 的能力边界
  3. Application 能拿到:
    • RHIDevice
    • RHICommandQueue
    • RHICommandList
    • swapchain backbuffer surface
    • shader-visible descriptor heap
    • 每帧 begin/present 生命周期
  4. 保留并接回现有 DPI / resize / cursor / screenshot 生命周期

验收:

  • XCUIEditor.exe 能用新宿主稳定打开
  • 调整窗口尺寸时不会再出现位图式整体拉伸
  • 空窗口 clear/present 稳定,无闪烁、无明显 resize 延迟

阶段 B: Viewport 纹理桥接正式化

目标:

  • XCEditor viewport slot 真正能展示来自引擎 RHI 的 render target

主要工作:

  1. 明确 UITextureHandlenew_editor 中的正式 viewport 语义
  2. 补齐 ShaderResourceView 路径,而不是继续只支持文件位图
  3. 建立 render target -> UI texture handle 的生命周期管理
  4. 处理 descriptor/state/resize/recreate 规则

建议测试:

  • tests/UI/Editor/integration 下新增专门的 viewport GPU 纹理验证用例
  • 先用一个最小 GPU clear/checkerboard 纹理跑通 ViewportShell

验收:

  • ViewportShell 可显示真实 GPU render target
  • viewport 尺寸变化时,纹理尺寸和显示内容立即同步
  • 整个链路不含 readback / screenshot / 中间文件

阶段 C: Scene/Game 从 HostedContent 切到 ViewportShell

目标:

  • scenegame 不再是伪面板,而是正式 viewport panel

主要工作:

  1. 修改 ProductShellAssetscene/game 的 presentation 模型
  2. new_editor/app 建立正式的 viewport panel 装配点
  3. 建立 viewport request/response 数据模型:
    • requested size
    • presented frame
    • status text
    • capture/focus/input state

验收:

  • SceneGame 面板进入统一 viewport 壳层
  • 可以显示“真实 viewport frame”不再是纯 placeholder/调试文案

阶段 D: Scene 真实渲染最小闭环

目标:

  • 先让 Scene 面板输出旧 editor 那条真实 3D 场景渲染

主要工作:

  1. new_editor/app/Viewport 下建立 ProductViewportHostService
  2. 先迁移旧 ViewportHostService 的最小 spine:
    • scene editor camera state
    • scene viewport render targets
    • SceneRenderer 调用
    • status/failure policy
  3. 只先做“能稳定渲染”的最小闭环
  4. 暂时不带 gizmo不带复杂 overlay不带过多面板业务联动

验收:

  • Scene 面板显示真实 3D 场景
  • resize 时 render target 立即更新
  • 画面不是占位实现,不是 2D 假画面

阶段 E: Game 真实渲染闭环

目标:

  • 接上 Game 面板的真实 camera render path

主要工作:

  1. 对齐旧 editor 的 game viewport 请求方式
  2. 使用 active scene camera 或旧 editor 当前约定的 camera 选择规则
  3. 接上 game viewport 状态显示和 resize 规则

验收:

  • Game 面板显示真实场景相机输出
  • Scene 共享宿主基础设施,但 camera 语义独立

阶段 F: Scene 输入、导航、拾取

目标:

  • 在真实 3D 画面已经稳定的前提下,补回 Scene 交互

主要工作:

  1. 迁移 scene camera navigation
  2. 迁移 focus selection
  3. 迁移 object id picking
  4. 接回 selection 路由

验收:

  • 右键看、平移、缩放、聚焦等基础导航恢复
  • 点击对象能正确选中

阶段 G: Overlay / Gizmo / Editor 辅助渲染

目标:

  • 继续对齐旧 editor 的 editor-only viewport 叠加能力

主要工作:

  1. overlay frame cache
  2. overlay builder
  3. selection outline / orientation / transform gizmo
  4. Scene/Game 差异化 overlay policy

验收:

  • Scene overlay 与 gizmo 基本达到旧 editor 可用水平
  • 不因 overlay 引入新的渲染路径分叉

6. 并行切分策略

这条主线不是完全串行,但前两阶段有明显关键路径。

必须串行的部分

  1. 阶段 A 宿主 render host
  2. 阶段 B viewport 纹理桥接

这两步没完成,后面的 Scene/Game 真渲染都只能是假接入。

可以并行的部分

在 A/B 基本定型后,可并行拆为 3 组:

  1. Host
    • window renderer
    • present/frame lifecycle
    • viewport texture bridge
  2. app/Viewport
    • render targets
    • scene/game render request owner
    • status/failure policy
  3. XCEditor / app/Shell
    • scene/game 切换到 ViewportShell
    • viewport 状态展示
    • 相关 integration tests

7. 明确不做的事

这份计划期间,不做以下偏移主线的工作:

  • 不继续优先铺新的业务面板细节
  • 不先做 inspector/component editor 的深层业务联动
  • 不把 runtime UI 主题资源机制重新塞回 editor UI
  • 不用临时截图/静态贴图假装 viewport

8. 收口标准

满足以下条件,才算 new_editor 的 3D 渲染基础层正式收口:

  1. SceneGame 都显示真实 3D GPU 输出
  2. resize、DPI、focus、capture 行为稳定
  3. viewport 纹理链路不依赖 ImGui
  4. Scene 基础导航和 picking 恢复
  5. 后续继续重建 new_editor 时,不需要再回头推倒宿主渲染基础层

9. 旧计划归档说明

本轮归档:

  • docs/plan/used/NewEditor对标旧Editor迁移重建计划_2026-04-12.md

保留为参考文档,不归档:

  • docs/plan/Editor架构说明.md

原因:

  • 它仍然是旧 editor 分层与边界的有效参考
  • 但当前主线已经从“泛迁移计划”切换为“viewport / rendering 主链正式接入计划”