Plan new editor viewport render host migration

This commit is contained in:
2026-04-12 22:35:23 +08:00
parent e86d260d64
commit a660fc489a
2 changed files with 333 additions and 0 deletions

View File

@@ -0,0 +1,333 @@
# 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` 里,`scene``game` 仍然只是 `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 输出。
- 禁止在 `Scene``Game` 面板内部偷偷持有一套临时渲染路径。
### 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 子系统
- `Scene``Game` 不能继续当普通 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. 明确 `UITextureHandle``new_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
目标:
-`scene``game` 不再是伪面板,而是正式 viewport panel
主要工作:
1. 修改 `ProductShellAsset``scene/game` 的 presentation 模型
2.`new_editor/app` 建立正式的 viewport panel 装配点
3. 建立 viewport request/response 数据模型:
- requested size
- presented frame
- status text
- capture/focus/input state
验收:
- `Scene``Game` 面板进入统一 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. `Scene``Game` 都显示真实 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 主链正式接入计划”