docs: sync api and planning docs
This commit is contained in:
776
docs/used/API文档实时同步任务池_2026-04-03.md
Normal file
776
docs/used/API文档实时同步任务池_2026-04-03.md
Normal file
@@ -0,0 +1,776 @@
|
||||
# API文档实时同步任务池(2026-04-03,第三轮)
|
||||
|
||||
## 文档定位
|
||||
|
||||
这份任务池接替已归档的第二轮计划:
|
||||
|
||||
- `docs/plan/used/API文档实时同步任务池_2026-04-03_第二轮归档.md`
|
||||
|
||||
前两轮已经完成的重点包括:
|
||||
|
||||
- canonical API 目录结构收口
|
||||
- 大批缺页补齐
|
||||
- 多轮模板页清理与内容重写
|
||||
- 结构层审计修复到全绿
|
||||
|
||||
第三轮不再以“结构补齐”为主,而是专门处理“源码/测试已经变化,但 API 文档内容还没有跟上”的增量漂移。
|
||||
|
||||
## 当前复核快照
|
||||
|
||||
- 最近一次结构审计时间:`2026-04-07 01:26:32`
|
||||
- 审计命令:`python -B docs/api/_tools/audit_api_docs.py`
|
||||
- 当前结果:
|
||||
- `Public headers: 304`
|
||||
- `Editor source headers: 142`
|
||||
- `Valid header refs (canonical): 304`
|
||||
- `Invalid header refs: 0`
|
||||
- `Invalid source refs: 0`
|
||||
- `Valid source refs (Editor canonical): 142`
|
||||
- `Broken .md links: 0`
|
||||
- `Missing directory index pages: 0`
|
||||
- `Stale canonical doc tokens: 0`
|
||||
- `Stale editor doc tokens: 0`
|
||||
- `Stale editor canonical pages: 0`
|
||||
|
||||
这说明当前 canonical public header 覆盖与全部 Editor source-backed API 都已恢复全绿;此前集中在 `engine/include/XCEngine/UI/**` 的缺口已经收口完成。
|
||||
|
||||
### 已复核、暂不新开任务的区域
|
||||
|
||||
- `Resources/Material` / `RenderMaterialUtility` / `BuiltinForwardPipeline`
|
||||
- `Components/MeshFilterComponent` / `MeshRendererComponent`
|
||||
- `Scene` 中 builtin mesh / material 路径 round-trip
|
||||
- `Components/GameObject` 辅助访问器与层级辅助页
|
||||
|
||||
这些区域本轮已对照当前源码和测试抽查,暂时没有发现新的明确失配。
|
||||
|
||||
## 认领规则
|
||||
|
||||
- 一次只认领 `1` 个任务块。
|
||||
- 先把 `状态` 改成 `DOING`,再写 `认领人`。
|
||||
- 只允许修改自己任务块声明的 `写入范围`。
|
||||
- 所有改动都必须基于“当前头文件 + 当前实现 + 当前测试 + 当前真实调用链”。
|
||||
- 如果需要同步 `_guides` 或模块总览页,必须在对应任务块内明确列出,避免多人撞写。
|
||||
- 做完后必须补一次最小复核,至少确认相关链接和交叉引用没有坏掉。
|
||||
|
||||
## 任务池
|
||||
|
||||
## T01 Core / Asset `AssetDatabase` 显式重导入接口补页
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P0`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Core/Asset/AssetDatabase/**`
|
||||
- 主要源码依据:
|
||||
- `engine/include/XCEngine/Core/Asset/AssetDatabase.h`
|
||||
- `engine/src/Core/Asset/AssetDatabase.cpp`
|
||||
- `tests/Core/Asset/test_resource_manager.cpp`
|
||||
- 已确认问题:
|
||||
- 头文件已新增 `TryGetImportableResourceType()`、`ReimportAsset()`、`ReimportAllAssets()`,但 canonical 目录下没有对应方法页。
|
||||
- `AssetDatabase.md` 的公开方法表仍停在旧集合,没有把“可导入类型探测 / 单资产重导入 / 批量重导入”纳入公开能力。
|
||||
- `kCurrentImporterVersion` 已升到 `5`,总览页需要同步当前 importer 版本口径。
|
||||
- 产出要求:
|
||||
- 新增 `TryGetImportableResourceType.md`、`ReimportAsset.md`、`ReimportAllAssets.md`。
|
||||
- 更新 `AssetDatabase.md`,必要时同步 `ResolvedAsset.md` 的交叉引用。
|
||||
- 文档必须写清以下真实边界:
|
||||
- 只接受项目 `Assets/...` 内、存在且非目录的 source asset。
|
||||
- `TryGetImportableResourceType()` 只返回当前 importer 的 primary `ResourceType`;`Unknown` 直接失败。
|
||||
- `ReimportAsset()` 会重建单个 artifact、更新 source/artifact DB,并返回可直接消费的 `ResolvedAsset`。
|
||||
- `ReimportAllAssets()` 会遍历全部可导入 source record;单个条目失败不会中断全量循环,但最终返回总体成功位。
|
||||
|
||||
## T02 Core / Asset `AssetImportService` Library 工具接口与 `ImportedAsset` 语义同步
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P0`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Core/Asset/AssetImportService/**`
|
||||
- 主要源码依据:
|
||||
- `engine/include/XCEngine/Core/Asset/AssetImportService.h`
|
||||
- `engine/src/Core/Asset/AssetImportService.cpp`
|
||||
- `tests/Core/Asset/test_resource_manager.cpp`
|
||||
- 已确认问题:
|
||||
- 缺少 `ClearLibraryCache.md`、`ReimportAllAssets.md`、`ReimportAsset.md`、`TryGetImportableResourceType.md`。
|
||||
- `AssetImportService.md` 还没有把这批显式工具接口纳入生命周期和能力说明。
|
||||
- `ImportedAsset` 页虽然已存在,但需要按当前 `ConvertResolvedAsset()` 口径复核 `runtimeLoadPath`、`artifactDirectory`、`mainLocalID` 和成功路径语义。
|
||||
- 产出要求:
|
||||
- 新增缺失方法页,并更新 `AssetImportService.md`、必要时同步 `ImportedAsset.md` 与 `EnsureArtifact.md`。
|
||||
- 文档必须写清以下真实边界:
|
||||
- `ClearLibraryCache()` 会关停数据库、删除整个 `Library` 目录、再重新初始化;它本身不会批量重导入所有资产。
|
||||
- `RebuildLibraryCache()` 等于 `ClearLibraryCache() + ReimportAllAssets()`。
|
||||
- `ReimportAsset()` 会先 `Refresh()`,再强制重导入指定路径,返回 `ImportedAsset`。
|
||||
- `TryGetImportableResourceType()` 只是服务层转发;项目根无效时必须返回失败并把输出设为 `Unknown`。
|
||||
- `AssetImportService_Test.RebuildLibraryCacheKeepsStableAssetRefs` 证明:重建 `Library` 不应破坏现有 `.meta` 驱动的稳定 `AssetRef`。
|
||||
|
||||
## T03 Core / Asset `ResourceManager` 项目资产工具入口同步
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P0`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Core/Asset/ResourceManager/**`
|
||||
- 主要源码依据:
|
||||
- `engine/include/XCEngine/Core/Asset/ResourceManager.h`
|
||||
- `engine/src/Core/Asset/ResourceManager.cpp`
|
||||
- `tests/Core/Asset/test_resource_manager.cpp`
|
||||
- 已确认问题:
|
||||
- 缺少 `CanReimportProjectAsset.md`、`ReimportProjectAsset.md`、`ClearProjectLibraryCache.md`。
|
||||
- `ResourceManager.md` 还没有覆盖当前项目资产工具入口,也没有把这些接口和 `UnloadAll()` / `ProjectAssetIndex::RefreshFrom()` 的关系写清。
|
||||
- `RebuildProjectAssetCache.md`、`GetProjectLibraryRoot.md` 需要和新接口形成正确对比与交叉链接。
|
||||
- 产出要求:
|
||||
- 新增缺失方法页,更新 `ResourceManager.md`,必要时补交叉链接。
|
||||
- 文档必须写清以下真实边界:
|
||||
- 这批接口都要求 `m_resourceRoot` 非空;否则直接失败。
|
||||
- `CanReimportProjectAsset()` 只做“当前路径是否可导入”的无副作用判断。
|
||||
- `ReimportProjectAsset()` 会先 `UnloadAll()`,再重导入单路径资产,随后刷新 `ProjectAssetIndex`,成功时补记 `RememberResolvedPath(...)`。
|
||||
- `ClearProjectLibraryCache()` 会先卸载运行时资源,再清空 `Library`,然后刷新 snapshot,但不会自动批量重导入。
|
||||
- `ResourceManager_Test.ReimportProjectAssetBuildsArtifactForSelectedPath` 与 `RebuildProjectAssetCacheRefreshesLookupState` 是当前最直接的行为锚点。
|
||||
|
||||
## T04 Scripting / Mono `[SerializeField] private` 字段发现与持久化语义同步
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P0`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Scripting/Mono/Mono.md`
|
||||
- `docs/api/XCEngine/Scripting/Mono/MonoScriptRuntime/**`
|
||||
- `docs/api/_guides/Scripting/Scripting-Runtime-And-Field-Model.md`
|
||||
- `docs/api/_guides/Scripting/Project-Script-Assembly-And-Field-Sync.md`
|
||||
- 主要源码依据:
|
||||
- `engine/include/XCEngine/Scripting/Mono/MonoScriptRuntime.h`
|
||||
- `engine/src/Scripting/Mono/MonoScriptRuntime.cpp`
|
||||
- `managed/XCEngine.ScriptCore/SerializeField.cs`
|
||||
- `managed/GameScripts/FieldMetadataProbe.cs`
|
||||
- `managed/GameScripts/SerializeFieldProbe.cs`
|
||||
- `tests/Scripting/test_mono_script_runtime.cpp`
|
||||
- `tests/Scripting/test_project_script_assembly.cpp`
|
||||
- 已确认问题:
|
||||
- `Mono.md`、`TryGetClassFieldMetadata.md`、两篇 scripting guide 仍在沿用“只收录 public 实例字段”的旧口径。
|
||||
- 当前真实实现已经变成:
|
||||
- 过滤掉 `static` / `literal` / `init-only`
|
||||
- 然后接受“public 字段”或“标了 `[SerializeField]` 的 private 字段”
|
||||
- 最后再按支持类型过滤
|
||||
- 测试已经明确覆盖 `HiddenFlag`、`HiddenCounter`、`HiddenEnabled` 这类 `[SerializeField] private` 字段的元数据发现、默认值读取、运行时写回与场景 round-trip。
|
||||
- 未标 `[SerializeField]` 的 private 字段仍应保持忽略,但当前文档没有把这条边界讲清。
|
||||
- 产出要求:
|
||||
- 至少同步 `Mono.md`、`MonoScriptRuntime.md`、`TryGetClassFieldMetadata.md`、`TryGetClassFieldDefaultValues.md`。
|
||||
- 两篇 guide 需要补上 Unity 风格设计解释:
|
||||
- 为什么支持 `[SerializeField] private`
|
||||
- 这样做对 Inspector、字段持久化、重构安全性有什么好处
|
||||
- 哪些 private 字段仍不会进序列化层
|
||||
- 文档必须明确当前排除项:
|
||||
- `static`
|
||||
- `const/literal`
|
||||
- `readonly/init-only`
|
||||
- 不支持的字段类型
|
||||
- 未标 `[SerializeField]` 的 private 字段
|
||||
|
||||
## T05 Editor / Viewport `SceneViewportOverlayBuilder` provider-registry 口径同步
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportOverlayBuilder/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/Viewport.md`
|
||||
- `docs/api/XCEngine/Editor/Viewport/ViewportHostService/**`
|
||||
- 主要源码依据:
|
||||
- `editor/src/Viewport/SceneViewportOverlayBuilder.h`
|
||||
- `editor/src/Viewport/SceneViewportOverlayBuilder.cpp`
|
||||
- `editor/src/Viewport/SceneViewportOverlayProviders.h`
|
||||
- `editor/src/Viewport/SceneViewportOverlayProviders.cpp`
|
||||
- `editor/src/Viewport/ViewportHostService.h`
|
||||
- `tests/Editor/test_scene_viewport_overlay_providers.cpp`
|
||||
- 已确认问题:
|
||||
- `SceneViewportOverlayBuilder.md` 与 `Build.md` 仍沿用旧版“静态 / 无状态 / 单体 builder”口径,没有同步当前实例 builder + provider registry 模型。
|
||||
- `SceneViewportOverlayBuilder` 目录缺少 `Constructor.md` 与 `GetProviderRegistry.md`,导致新公开入口没有 canonical 页面。
|
||||
- `Viewport.md`、`ViewportHostService.md` 与 `SceneView-Overlay-Frame-Data.md` 仍把基础 editor overlay 的来源写成 `SceneViewportOverlayBuilder::Build(...)`,没有同步宿主当前持有成员 `m_sceneViewportOverlayBuilder` 且默认聚合 camera / light provider 的事实。
|
||||
- 完成记录:
|
||||
- 已重写 `SceneViewportOverlayBuilder.md` 与 `Build.md`,改成当前实例 builder + registry 分发语义。
|
||||
- 已新增 `Constructor.md` 与 `GetProviderRegistry.md`。
|
||||
- 已同步 `Viewport.md`、`ViewportHostService.md` 与 `SceneView-Overlay-Frame-Data.md` 的上层调用链表述。
|
||||
- 已重新运行 `python -B docs/api/_tools/audit_api_docs.py`,并确认 `Broken .md links: 0`、`Stale editor doc tokens: 0`、`Stale editor canonical pages: 0`。
|
||||
|
||||
## T06 Editor / Viewport HUD / interaction-actions / canonical overlay-state 口径同步
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Editor/Viewport/Viewport.md`
|
||||
- `docs/api/XCEngine/Editor/Viewport/IViewportHostService/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/ViewportHostService/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportHudOverlay/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportInteractionResolver/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportInteractionActions/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportTransformGizmoCoordinator/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportOverlayBuilder/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportOverlayProviders/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportEditorOverlayData/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportOverlayHitTester/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportEditorOverlayPass/**`
|
||||
- `docs/api/XCEngine/Editor/panels/SceneViewPanel/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportOverlayHandleBuilder/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/**`
|
||||
- 主要源码依据:
|
||||
- `editor/src/Viewport/SceneViewportHudOverlay.h`
|
||||
- `editor/src/Viewport/SceneViewportHudOverlay.cpp`
|
||||
- `editor/src/Viewport/SceneViewportInteractionResolver.h`
|
||||
- `editor/src/Viewport/SceneViewportInteractionResolver.cpp`
|
||||
- `editor/src/Viewport/SceneViewportInteractionActions.h`
|
||||
- `editor/src/Viewport/SceneViewportInteractionActions.cpp`
|
||||
- `editor/src/Viewport/SceneViewportTransformGizmoCoordinator.h`
|
||||
- `editor/src/Viewport/SceneViewportTransformGizmoCoordinator.cpp`
|
||||
- `editor/src/Viewport/IViewportHostService.h`
|
||||
- `editor/src/Viewport/ViewportHostService.h`
|
||||
- `editor/src/Viewport/SceneViewportOverlayBuilder.h`
|
||||
- `editor/src/Viewport/SceneViewportOverlayProviders.h`
|
||||
- `editor/src/Viewport/SceneViewportOverlayProviders.cpp`
|
||||
- `editor/src/Panels/SceneViewPanel.cpp`
|
||||
- `editor/src/Viewport/SceneViewportOverlayHandleBuilder.h`
|
||||
- `editor/src/Viewport/SceneViewportMoveGizmo.h`
|
||||
- `editor/src/Viewport/SceneViewportRotateGizmo.h`
|
||||
- `editor/src/Viewport/SceneViewportScaleGizmo.h`
|
||||
- `tests/Editor/test_scene_viewport_interaction_actions.cpp`
|
||||
- `tests/Editor/test_scene_viewport_transform_gizmo_coordinator.cpp`
|
||||
- `tests/Editor/test_scene_viewport_interaction_resolver.cpp`
|
||||
- `tests/Editor/test_scene_viewport_overlay_providers.cpp`
|
||||
- 已确认问题:
|
||||
- `IViewportHostService` / `ViewportHostService` / `SceneViewPanel` 文档仍在使用 `GetSceneViewInteractionOverlayFrameData(...)` 与 `SetSceneViewTransientTransformGizmoOverlayData(...)` 的旧双轨口径,但当前真实接口只剩 `SetSceneViewTransformGizmoOverlayState(...)` + `GetSceneViewEditorOverlayFrameData(...)`。
|
||||
- `SceneViewportOverlayBuilder` / `SceneViewportOverlayProviders` 文档没有同步当前 optional `transformGizmoOverlayState`、`CreateSceneViewportTransformGizmoOverlayProvider()`,以及默认 registry 已注册 camera / light / transform gizmo provider 的事实。
|
||||
- `SceneViewportEditorOverlayData` / `SceneViewportEditorOverlayPass` / `SceneViewportOverlayHitTester` 文档仍把 canonical frame 当成“仅世界线和图标”,没有同步 `screenTriangles` 与 `handleRecords` 已并入统一 frame data。
|
||||
- 缺少 `SceneViewportInteractionActions.h` 的 canonical 目录,导致交互动作规范层没有文档入口。
|
||||
- 缺少 `SceneViewportTransformGizmoCoordinator.h` 的 canonical 目录,且 `SceneViewPanel` 文档没有同步当前 overlay submission / lifecycle command helper 链路。
|
||||
- move / rotate / scale gizmo 的 draw-data 与 state-query 页面仍在传播“面板直接把 `GetDrawData()` 变成临时 render overlay”的旧口径,未同步统一 gizmo state + provider 模式。
|
||||
- 完成记录:
|
||||
- 已新增 `SceneViewportInteractionActions/**`,补齐 hover-state / click-action / dispatch API 页面。
|
||||
- 已新增 `SceneViewportTransformGizmoCoordinator/**`,补齐 overlay submission 与 gizmo lifecycle command 页面。
|
||||
- 已重写 `Viewport.md`、`IViewportHostService/**`、`ViewportHostService/**`、`SceneViewPanel/**`,统一到当前 `SetSceneViewTransformGizmoOverlayState(...)` + canonical `SceneViewportOverlayFrameData` 链路。
|
||||
- 已同步 `SceneViewportOverlayBuilder/**`、`SceneViewportOverlayProviders/**`、`SceneViewportEditorOverlayData/**`、`SceneViewportOverlayHitTester/**` 与 `SceneViewportEditorOverlayPass/**` 到当前 provider-registry + 统一 gizmo state 架构。
|
||||
- 已同步 move / rotate / scale gizmo 的 draw-data / state-query 页面到当前统一 state 消费口径。
|
||||
- 已重新运行 `python -B docs/api/_tools/audit_api_docs.py`,结果为:`Valid source refs (Editor canonical): 129`、`Invalid header refs: 0`、`Invalid source refs: 0`、`Broken .md links: 0`、`Stale editor canonical pages: 0`。
|
||||
|
||||
## T07 Scripting guide / 项目脚本程序集测试输出目录口径修正
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/_guides/Scripting/Project-Script-Assembly-And-Field-Sync.md`
|
||||
- 主要源码依据:
|
||||
- `managed/CMakeLists.txt`
|
||||
- `tests/Scripting/CMakeLists.txt`
|
||||
- `tests/Scripting/test_project_script_assembly.cpp`
|
||||
- 已确认问题:
|
||||
- guide 仍把 `tests/Scripting/test_project_script_assembly.cpp` 描述成“直接把 `assemblyDirectory` 指向 `project/Library/ScriptAssemblies`”。
|
||||
- 当前真实测试口径已经改成优先使用 `XCENGINE_TEST_PROJECT_MANAGED_OUTPUT_DIR`,由 `xcengine_test_project_managed_assemblies` target 提供测试专用输出目录;未配置时 fallback 到 `build/managed/ProjectScriptAssemblies`。
|
||||
- `project/Library/ScriptAssemblies/` 仍是 editor/runtime 项目程序集的真实输出目录,但它和测试专用输出目录不能混写成同一个概念。
|
||||
- 完成记录:
|
||||
- 已改写 `Project-Script-Assembly-And-Field-Sync.md`,把“真实项目输出目录”和“测试专用输出目录”拆开描述。
|
||||
- 已明确 `test_project_script_assembly.cpp` 验证的是“项目 `Assets/**/*.cs` 被编译成可发现的 `GameScripts.dll`”这条链路,而不是直接依赖工作树里的 `project/Library/ScriptAssemblies/` 快照。
|
||||
- 已重新运行 `python -B docs/api/_tools/audit_api_docs.py`,结果为:`Public headers: 244`、`Editor source headers: 129`、`Broken .md links: 0`、`Stale canonical doc tokens: 0`、`Stale editor canonical pages: 0`。
|
||||
|
||||
## T08 Rendering / `RenderMaterialUtility` builtin-pass 元数据与资源绑定契约补页
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Rendering/RenderMaterialUtility/**`
|
||||
- `docs/api/XCEngine/Rendering/Pipelines/BuiltinForwardPipeline/**`
|
||||
- `docs/api/XCEngine/Rendering/Passes/BuiltinObjectIdPass/**`
|
||||
- 主要源码依据:
|
||||
- `engine/include/XCEngine/Rendering/RenderMaterialUtility.h`
|
||||
- `engine/src/Rendering/Pipelines/BuiltinForwardPipeline.cpp`
|
||||
- `engine/src/Rendering/Passes/BuiltinObjectIdPass.cpp`
|
||||
- `tests/Rendering/unit/test_builtin_forward_pipeline.cpp`
|
||||
- `tests/Rendering/unit/test_render_scene_extractor.cpp`
|
||||
- 已确认问题:
|
||||
- `RenderMaterialUtility.h` 当前已经公开 `BuiltinMaterialPass`、binding-plan struct、legacy fallback 绑定构造和 builtin pass 元数据匹配 helper,但 canonical 文档树仍只覆盖旧的材质解析 / render-state 子集。
|
||||
- `MaterialConstantPayloadView` 与 `ResolveSchemaMaterialConstantPayload()` 文档仍停留在“只有 `data + size`”的旧口径,没有同步当前 `layout` 视图和 `layout.size == size` 的有效性约束。
|
||||
- `BuiltinForwardPipeline` 与 `BuiltinObjectIdPass` 文档虽然已经写到 explicit resource contract,但还没有把 canonical 入口回链到 `RenderMaterialUtility` 的 binding-plan helper。
|
||||
- 完成记录:
|
||||
- 已新增 builtin pass 元数据 / 资源绑定契约页面,覆盖 `BuiltinMaterialPass`、`BuiltinPassResourceBindingPlan`、`TryBuildBuiltinPassResourceBindingPlan()`、legacy fallback 绑定构造与 shader-pass 元数据匹配 helper。
|
||||
- 已新增 `MaterialConstantLayoutView.md`、`FindShaderPropertyBySemantic.md`,并同步 `MaterialConstantPayloadView.md`、`ResolveSchemaMaterialConstantPayload.md` 到当前 layout-aware 语义。
|
||||
- 已重写 `RenderMaterialUtility.md` 的公开类型 / 函数索引,把 builtin pass 规范化与 binding-plan 契约纳入模块总览。
|
||||
- 已同步 `BuiltinForwardPipeline.md` 与 `BuiltinObjectIdPass.md` 到当前 explicit binding-plan + legacy fallback 口径。
|
||||
|
||||
## T09 Rendering / `RenderMaterialUtility` 顶层 helper completeness 补页
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Rendering/RenderMaterialUtility/**`
|
||||
- 主要源码依据:
|
||||
- `engine/include/XCEngine/Rendering/RenderMaterialUtility.h`
|
||||
- `engine/src/Rendering/Pipelines/BuiltinForwardPipeline.cpp`
|
||||
- `tests/Rendering/unit/test_builtin_forward_pipeline.cpp`
|
||||
- `tests/Rendering/unit/test_render_scene_extractor.cpp`
|
||||
- 已确认问题:
|
||||
- `RenderMaterialUtility.h` 的顶层公开符号里,`IsForwardPassName()` 等 pass-name alias helper、`ToRHI*` 状态映射 helper,以及 `MaterialRenderStateHash` 仍无对应 canonical 页面。
|
||||
- `RenderMaterialUtility.md` 的索引也没有把这批顶层 helper 纳入公开函数 / 类型列表,导致文档目录和实际公开符号仍有一层颗粒度缺口。
|
||||
- 完成记录:
|
||||
- 已新增 `IsForwardPassName.md`、`IsUnlitPassName.md`、`IsDepthOnlyPassName.md`、`IsShadowCasterPassName.md`、`IsObjectIdPassName.md`。
|
||||
- 已新增 `ToRHICullMode.md`、`ToRHIComparisonFunc.md`、`ToRHIBlendFactor.md`、`ToRHIBlendOp.md` 与 `MaterialRenderStateHash.md`。
|
||||
- 已同步 `RenderMaterialUtility.md`,把这批 helper 和 hash functor 纳入模块索引。
|
||||
- 已对照 `RenderMaterialUtility.h` 的顶层公开类型 / 函数名,确认当前 canonical 页已全覆盖。
|
||||
|
||||
## T10 Active API docs / 测试路径大小写按真实目录统一
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/_guides/**`
|
||||
- `docs/api/XCEngine/**`
|
||||
- 主要源码依据:
|
||||
- `tests/`
|
||||
- 已确认问题:
|
||||
- 活跃文档里曾残留 `tests/core/...`、`tests/math/...`、`tests/scripting/...` 这类小写路径。
|
||||
- 当前工作树真实目录名是 `tests/Core/`、`tests/Core/Math/`、`tests/Scripting/`;继续沿用小写写法会让文档和工程现实脱节。
|
||||
- 这类问题与此前已收口的 `tests/Editor/` 一样,属于 Windows 工作树里最容易被忽略、但会持续制造噪音的路径口径漂移。
|
||||
- 完成记录:
|
||||
- 已把活跃 guide 与 canonical API 文档中的 `tests/Core/...`、`tests/Core/Math/...`、`tests/Scripting/...` 统一改成真实目录大小写。
|
||||
- 本轮只收口活跃文档;`docs/plan/used/`、`docs/used/` 等归档材料继续保留历史写法。
|
||||
|
||||
## T11 Editor / Viewport 新增 header helper 补页
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Editor/Viewport/Viewport.md`
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportEditorModes/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportInteractionFrame/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportNavigation/**`
|
||||
- `docs/api/_meta/rebuild-status.md`
|
||||
- 主要源码依据:
|
||||
- `editor/src/Viewport/SceneViewportEditorModes.h`
|
||||
- `editor/src/Viewport/SceneViewportInteractionFrame.h`
|
||||
- `editor/src/Viewport/SceneViewportNavigation.h`
|
||||
- `editor/src/Panels/SceneViewPanel.cpp`
|
||||
- 已确认问题:
|
||||
- 工作树里新增了 `SceneViewportEditorModes.h`、`SceneViewportInteractionFrame.h`、`SceneViewportNavigation.h` 三个 editor source header,但 canonical 文档树还没有对应目录页。
|
||||
- `Viewport.md` 也没有把这三块新 helper 纳入当前职责拆分,导致 Scene View 交互装配和导航状态管理的真实入口在模块总览里缺席。
|
||||
- 完成记录:
|
||||
- 已新增 `SceneViewportEditorModes/SceneViewportEditorModes.md`,收口 tool / pivot / transform-space 三类模式枚举。
|
||||
- 已新增 `SceneViewportInteractionFrame/SceneViewportInteractionFrame.md`,补齐 tool state、frame geometry、interaction frame state 与 resolve request 装配语义。
|
||||
- 已新增 `SceneViewportNavigation/SceneViewportNavigation.md`,补齐快捷键、look/pan 导航、capture flags 与 `SceneViewportInput` 构建逻辑。
|
||||
- 已补齐 `BuildSceneViewportTransformGizmoOverlayState.md`,并重写 `SceneViewPanel/**`、`SceneViewportOverlayHandleBuilder/**` 与 `SceneView-Interaction-And-Gizmo-Model.md` 的残留旧口径。
|
||||
- 已顺手修复 `BuildSceneViewportGridPassData.md` 指向旧页名的坏链接。
|
||||
- 已重新运行 `python -B docs/api/_tools/audit_api_docs.py`,确认 `Editor source headers: 133`、`Valid source refs (Editor canonical): 133`、`Invalid source refs: 0`、`Broken .md links: 0`。
|
||||
|
||||
## T12 Editor / Viewport `SceneViewportInteractionFrame` Phase 5G focus 与 presentation helper 同步
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportInteractionFrame/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportNavigation/SceneViewportNavigationUpdate.md`
|
||||
- `docs/api/XCEngine/Editor/Viewport/Viewport.md`
|
||||
- `docs/api/XCEngine/Editor/panels/SceneViewPanel/**`
|
||||
- `docs/api/_meta/rebuild-status.md`
|
||||
- 主要源码依据:
|
||||
- `editor/src/Viewport/SceneViewportInteractionFrame.h`
|
||||
- `editor/src/panels/SceneViewPanel.cpp`
|
||||
- `tests/Editor/test_scene_viewport_interaction_frame.cpp`
|
||||
- 已确认问题:
|
||||
- `SceneViewportInteractionFrame.h` 当前已经新增 `ShouldFocusSceneViewportAfterInteraction()`、`SceneViewportPresentationRequest` 与 `RefreshAndDrawSceneViewportPresentation()`,但 canonical 目录下还没有对应页面,模块总览也仍停在“只做交互前 frame-state 装配”的旧口径。
|
||||
- `SceneViewportNavigationUpdate.md` 仍写成 `beginLookDrag` / `beginPanDrag` 直接决定 `ImGui::SetWindowFocus()`;当前真实逻辑已经改成由 `ShouldFocusSceneViewportAfterInteraction(...)` 统一折叠 tool command、interaction action 与 navigation begin 标志。
|
||||
- `Viewport.md` 与 `SceneViewPanel/**` 对 `SceneViewportInteractionFrame` 的职责描述还没有完整纳入 focus / presentation helper 这一层尾段语义。
|
||||
- 完成记录:
|
||||
- 已新增 `ShouldFocusSceneViewportAfterInteraction.md`、`SceneViewportPresentationRequest.md` 与 `RefreshAndDrawSceneViewportPresentation.md`,补齐 `SceneViewportInteractionFrame.h` 的新增公开入口。
|
||||
- 已重写 `SceneViewportInteractionFrame.md`,把模块职责从“交互前 frame-state 装配”扩展到当前真实的 focus 决策与 presentation 尾段收口语义。
|
||||
- 已同步 `SceneViewportNavigationUpdate.md`、`Viewport.md`、`SceneViewPanel/Render.md` 与 `SceneViewPanel.md`,移除 `SetWindowFocus()` / presentation tail 的旧口径描述。
|
||||
- 已重新运行 `python -B docs/api/_tools/audit_api_docs.py`,确认 `Editor source headers: 133`、`Valid source refs (Editor canonical): 133`、`Invalid source refs: 0`、`Broken .md links: 0`、`Stale editor canonical pages: 0`。
|
||||
|
||||
## T13 Editor / Viewport `SceneViewportChrome` 与 `SceneViewPanel` 当前编排链补正
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportChrome/**`
|
||||
- `docs/api/XCEngine/Editor/panels/SceneViewPanel/**`
|
||||
- `docs/api/_meta/rebuild-status.md`
|
||||
- 主要源码依据:
|
||||
- `editor/src/Viewport/SceneViewportChrome.h`
|
||||
- `editor/src/Viewport/SceneViewportChrome.cpp`
|
||||
- `editor/src/panels/SceneViewPanel.h`
|
||||
- `editor/src/panels/SceneViewPanel.cpp`
|
||||
- `tests/Editor/test_scene_viewport_chrome.cpp`
|
||||
- 已确认问题:
|
||||
- `SceneViewportChrome.md` 仍写成“没有独立单元测试”,但当前工作树已经存在 `tests/Editor/test_scene_viewport_chrome.cpp`,并覆盖工具命令折叠与执行规则。
|
||||
- `SceneViewPanel.md` 与 `Render.md` 仍残留旧的 helper 列表和编排口径,没有完整对齐当前真实调用顺序,包括工具命令执行、focus 决策以及 `RefreshAndDrawSceneViewportPresentation(...)` 收口。
|
||||
- 完成记录:
|
||||
- 已修正 `SceneViewportChrome.md` 的测试锚点描述,明确区分“命令折叠规则已有单测”和“UI 绘制细节仍由源码调用链锚定”。
|
||||
- 已重写 `SceneViewPanel.md` 与 `Render.md`,按当前源码同步 `Chrome -> InteractionFrame -> Navigation -> InteractionActions -> Presentation` 的真实编排链。
|
||||
- 已重新运行 `python -B docs/api/_tools/audit_api_docs.py`,确认 `Editor source headers: 133`、`Valid source refs (Editor canonical): 133`、`Invalid source refs: 0`、`Broken .md links: 0`、`Stale editor canonical pages: 0`。
|
||||
|
||||
## T14 Core / Asset `ArtifactFormats` shader artifact 正文布局补页
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Core/Asset/ArtifactFormats/ArtifactFormats.md`
|
||||
- `docs/api/_meta/rebuild-status.md`
|
||||
- 主要源码依据:
|
||||
- `engine/include/XCEngine/Core/Asset/ArtifactFormats.h`
|
||||
- `engine/src/Core/Asset/AssetDatabase.cpp`
|
||||
- `engine/src/Resources/Shader/ShaderLoader.cpp`
|
||||
- `tests/Resources/Shader/test_shader_loader.cpp`
|
||||
- 已确认问题:
|
||||
- `ArtifactFormats.md` 的 shader artifact 小节当前只列出了几种头结构名,没有像 material / mesh 一样写清真实正文布局,缺少 name/source-path 字符串、property 段、per-pass tag/resource/variant 段以及 `compiledBinary` payload 的写入顺序。
|
||||
- 同页“读取侧”当前漏写了 `.xcshader` 的真实消费者 `ShaderLoader`。
|
||||
- 写入侧对 shader 只写了“产出 shader artifact”,没有和当前实现保持同样的主 artifact 文件名口径 `main.xcshader`。
|
||||
- 完成记录:
|
||||
- 已为 `ArtifactFormats.md` 的 shader artifact 小节补齐当前正文布局,明确名称/路径字符串、property 段、pass tag/resource/variant 段以及 `compiledBinary` payload 的写入顺序。
|
||||
- 已补充 shader artifact 的 schema 值、`main.xcshader` 主 artifact 文件名,以及读取侧 `ShaderLoader` 的真实消费链。
|
||||
- 已重新运行 `python -B docs/api/_tools/audit_api_docs.py`,确认 `Public headers: 244`、`Editor source headers: 133`、`Invalid header refs: 0`、`Invalid source refs: 0`、`Broken .md links: 0`、`Stale editor canonical pages: 0`。
|
||||
|
||||
## T15 Resources / Material `Material.h` 公开符号 completeness 补页
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Resources/Material/Material/**`
|
||||
- `docs/api/_meta/rebuild-status.md`
|
||||
- 主要源码依据:
|
||||
- `engine/include/XCEngine/Resources/Material/Material.h`
|
||||
- `engine/src/Resources/Material/Material.cpp`
|
||||
- `tests/Resources/Material/test_material.cpp`
|
||||
- `tests/Resources/Material/test_material_loader.cpp`
|
||||
- `tests/Rendering/unit/test_render_scene_extractor.cpp`
|
||||
- 已确认问题:
|
||||
- `Material.h` 当前已经公开 `renderQueue / renderState / shaderPass / tags / constant layout / change version` 这一整组运行时接口,但 canonical 文档树仍主要停留在“数值属性 + 纹理绑定”子集,缺少大量类型页与方法页。
|
||||
- 缺页不仅包括 `SetRenderQueue()`、`SetRenderState()`、`SetShaderPass()`、tag API、`GetConstantLayout()`、`FindConstantField()`、`GetChangeVersion()`、`RecalculateMemorySize()`,还包括 `MaterialRenderQueue`、`MaterialRenderState`、`MaterialConstantFieldDesc`、`MaterialTagEntry`、`PendingTextureLoadState` 等公开类型。
|
||||
- `Material/Material.md` 的声明索引也没有把这批 render metadata / tag / constant-layout 相关公开符号纳入模块总览。
|
||||
- 完成记录:
|
||||
- 已补齐 `Material.h` 当前公开的 render metadata / tag / constant-layout 相关类型页与方法页,并重写 `Material.md` 的模块索引。
|
||||
- 已把 `renderQueue / renderState / shaderPass / tags / texture bindings / properties / constant layout / change version` 这一整组运行时接口同步到 canonical 文档树。
|
||||
- 已重新运行 `python -B docs/api/_tools/audit_api_docs.py`,确认 `Public headers: 247`、`Editor source headers: 136`、`Invalid header refs: 0`、`Invalid source refs: 0`、`Broken .md links: 0`。
|
||||
|
||||
## T16 Editor / Viewport `SceneViewportOverlaySpriteResources` 新增头文件补页
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportOverlaySpriteResources/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/Viewport.md`
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportEditorOverlayData/SceneViewportEditorOverlayData.md`
|
||||
- `docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportEditorOverlayPass/**`
|
||||
- `docs/api/_meta/rebuild-status.md`
|
||||
- 主要源码依据:
|
||||
- `editor/src/Viewport/SceneViewportOverlaySpriteResources.h`
|
||||
- `editor/src/Viewport/SceneViewportOverlaySpriteResources.cpp`
|
||||
- `editor/src/Viewport/Passes/SceneViewportEditorOverlayPass.h`
|
||||
- `editor/src/Viewport/Passes/SceneViewportEditorOverlayPass.cpp`
|
||||
- `tests/Editor/test_scene_viewport_overlay_sprite_resources.cpp`
|
||||
- 已确认问题:
|
||||
- 工作树当前新增了 `SceneViewportOverlaySpriteResources.h`,但 canonical 文档树还没有对应目录页,导致结构审计一度出现 `Editor source headers: 136` / `Valid source refs (Editor canonical): 135`。
|
||||
- `SceneViewportEditorOverlayPass` 文档仍把 camera / light icon 纹理描述成 pass 内部细节,没有同步当前已经拆出的“资源路径解析 + RGBA 解码 + descriptor set 缓存”辅助层。
|
||||
- `SceneViewportOverlaySpriteTextureKind` 当前已经不再直接隐含具体文件路径;真实资源解析口径来自新头文件里的 helper 与 cache。
|
||||
- 完成记录:
|
||||
- 已新增 `SceneViewportOverlaySpriteResources` canonical 目录,补齐 texture-kind 映射、asset spec、pixel payload、像素加载与 GPU 资源缓存页面。
|
||||
- 已同步 `Viewport.md`、`SceneViewportEditorOverlayData.md` 与 `SceneViewportEditorOverlayPass/**`,把 sprite overlay 资源准备链路改写为当前真实的 helper-header + cache 模型。
|
||||
- 已重新运行 `python -B docs/api/_tools/audit_api_docs.py`,确认 `Public headers: 247`、`Editor source headers: 136`、`Valid source refs (Editor canonical): 136`、`Invalid source refs: 0`、`Broken .md links: 0`。
|
||||
|
||||
## T17 Editor / Viewport `SceneViewportShaderPaths` 兼容层化与 pass-spec wrapper 类型口径收口
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportShaderPaths/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportGridPass/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportSelectionOutlinePass/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportEditorOverlayPass/**`
|
||||
- `docs/api/XCEngine/Resources/BuiltinResources/BuiltinResources.md`
|
||||
- `docs/api/_meta/rebuild-status.md`
|
||||
- 主要源码依据:
|
||||
- `editor/src/Viewport/SceneViewportShaderPaths.h`
|
||||
- `editor/src/Viewport/SceneViewportResourcePaths.h`
|
||||
- `editor/src/Viewport/SceneViewportPassSpecs.h`
|
||||
- `editor/src/Viewport/ViewportHostRenderFlowUtils.h`
|
||||
- `editor/src/Viewport/SceneViewportRenderPlan.h`
|
||||
- `editor/src/Viewport/Passes/SceneViewportGridPass.h`
|
||||
- `editor/src/Viewport/Passes/SceneViewportGridPass.cpp`
|
||||
- `editor/src/Viewport/Passes/SceneViewportSelectionOutlinePass.h`
|
||||
- `editor/src/Viewport/Passes/SceneViewportSelectionOutlinePass.cpp`
|
||||
- `editor/src/Viewport/Passes/SceneViewportEditorOverlayPass.h`
|
||||
- `editor/src/Viewport/Passes/SceneViewportEditorOverlayPass.cpp`
|
||||
- `engine/include/XCEngine/Resources/BuiltinResources.h`
|
||||
- `tests/Editor/test_scene_viewport_shader_paths.cpp`
|
||||
- `tests/Editor/test_viewport_render_flow_utils.cpp`
|
||||
- 已确认问题:
|
||||
- `SceneViewportShaderPaths.h` 当前已经退化为只包含 `SceneViewportResourcePaths.h` 的兼容头,但部分文档仍把它写成路径 helper 的真实 owner。
|
||||
- `BuildSceneViewportGridPassData()`、`BuildSceneViewportSelectionOutlineStyle()`、两类 factory alias,以及 grid / selection-outline pass 适配页仍沿用旧签名,把 editor wrapper 类型写成 runtime `InfiniteGridPassData` / `ObjectIdOutlineStyle`。
|
||||
- `SceneViewportEditorOverlayPass` 与 `BuiltinResources.md` 仍残留一部分旧口径,没有完全同步 sprite resource cache 和新的 builtin shader 集合。
|
||||
- 完成记录:
|
||||
- 已把 `SceneViewportShaderPaths/**` 收口为“兼容 include 层 + 迁移说明”口径,并统一回链当前真实 owner `SceneViewportResourcePaths`。
|
||||
- 已同步 `ViewportHostRenderFlowUtils/**`、`SceneViewportRenderPlan/**`、`SceneViewportGridPass/**` 与 `SceneViewportSelectionOutlinePass/**` 到当前 `SceneViewportGridPassData` / `SceneViewportSelectionOutlineStyle` wrapper 类型,以及 `ToBuiltin...` 转换链。
|
||||
- 已补充 `SceneViewportEditorOverlayPass/**` 对 `SceneViewportOverlaySpriteResourceCache` 的引用,并把 `BuiltinResources.md` 改到当前 builtin shader 集合 `forward-lit / unlit / depth-only / shadow-caster / object-id`。
|
||||
- 已重新运行 `python -B docs/api/_tools/audit_api_docs.py`,确认 `Public headers: 247`、`Editor source headers: 136`、`Valid header refs (canonical): 247`、`Valid source refs (Editor canonical): 136`、`Broken .md links: 0`。
|
||||
|
||||
## T18 Rendering / `CameraRenderer` depth-only 与 shadow-caster pass 注入链补页
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Rendering/CameraRenderer/**`
|
||||
- 主要源码依据:
|
||||
- `engine/include/XCEngine/Rendering/CameraRenderer.h`
|
||||
- `engine/src/Rendering/CameraRenderer.cpp`
|
||||
- `tests/Rendering/unit/test_camera_scene_renderer.cpp`
|
||||
- 已确认问题:
|
||||
- `CameraRenderer.h` 当前已经公开 `SetDepthOnlyPass()`、`SetShadowCasterPass()`、`GetDepthOnlyPass()`、`GetShadowCasterPass()`,但 canonical 文档树还停留在只有主管线与 object-id pass 的旧索引。
|
||||
- `Constructor.md` 仍把最高阶构造重载写成只有 `(pipeline, objectIdPass)`,没有同步当前 `depthOnlyPass / shadowCasterPass` 注入点。
|
||||
- `Render.md` 仍把执行链写成 `pre -> pipeline -> object-id -> post -> overlay`,没有同步当前先跑 `shadowCaster` 和 `depthOnly` 请求的真实顺序。
|
||||
- 完成记录:
|
||||
- 已补齐 `SetDepthOnlyPass.md`、`SetShadowCasterPass.md`、`GetDepthOnlyPass.md`、`GetShadowCasterPass.md`。
|
||||
- 已重写 `CameraRenderer.md`、`Constructor.md`、`Render.md` 与 `Destructor.md`,同步当前 depth-only / shadow-caster pass 的持有、回退与执行链语义。
|
||||
- 已重新运行 `python -B docs/api/_tools/audit_api_docs.py`,确认 `Public headers: 247`、`Broken .md links: 0`、`Stale canonical doc tokens: 0`。
|
||||
|
||||
## T19 Editor / Viewport `SceneViewportOverlayFrameCache` 新增头文件补页
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportOverlayFrameCache/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/Viewport.md`
|
||||
- `docs/api/XCEngine/Editor/Viewport/ViewportHostService/SceneView-Overlay-Frame-Data.md`
|
||||
- `docs/api/_meta/rebuild-status.md`
|
||||
- 主要源码依据:
|
||||
- `editor/src/Viewport/SceneViewportOverlayFrameCache.h`
|
||||
- `editor/src/Viewport/SceneViewportOverlayFrameCache.cpp`
|
||||
- `editor/src/Viewport/ViewportHostService.h`
|
||||
- `tests/Editor/test_scene_viewport_overlay_frame_cache.cpp`
|
||||
- 已确认问题:
|
||||
- 工作树新增了 `SceneViewportOverlayFrameCache.h`,但 canonical 文档树没有对应目录页,导致结构审计一度出现 `Editor source headers: 137` / `Valid source refs (Editor canonical): 136`。
|
||||
- `Viewport` 与 `ViewportHostService/SceneView-Overlay-Frame-Data.md` 仍在用“宿主类内部散落 cache key”的旧口径,没有把 viewport 尺寸解析、内容签名与重建判定收口到新 helper header。
|
||||
- 完成记录:
|
||||
- 已新增 `SceneViewportOverlayFrameCache/**`,补齐 cache state、viewport 尺寸解析、内容签名、overlay 比较与重建判定页面。
|
||||
- 已同步 `Viewport.md` 与 `ViewportHostService/SceneView-Overlay-Frame-Data.md`,把 Scene View editor overlay frame 的缓存链路改写到当前 helper-header 模型。
|
||||
- 已重新运行 `python -B docs/api/_tools/audit_api_docs.py`,确认 `Public headers: 247`、`Editor source headers: 137`、`Valid source refs (Editor canonical): 137`、`Broken .md links: 0`。
|
||||
|
||||
## T20 Editor / Viewport `SceneViewportRenderPassBundle` 上层总览与 guide 口径同步
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Editor/Viewport/Viewport.md`
|
||||
- `docs/api/XCEngine/Editor/Viewport/ViewportHostService/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportGridPass/SceneViewportGridPass.md`
|
||||
- `docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportSelectionOutlinePass/SceneViewportSelectionOutlinePass.md`
|
||||
- `docs/api/_guides/Editor/Scene-Viewport-Render-Plan-And-Failure-Flow.md`
|
||||
- `docs/api/_meta/rebuild-status.md`
|
||||
- 主要源码依据:
|
||||
- `editor/src/Viewport/ViewportHostService.h`
|
||||
- `editor/src/Viewport/SceneViewportRenderPassBundle.h`
|
||||
- `editor/src/Viewport/SceneViewportRenderPassBundle.cpp`
|
||||
- `editor/src/Viewport/SceneViewportRenderPlan.h`
|
||||
- `editor/src/Viewport/Passes/SceneViewportGridPass.h`
|
||||
- `editor/src/Viewport/Passes/SceneViewportSelectionOutlinePass.h`
|
||||
- `tests/Editor/test_scene_viewport_render_pass_bundle.cpp`
|
||||
- `tests/Editor/test_viewport_render_flow_utils.cpp`
|
||||
- 已确认问题:
|
||||
- `SceneViewportRenderPassBundle` 的 canonical 页面虽然已经存在,但 `Viewport.md`、`ViewportHostService.md`、`Initialize-And-Shutdown.md`、`RenderRequestedViewports.md`、`SceneViewportRenderPlan.md` 与 Scene View render-plan guide 仍在传播旧口径,把宿主服务写成“直接持有三个 pass renderer”或“直接调用 `BuildSceneViewportRenderPlan(...)`”。
|
||||
- `SceneViewportGridPass.md`、`SceneViewportSelectionOutlinePass.md` 与 `SceneViewportGridPassFactory.md` 仍把 factory 绑定位置写成 `ViewportHostService` 上的旧 renderer 成员,而不是当前 bundle 内部成员。
|
||||
- `Viewport.md` 还没有把 `SceneViewportResourcePaths`、`SceneViewportPassSpecs`、`SceneViewportRenderPlan`、`SceneViewportRenderPassBundle` 与 `ViewportHostRenderFlowUtils` 纳入当前模块总览。
|
||||
- 完成记录:
|
||||
- 已同步 `Viewport.md`、`ViewportHostService/**`、`SceneViewportRenderPlan/**` 与 Scene View render-plan guide 到当前真实链路:`ViewportHostService -> SceneViewportRenderPassBundle -> BuildSceneViewportRenderPlan / ApplySceneViewportRenderPlan`。
|
||||
- 已修正 grid / selection-outline 相关页面,把 factory 绑定和 renderer 生命周期表述改成 bundle 持有模型,并补上新的上层交叉链接。
|
||||
- 已重新运行 `python -B docs/api/_tools/audit_api_docs.py`,确认 `Public headers: 247`、`Editor source headers: 138`、`Valid source refs (Editor canonical): 138`、`Broken .md links: 0`、`Stale editor canonical pages: 0`。
|
||||
|
||||
## T21 XCUI / `Resources/UI` / `UI/Types` / `UI/DrawData` / Editor transition header 补页
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P0`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Resources/UI/**`
|
||||
- `docs/api/XCEngine/UI/UI.md`
|
||||
- `docs/api/XCEngine/UI/Types/**`
|
||||
- `docs/api/XCEngine/UI/DrawData/**`
|
||||
- `docs/api/XCEngine/Editor/Editor.md`
|
||||
- `docs/api/XCEngine/Editor/XCUIBackend/**`
|
||||
- `docs/api/XCEngine/Editor/Platform/Platform.md`
|
||||
- `docs/api/XCEngine/Editor/Platform/D3D12WindowRendererImGuiInterop/**`
|
||||
- `docs/api/XCEngine/Editor/panels/panels.md`
|
||||
- `docs/api/XCEngine/Editor/panels/XCUIDemoPanel/**`
|
||||
- 主要源码依据:
|
||||
- `engine/include/XCEngine/Resources/UI/UIDocumentTypes.h`
|
||||
- `engine/include/XCEngine/Resources/UI/UIDocumentCompiler.h`
|
||||
- `engine/include/XCEngine/Resources/UI/UIDocuments.h`
|
||||
- `engine/include/XCEngine/Resources/UI/UIDocumentLoaders.h`
|
||||
- `engine/src/Resources/UI/UIDocumentCompiler.cpp`
|
||||
- `engine/src/Resources/UI/UIDocuments.cpp`
|
||||
- `engine/src/Resources/UI/UIDocumentLoaders.cpp`
|
||||
- `engine/include/XCEngine/UI/Types.h`
|
||||
- `engine/include/XCEngine/UI/DrawData.h`
|
||||
- `editor/src/XCUIBackend/ImGuiTransitionBackend.h`
|
||||
- `editor/src/XCUIBackend/XCUIDemoRuntime.h`
|
||||
- `editor/src/Platform/D3D12WindowRendererImGuiInterop.h`
|
||||
- `editor/src/panels/XCUIDemoPanel.h`
|
||||
- `editor/src/panels/XCUIDemoPanel.cpp`
|
||||
- `editor/src/Application.cpp`
|
||||
- `editor/src/Core/EditorWorkspace.h`
|
||||
- `tests/Resources/UI/test_ui_document_loader.cpp`
|
||||
- `tests/Resources/UI/test_ui_schema_document.cpp`
|
||||
- `tests/UI/Core/unit/test_ui_core.cpp`
|
||||
- `tests/Editor/test_xcui_imgui_transition_backend.cpp`
|
||||
- `tests/Editor/test_window_renderer_api.cpp`
|
||||
- 已确认问题:
|
||||
- `Resources/UI` 模块总览已经存在,但四个 public header 仍缺少 canonical 页面。
|
||||
- `UI/Types.h` 与 `UI/DrawData.h` 已被 runtime、Scene 和 editor transition backend 大量使用,但根模块入口页还没有把它们纳入顶层 API。
|
||||
- `editor/src/XCUIBackend`、`editor/src/Platform/D3D12WindowRendererImGuiInterop.h` 与 `editor/src/panels/XCUIDemoPanel.h` 没有 source-backed API 页面,导致 Editor 侧 XCUI transition 链路存在结构缺口。
|
||||
- 完成记录:
|
||||
- 已新增 `UIDocumentTypes`、`UIDocumentCompiler`、`UIDocumentLoaders`、`UIDocuments`、`Types`、`DrawData`、`XCUIBackend`、`ImGuiTransitionBackend`、`XCUIDemoRuntime`、`D3D12WindowRendererImGuiInterop`、`XCUIDemoPanel` 页面。
|
||||
- 已同步 `Resources/UI/UI.md`、`UI/UI.md`、`Editor.md`、`Platform.md` 与 `panels.md`,把 UI 资源层、XCUI transition backend 和 demo panel 纳入当前模块入口。
|
||||
- 已重新运行 `python -B docs/api/_tools/audit_api_docs.py`,确认 `Editor source headers: 142`、`Valid source refs (Editor canonical): 142`、`Invalid source refs: 0`、`Broken .md links: 0`。
|
||||
|
||||
## T22 RHI / Shader formalization 文档补页与 `MaterialRenderState` 归位
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/RHI/ShaderCompiler/**`
|
||||
- `docs/api/XCEngine/Resources/Shader/**`
|
||||
- `docs/api/XCEngine/Resources/Material/**`
|
||||
- 主要源码依据:
|
||||
- `engine/include/XCEngine/RHI/ShaderCompiler/SpirvShaderCompiler.h`
|
||||
- `engine/src/RHI/ShaderCompiler/SpirvShaderCompiler.cpp`
|
||||
- `engine/src/RHI/Vulkan/VulkanShaderCompiler.cpp`
|
||||
- `engine/src/RHI/OpenGL/OpenGLDevice.cpp`
|
||||
- `engine/include/XCEngine/Resources/Shader/ShaderKeywordTypes.h`
|
||||
- `engine/src/Resources/Shader/ShaderLoader.cpp`
|
||||
- `engine/src/Resources/Shader/Shader.cpp`
|
||||
- `engine/include/XCEngine/Resources/Material/MaterialRenderState.h`
|
||||
- `engine/src/Resources/Material/Material.cpp`
|
||||
- `tests/Resources/Shader/test_shader_loader.cpp`
|
||||
- `tests/Resources/Shader/test_shader.cpp`
|
||||
- `tests/Resources/Material/test_material.cpp`
|
||||
- `tests/Rendering/unit/test_render_scene_extractor.cpp`
|
||||
- 已确认问题:
|
||||
- `SpirvShaderCompiler.h` 与 `ShaderKeywordTypes.h` 已进入当前工作树,但 canonical API 树缺少对应入口页。
|
||||
- `MaterialRenderState` 及其相关枚举页仍沿用旧归属,`头文件` 元信息还停在 `Material.h`。
|
||||
- 复核过程中发现 `ShaderRenderState.h` 并不在当前 public header 集合里,说明不能把计划中的 formalized pass-state 设想误写成现有 API 页面。
|
||||
- 完成记录:
|
||||
- 已新增 `SpirvShaderCompiler/SpirvShaderCompiler.md` 与 `ShaderKeywordTypes/ShaderKeywordTypes.md`,并同步 `ShaderCompiler.md`、`Resources/Shader/Shader.md`。
|
||||
- 已把 `MaterialRenderState`、`MaterialCullMode`、`MaterialComparisonFunc`、`MaterialBlendOp`、`MaterialBlendFactor` 的 `头文件` 归位到 `MaterialRenderState.h`,并更新 `Resources/Material/Material.md`。
|
||||
- 已删除误建的 `ShaderRenderState` canonical 页面,并重新运行审计,确认 `Public headers: 304`、`Invalid header refs: 0`、`Broken .md links: 0`。
|
||||
|
||||
## T23 UI / Core + Input header coverage 补页
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P0`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/UI/Core/**`
|
||||
- `docs/api/XCEngine/UI/Input/**`
|
||||
- `docs/api/XCEngine/UI/UI.md`
|
||||
- 主要源码依据:
|
||||
- `engine/include/XCEngine/UI/Core/UIBuildContext.h`
|
||||
- `engine/include/XCEngine/UI/Core/UIContext.h`
|
||||
- `engine/include/XCEngine/UI/Core/UIElementTree.h`
|
||||
- `engine/include/XCEngine/UI/Core/UIInvalidation.h`
|
||||
- `engine/include/XCEngine/UI/Core/UIViewModel.h`
|
||||
- `engine/include/XCEngine/UI/Input/UIFocusController.h`
|
||||
- `engine/include/XCEngine/UI/Input/UIInputDispatcher.h`
|
||||
- `engine/include/XCEngine/UI/Input/UIInputPath.h`
|
||||
- `engine/include/XCEngine/UI/Input/UIInputRouter.h`
|
||||
- `engine/include/XCEngine/UI/Input/UIShortcutRegistry.h`
|
||||
- `engine/src/UI/Core/**`
|
||||
- `engine/src/UI/Input/**`
|
||||
- `tests/UI/Core/unit/**`
|
||||
- `tests/UI/Runtime/unit/**`
|
||||
- 已确认问题:
|
||||
- 最新审计显示 `UI` 模块当前只覆盖 `2 / 37`,剩余缺口里最基础的一批就是 `Core` 与 `Input`。
|
||||
- 这些头文件已经有真实 `.cpp`、单测和 runtime 调用链,但 canonical API 树仍停留在目录总览页。
|
||||
- 完成记录:
|
||||
- 已新增 `UIBuildContext`、`UIContext`、`UIElementTree`、`UIInvalidation`、`UIViewModel`、`UIFocusController`、`UIInputDispatcher`、`UIInputPath`、`UIInputRouter`、`UIShortcutRegistry` 页面。
|
||||
- 已同步 `Core.md`、`Input.md` 与 `UI.md`,把 retained-mode build / diff 主链和输入分发主链纳入当前模块入口。
|
||||
- 已重新运行 `python -B docs/api/_tools/audit_api_docs.py`,确认 `Valid header refs (canonical): 279`、`Invalid header refs: 0`、`Invalid source refs: 0`、`Broken .md links: 0`。
|
||||
|
||||
## T24 UI / Layout + Runtime + Style + Text + Widgets header coverage 补页
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P0`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/UI/Layout/**`
|
||||
- `docs/api/XCEngine/UI/Runtime/**`
|
||||
- `docs/api/XCEngine/UI/Style/**`
|
||||
- `docs/api/XCEngine/UI/Text/**`
|
||||
- `docs/api/XCEngine/UI/Widgets/**`
|
||||
- `docs/api/XCEngine/UI/UI.md`
|
||||
- 主要源码依据:
|
||||
- `engine/include/XCEngine/UI/Layout/*.h`
|
||||
- `engine/include/XCEngine/UI/Runtime/*.h`
|
||||
- `engine/include/XCEngine/UI/Style/*.h`
|
||||
- `engine/include/XCEngine/UI/Text/*.h`
|
||||
- `engine/include/XCEngine/UI/Widgets/*.h`
|
||||
- `engine/src/UI/Runtime/**`
|
||||
- `engine/src/UI/Style/**`
|
||||
- `engine/src/UI/Text/**`
|
||||
- `engine/src/UI/Widgets/**`
|
||||
- `tests/UI/Core/unit/**`
|
||||
- `tests/UI/Runtime/unit/**`
|
||||
- `tests/Scene/test_scene_runtime.cpp`
|
||||
- 已确认问题:
|
||||
- `Layout / Runtime / Style / Text / Widgets` 还剩 `25` 个未覆盖 public headers,是当前 API 文档最大的连续缺口。
|
||||
- 这些头文件里既有 header-only layout / interaction helper,也有真实 source-backed runtime / style / widget 状态模型;如果不拆开写,overview 很容易继续混淆“声明契约”和“当前实现行为”。
|
||||
- 当前进展:
|
||||
- 已新增 `LayoutTypes`、`LayoutEngine`、`UISplitterLayout`、`UITabStripLayout`、`UIScreenTypes`、`UISceneRuntimeContext`、`UIScreenDocumentHost`、`UIScreenPlayer`、`UIScreenStackController`、`UISystem`、`StyleTypes`、`StyleSet`、`Theme`、`StyleResolver`、`DocumentStyleCompiler`、`UITextEditing`、`UITextInputController`、`UIExpansionModel`、`UIFlatHierarchyHelpers`、`UIKeyboardNavigationModel`、`UIPopupOverlayModel`、`UIPropertyEditModel`、`UISelectionModel`、`UISplitterInteraction`、`UITabStripModel` 页面。
|
||||
- 已同步 `Layout.md`、`Runtime.md`、`Style.md`、`Text.md`、`Widgets.md` 与 `UI.md`,把 header-only helper 和 source-backed runtime/style/widget 状态模型拆开归位。
|
||||
- 已重新运行 `python -B docs/api/_tools/audit_api_docs.py`,结果为:`Valid header refs (canonical): 304`、`UI: 37/37`、`Invalid source refs: 0`、`Broken .md links: 0`。
|
||||
|
||||
## T25 Editor UI 壳层与 `RenderMaterialResolve` 增量漂移复核
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Editor/UI/ImGuiSession/ImGuiSession.md`
|
||||
- `docs/api/XCEngine/Editor/panels/ViewportPanelContent/ViewportPanelContent.md`
|
||||
- `docs/api/XCEngine/Editor/Layout/DockLayoutController/DockLayoutController.md`
|
||||
- `docs/api/XCEngine/Rendering/Materials/RenderMaterialResolve/RenderMaterialResolve.md`
|
||||
- 主要源码依据:
|
||||
- `editor/src/UI/ImGuiSession.h`
|
||||
- `editor/src/panels/ViewportPanelContent.h`
|
||||
- `editor/src/Layout/DockLayoutController.h`
|
||||
- `engine/include/XCEngine/Rendering/Materials/RenderMaterialResolve.h`
|
||||
- `engine/src/RHI/D3D12/D3D12ResourceView.cpp`
|
||||
- `engine/include/XCEngine/Input/InputTypes.h`
|
||||
- `engine/include/XCEngine/Threading/TaskSystem.h`
|
||||
- 已确认问题:
|
||||
- `ImGuiSession.md` 仍停留在旧的“单字体 + 简单初始化”口径,没有同步 `SetProjectPath()` / `GetIniPath()`、双字体回退链和 DPI 配置。
|
||||
- `ViewportPanelContent.md` 没有写出当前 `AllowWhenOverlappedByItem` 的 hover/click 采样语义,容易误解 toolbar 覆盖视口时的交互行为。
|
||||
- `DockLayoutController.md` 没有同步当前 main viewport work-area、dock tab bar chrome 配置和 reset 延迟到下一帧重建的真实路径。
|
||||
- `RenderMaterialResolve.md` 漏掉了一批已经公开的 render-queue / legacy pass-fallback helper,也没把常量 payload 有效性和 skybox 模式优先级写清。
|
||||
- 完成记录:
|
||||
- 已重写 `ImGuiSession.md`,补齐 `Initialize(projectPath, mainDpiScale)`、`GetIniPath()`、`SetProjectPath()`、Segoe UI + 微软雅黑 fallback 和 DPI 钳制逻辑。
|
||||
- 已更新 `ViewportPanelContent.md`,补上 overlappable 交互表面、root-child focus 与状态文案依赖 item rect 的当前实现说明。
|
||||
- 已更新 `DockLayoutController.md`,同步 dock host work-area、tab bar chrome 配置与 reset/rebuild 触发链。
|
||||
- 已更新 `RenderMaterialResolve.md`,补齐 render queue tag 解析、legacy builtin pass fallback、skybox 纹理模式优先级和常量 payload 有效性边界。
|
||||
- 抽查 `InputTypes`、`TaskSystem` 与 `D3D12ResourceView` 后,本轮未发现新的明确文档失配。
|
||||
|
||||
## 当前结论
|
||||
|
||||
- 第三轮复核当前已确认 `25` 组失配;`T01` 到 `T25` 已全部完成。
|
||||
- 当前 `Public headers` 已达到 `304/304`,`Editor source headers` 已达到 `142/142`;结构层、Resources、RHI、Rendering、UI 和全部 Editor source-backed API 均为全绿状态。
|
||||
- 后续如果 `docs/plan/` 再出现新的 API 相关计划,或工作树新增/改动 public header、Editor source header,应继续在此任务池追加新任务块,并在收口前重新运行 `python -B docs/api/_tools/audit_api_docs.py`。
|
||||
376
docs/used/API文档实时同步任务池_2026-04-03_第一轮归档.md
Normal file
376
docs/used/API文档实时同步任务池_2026-04-03_第一轮归档.md
Normal file
@@ -0,0 +1,376 @@
|
||||
# API 文档实时同步任务池(2026-04-03)
|
||||
|
||||
## 文档定位
|
||||
|
||||
这份任务池接替已归档的:
|
||||
|
||||
- `docs/plan/used/API文档并行更新任务池_2026-04-02.md`
|
||||
|
||||
旧任务池解决的是:
|
||||
|
||||
- canonical 目录结构收口
|
||||
- 历史缺页补齐
|
||||
- 第一轮大规模内容重写
|
||||
|
||||
本轮不再以“补结构”为主,而是以“跟踪当前工作树真实实现变化,持续清理失准内容和过期 API 页面”为主。
|
||||
|
||||
## 本轮复核方法
|
||||
|
||||
本轮按下面三层做交叉复核:
|
||||
|
||||
1. 重新执行 `python docs/api/_tools/audit_api_docs.py`
|
||||
2. 检查当前工作树里真实发生变化的源码与测试:
|
||||
- `engine/src/Components/MeshFilterComponent.cpp`
|
||||
- `engine/src/Components/MeshRendererComponent.cpp`
|
||||
- `editor/src/Actions/EditorActions.h`
|
||||
- `editor/src/Actions/MainMenuActionRouter.h`
|
||||
- `editor/src/Commands/ProjectCommands.h`
|
||||
- `editor/src/Core/IProjectManager.h`
|
||||
- `editor/src/Managers/ProjectManager.h`
|
||||
- `editor/src/Managers/ProjectManager.cpp`
|
||||
- `tests/Components/test_mesh_render_components.cpp`
|
||||
- `tests/Scene/test_scene.cpp`
|
||||
- `tests/editor/test_action_routing.cpp`
|
||||
3. 反向搜索 API 文档里对旧行为、旧菜单和旧序列化键的残留描述
|
||||
|
||||
## 当前总判断
|
||||
|
||||
- 旧的内容级失准问题已经全部关闭:
|
||||
- `Editor`:旧的项目迁移菜单、命令、接口、manager 和报告结构残留页已在 `2026-04-03 14:04:49` 收口完成
|
||||
- `Components`:`MeshFilterComponent / MeshRendererComponent` 的旧键名、普通项目路径 fallback 和模块总览口径已在 `2026-04-03 14:09:47` 对齐到当前源码 / 测试
|
||||
- 新暴露出的 `SceneViewportRenderPlan.h` 缺页问题已在 `2026-04-03 14:17:02` 收口完成
|
||||
- 当前结构项重新回到全绿:
|
||||
- public headers `246/246`
|
||||
- Editor source headers `122/122`
|
||||
- 失效 `.md` 链接 `0`
|
||||
- 无效 header / source ref `0`
|
||||
- Editor 显式过期符号残留 `0`
|
||||
- Editor 残留 canonical 旧页面 `0`
|
||||
|
||||
这说明当前审计工具已经同时具备三种能力:兜住结构一致性、自动报出已删除 API 的旧符号残留、以及发现工作树中新冒出的未补页 header;后续工作进入“继续跟踪新增 API 与计划文件新增任务块”的阶段。
|
||||
|
||||
## 认领规则
|
||||
|
||||
- 一次只认领 `1` 个任务块,先改 `状态` 和 `认领人`
|
||||
- 只修改自己任务块的 `写入范围`,不要跨任务顺手扩写其它模块
|
||||
- 每个任务都要以当前工作树源码、测试和真实调用点为依据,不允许只按旧文档重写旧文档
|
||||
- 除最后的审计收口任务外,不要随意覆盖 `docs/api/_meta/rebuild-status.md`
|
||||
- 如果任务涉及删除过期 API 页面,必须同步清理所有交叉链接
|
||||
|
||||
## 任务池
|
||||
|
||||
## T01 Components / Mesh 资产引用最终协议同步
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P0`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Components/MeshFilterComponent/**`
|
||||
- `docs/api/XCEngine/Components/MeshRendererComponent/**`
|
||||
- 必要时 `docs/api/XCEngine/Components/Components.md`
|
||||
- 必要时 `docs/api/_guides/Components/**`
|
||||
- 主要源码依据:
|
||||
- `engine/src/Components/MeshFilterComponent.cpp`
|
||||
- `engine/src/Components/MeshRendererComponent.cpp`
|
||||
- `tests/Components/test_mesh_render_components.cpp`
|
||||
- `tests/Scene/test_scene.cpp`
|
||||
- `engine/include/XCEngine/Components/MeshFilterComponent.h`
|
||||
- `engine/include/XCEngine/Components/MeshRendererComponent.h`
|
||||
- 当前确认缺口:
|
||||
- `MeshFilterComponent.md` 仍写“反序列化会读取 `mesh=<path>`”,而当前实现只识别 `meshPath`
|
||||
- `MeshFilterComponent.md` / `Serialize.md` 仍写“序列化输出 `mesh=<path>`”,而当前实现对项目资产已转向 `meshRef` 主路径,只在 virtual scheme 下保留 `meshPath`
|
||||
- `MeshFilterComponent::Deserialize.md` 仍写“只有路径时会补算 `AssetRef` 并接受普通路径”,而当前实现已忽略没有 `AssetRef` 的普通项目路径,只保留 virtual scheme 路径
|
||||
- `MeshRendererComponent.md` / `Serialize.md` / `Deserialize.md` 仍写“兼容 `materials=` 历史键”和“项目资产路径 fallback 仍是主恢复路径”,而当前实现已经不再读取 `materials=`,并且会清掉无 `AssetRef` 的普通 `materialPaths`
|
||||
- 组件模块总览当前对“路径 + AssetRef + 运行时句柄双轨”的描述仍偏旧,没有强调“项目资产主协议已经收口为 `AssetRef`,路径主要保留给 `builtin://` / 其它 virtual scheme”
|
||||
- 完成标准:
|
||||
- 把 `MeshFilterComponent` / `MeshRendererComponent` 类型页和序列化方法页全部改到当前实现
|
||||
- 明确“项目资产只依赖 `AssetRef`,普通项目路径不再作为长期兼容协议”
|
||||
- 明确“只有 virtual scheme 路径会稳定保留在 `meshPath` / `materialPaths` 里”
|
||||
- 清掉所有关于 `mesh=`、`materials=` 仍被当前实现兼容的说法
|
||||
- 完成记录:
|
||||
- 已重新核对 `MeshFilterComponent.h/.cpp`、`MeshRendererComponent.h/.cpp`、`tests/Components/test_mesh_render_components.cpp` 与 `tests/Scene/test_scene.cpp`
|
||||
- `MeshFilterComponent.md`、`Serialize.md`、`Deserialize.md` 与 `MeshRendererComponent.md`、`Serialize.md`、`Deserialize.md` 已确认按当前实现描述 `meshRef / materialRefs` 主协议
|
||||
- 已继续修正 `SetMeshPath.md`、`SetMaterialPath.md` 与 `Components.md`,把“运行时路径缓存”和“正式序列化协议”明确拆开
|
||||
- `2026-04-03 14:09:47` 审计后,当前仓库中这组页面不再把 `mesh=` / `materials=` 或普通项目路径 fallback 写成当前协议
|
||||
|
||||
## T02 Editor / 移除场景资产引用迁移链路文档与过期页
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P0`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Editor/Actions/EditorActions/**`
|
||||
- `docs/api/XCEngine/Editor/Actions/MainMenuActionRouter/**`
|
||||
- `docs/api/XCEngine/Editor/Commands/ProjectCommands/**`
|
||||
- `docs/api/XCEngine/Editor/Core/IProjectManager/**`
|
||||
- `docs/api/XCEngine/Editor/Managers/ProjectManager/**`
|
||||
- `docs/api/XCEngine/Editor/panels/ProjectPanel/**`
|
||||
- 必要时 `docs/api/_guides/Editor/**`
|
||||
- 主要源码依据:
|
||||
- `editor/src/Actions/EditorActions.h`
|
||||
- `editor/src/Actions/MainMenuActionRouter.h`
|
||||
- `editor/src/Commands/ProjectCommands.h`
|
||||
- `editor/src/Core/IProjectManager.h`
|
||||
- `editor/src/Managers/ProjectManager.h`
|
||||
- `editor/src/Managers/ProjectManager.cpp`
|
||||
- `tests/editor/test_action_routing.cpp`
|
||||
- 当前确认缺口:
|
||||
- `EditorActions.md` 仍包含 `MakeMigrateSceneAssetReferencesAction`
|
||||
- `MainMenuActionRouter.md` 仍把 `File -> Migrate Scene AssetRefs` 当成当前菜单项
|
||||
- `ProjectCommands.md` 仍写 `CanMigrateSceneAssetReferences()` / `MigrateSceneAssetReferences()`
|
||||
- `IProjectManager.md` 仍声明 `SceneAssetReferenceMigrationReport` 和 `MigrateSceneAssetReferences()`
|
||||
- `ProjectManager.md` 仍把“场景资产引用迁移”写成当前公开职责
|
||||
- `ProjectPanel.md` 仍把 `Migrate Scene AssetRefs` 记为项目级命令之一
|
||||
- 过期 canonical 页面仍存在:
|
||||
- `docs/api/XCEngine/Editor/Managers/ProjectManager/MigrateSceneAssetReferences.md`
|
||||
- 完成标准:
|
||||
- 把上述页面全部改成当前源码状态
|
||||
- 删除已不存在的 API 页面,并清理所有交叉引用
|
||||
- 把项目工作流文档收口到当前仍存在的入口:项目切换、保存、脚本重建、资源浏览与文件操作
|
||||
- 完成记录:
|
||||
- 已重写 `EditorActions.md`、`MainMenuActionRouter.md`、`ProjectCommands.md`、`IProjectManager.md`、`ProjectManager.md`、`ProjectPanel.md`
|
||||
- 已把 `IProjectManager` 进一步拆成 `Current Items And Selection`、`Navigation And Path`、`Initialization And Refresh`、`File Operations` 四页,按当前头文件分组收口
|
||||
- `docs/api/XCEngine/Editor/Managers/ProjectManager/MigrateSceneAssetReferences.md` 已删除;旧迁移 API 不再保留兼容入口页
|
||||
- `2026-04-03 14:04:49` 已重新执行 `python docs/api/_tools/audit_api_docs.py`,结果为:
|
||||
- `Stale editor doc tokens: 0`
|
||||
- `Broken .md links: 0`
|
||||
- `Valid source refs (Editor canonical): 121`
|
||||
|
||||
## T03 Cross-Module / 资产引用协议与编辑器工作流交叉说明收口
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Components/Components.md`
|
||||
- `docs/api/XCEngine/Scene/Scene.md`
|
||||
- `docs/api/_guides/Editor/Editor-Architecture-And-Workflow.md`
|
||||
- 必要时 `docs/api/main.md`
|
||||
- 主要源码依据:
|
||||
- `engine/src/Components/MeshFilterComponent.cpp`
|
||||
- `engine/src/Components/MeshRendererComponent.cpp`
|
||||
- `editor/src/Actions/MainMenuActionRouter.h`
|
||||
- `editor/src/Commands/ProjectCommands.h`
|
||||
- `editor/src/Managers/ProjectManager.cpp`
|
||||
- `tests/Scene/test_scene.cpp`
|
||||
- `tests/editor/test_action_routing.cpp`
|
||||
- 当前确认缺口:
|
||||
- 模块总览层还没有把“项目资产最终序列化协议已收口到 `AssetRef`,virtual path 只保留给 builtin/虚拟资源”讲透
|
||||
- Editor 架构层仍有旧项目维护入口的残留心智,需要删掉“场景迁移”这条已不存在的分支
|
||||
- 目前用户如果只读模块总览,仍容易得出“普通项目路径仍是第一公民协议”“主菜单还带场景迁移入口”的错误结论
|
||||
- 完成标准:
|
||||
- 模块页和 guide 页不再沿用旧心智模型
|
||||
- 用户只看总览页,也能得出当前正确结论:
|
||||
- 项目资产靠 `AssetRef`
|
||||
- `builtin://` / 其它 virtual scheme 才保留路径
|
||||
- 主菜单已无 `Migrate Scene AssetRefs`
|
||||
- 完成记录:
|
||||
- 已修正 `docs/api/XCEngine/Components/Components.md`,明确项目资产正式协议优先 `AssetRef`
|
||||
- 已复核 `docs/api/XCEngine/Scene/Scene.md`、`docs/api/_guides/Editor/Editor-Architecture-And-Workflow.md` 与 `docs/api/main.md`,确认不再传播旧菜单入口或“普通项目路径仍是第一公民协议”的说法
|
||||
- 当前仅阅读模块总览 / guide,也能得出“项目资产靠 `AssetRef`、virtual scheme 才稳定保留路径、主菜单没有旧迁移入口”的正确结论
|
||||
|
||||
## T04 API 审计工具补强 / 过期 API 页面检测
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/_tools/audit_api_docs.py`
|
||||
- 必要时 `docs/api/_meta/rebuild-status.md`
|
||||
- 必要时在 `docs/plan` 中补充审计口径说明
|
||||
- 主要依据:
|
||||
- 本轮复核结论
|
||||
- 当前 audit 全绿但仍漏报 `MigrateSceneAssetReferences` 这类已删除 API 残留页
|
||||
- 当前确认缺口:
|
||||
- 现有审计能发现“缺页”和“断链”,但不能发现“源码已经删除,文档页仍然存在”
|
||||
- 也不能发现模块页仍在描述已删除菜单项或已删除 helper
|
||||
- 完成标准:
|
||||
- 至少新增一种轻量检测,能把“已删除 API 的残留 canonical 页面”或“显式过期 helper 名称残留”暴露出来
|
||||
- 让后续复核不再完全依赖人工 grep
|
||||
- 完成记录:
|
||||
- `docs/api/_tools/audit_api_docs.py` 已新增 Editor 显式过期符号残留检测
|
||||
- `2026-04-03 13:53:21` 审计已能自动报出 `49` 处 `MigrateSceneAssetReferences` 相关残留
|
||||
|
||||
## T05 收口审计与进度回写
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P2`
|
||||
- 写入范围:
|
||||
- `docs/api/_meta/rebuild-status.md`
|
||||
- `docs/plan/API文档实时同步任务池_2026-04-03.md`
|
||||
- 主要依据:
|
||||
- `T01-T04` 完成结果
|
||||
- 完成标准:
|
||||
- 重新执行 `python docs/api/_tools/audit_api_docs.py`
|
||||
- 回写新的审计时间和结果
|
||||
- 明确记录本轮哪些失准点已关闭、哪些仍待继续跟踪
|
||||
- 完成记录:
|
||||
- 已在 `2026-04-03 14:20:04` 重新执行 `python docs/api/_tools/audit_api_docs.py`
|
||||
- 已回写 `docs/api/_meta/rebuild-status.md`
|
||||
- 本轮已关闭:
|
||||
- `T01` 对应的 Components / Mesh 资产引用协议失准
|
||||
- `T02` 对应的 Editor 旧迁移链路文档残留
|
||||
- `T03` 对应的跨模块总览与 guide 口径收口
|
||||
- `T07` 对应的 `SceneViewportRenderPlan.h` 缺页
|
||||
- 本轮剩余待继续跟踪:
|
||||
- 当前任务池内无未完成块;后续按新增 API 或新增计划任务继续开块
|
||||
|
||||
## 最新收口结论(2026-04-03 14:20:04)
|
||||
|
||||
- 已重新执行 `python docs/api/_tools/audit_api_docs.py`
|
||||
- 当前结构性问题重新回到 `0`
|
||||
- public headers `246/246`
|
||||
- Editor source headers `122/122`
|
||||
- 失效 `.md` 链接 `0`
|
||||
- 无效 header / source ref `0`
|
||||
- 本轮新增收口结果:
|
||||
- `T01 Components / Mesh 资产引用最终协议同步` 已完成
|
||||
- `T02 Editor / 移除场景资产引用迁移链路文档与过期页` 已完成
|
||||
- `T03 Cross-Module / 资产引用协议与编辑器工作流交叉说明收口` 已完成
|
||||
- `T07 Editor / SceneViewportRenderPlan 新增头文件补页` 已完成
|
||||
- `T09 Editor / EditorConsoleSink 生命周期与 Managers 总览口径复核` 已完成
|
||||
- `IProjectManager` 已按当前头文件拆成 4 个职责页,`ProjectManager` / `ProjectCommands` / `MainMenuActionRouter` / `EditorActions` / `ProjectPanel` 已全部同步到当前源码
|
||||
- Components 模块总览与 mesh/material 组件页已统一到“项目资产优先 `AssetRef`、virtual scheme 才稳定保留路径”的当前协议
|
||||
- 对应的旧迁移 canonical 页已删除,已删除 API 名称也不再出现在正文里
|
||||
- `EditorConsoleSink` 文档已改回当前真实生命周期:`GetInstance()` 没有 fallback 实例,未注册时会返回 `nullptr`
|
||||
- `docs/api/_meta/rebuild-status.md` 当前显示:
|
||||
- `Markdown pages (canonical): 3273`
|
||||
- `Stale editor doc tokens: 0`
|
||||
- `Stale editor canonical pages: 0`
|
||||
- `Editor high-risk single-page dirs: 0`
|
||||
- 当前仍待处理的内容级问题:
|
||||
- 当前任务池内无未完成块
|
||||
|
||||
## T06 Rendering / CameraRenderer 与主管线职责边界收口
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Rendering/CameraRenderer/**`
|
||||
- `docs/api/XCEngine/Rendering/RenderPipeline/**`
|
||||
- `docs/api/XCEngine/Rendering/RenderPipelineAsset/**`
|
||||
- `docs/api/XCEngine/Rendering/Pipelines/BuiltinForwardPipelineAsset/**`
|
||||
- 必要时 `docs/api/XCEngine/Rendering/Rendering.md`
|
||||
- 主要源码依据:
|
||||
- `engine/include/XCEngine/Rendering/CameraRenderer.h`
|
||||
- `engine/src/Rendering/CameraRenderer.cpp`
|
||||
- `engine/include/XCEngine/Rendering/RenderPipeline.h`
|
||||
- `engine/include/XCEngine/Rendering/RenderPipelineAsset.h`
|
||||
- `engine/include/XCEngine/Rendering/Pipelines/BuiltinForwardPipeline.h`
|
||||
- `tests/Rendering/unit/test_camera_scene_renderer.cpp`
|
||||
- 当前缺口:
|
||||
- 已重写 `CameraRenderer.md`、`Constructor.md`、`Render.md`、`Rendering.md`、`RenderPipeline.md`,把“`SceneRenderer` 负责请求规划、`CameraRenderer` 负责执行单 request”的真实分层,以及默认 `BuiltinForwardPipelineAsset -> BuiltinForwardPipeline` 链路同步到当前实现。
|
||||
- 已继续重写 `RenderPipeline/Initialize.md`、`Render.md`、`Shutdown.md`、`Destructor.md`,明确 `RenderPipeline` 只覆盖主场景 runtime 绘制,不承担 object-id / builtin post-process / overlay 编排;同时写清 `Initialize()` 不是上层强制预热点,`Shutdown()` 调用路径由 `CameraRenderer` 托管。
|
||||
- 已校正 `RenderPipelineAsset.md`、`CreatePipeline.md`、`BuiltinForwardPipelineAsset.md`、`CreatePipeline.md`,把“asset 负责创建 runtime pipeline”与“空 asset / 空返回后的 fallback 由 `CameraRenderer` 处理”拆开说明,避免把调用方策略误记到 asset 接口本身。
|
||||
- 完成标准:
|
||||
- 用户只看 `CameraRenderer` / `RenderPipeline` / `RenderPipelineAsset` 这一组页面,也能得出当前正确结论:
|
||||
- `SceneRenderer` 负责请求规划,`CameraRenderer` 负责执行单 request
|
||||
- `RenderPipeline` 只负责主场景 runtime 绘制
|
||||
- fallback 属于调用方装配逻辑,不属于 `RenderPipelineAsset` 接口本身
|
||||
|
||||
## T07 Editor / SceneViewportRenderPlan 新增头文件补页
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/**`
|
||||
- 必要时 `docs/api/XCEngine/Editor/Viewport/Viewport.md`
|
||||
- 必要时 `docs/api/_guides/Editor/**`
|
||||
- 主要源码依据:
|
||||
- `editor/src/Viewport/SceneViewportRenderPlan.h`
|
||||
- `editor/src/Viewport/ViewportHostService.h`
|
||||
- 当前缺口:
|
||||
- `docs/api/_tools/audit_api_docs.py` 于 `2026-04-03 14:11:12` 报出新增未覆盖 header:`editor/src/Viewport/SceneViewportRenderPlan.h`
|
||||
- 当前缺的不只是类型页,还包括内联 helper:
|
||||
- `SceneViewportRenderPlan`
|
||||
- `SceneViewportRenderPlanBuildResult`
|
||||
- `BuildSceneViewportRenderPlan(...)`
|
||||
- `ApplySceneViewportRenderPlan(...)`
|
||||
- 从 `ViewportHostService.h` 的调用关系看,这个头文件已经成为 Scene View request 装配链的一部分,不能继续留白
|
||||
- 完成标准:
|
||||
- 为 `SceneViewportRenderPlan.h` 建立 canonical 目录与类型页
|
||||
- 把 plan 结构、build result、build/apply 两个 helper 的职责边界写清楚
|
||||
- 用户只看这组页面,也能得出当前正确结论:
|
||||
- 它负责把 Scene View 的 builtin post-process、overlay passes 与 clear-color override 收口成一个 request plan
|
||||
- `Build...` 负责从 overlay / targets 生成 plan
|
||||
- `Apply...` 负责把 plan 回写到 `CameraRenderRequest`
|
||||
- 完成记录:
|
||||
- 已新增:
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/SceneViewportRenderPlan.md`
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/SceneViewportRenderPlanBuildResult.md`
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/BuildSceneViewportRenderPlan.md`
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/ApplySceneViewportRenderPlan.md`
|
||||
- 已同步更新:
|
||||
- `docs/api/XCEngine/Editor/Viewport/Viewport.md`
|
||||
- `docs/api/XCEngine/Editor/Viewport/ViewportHostService/ViewportHostService.md`
|
||||
- `2026-04-03 14:20:04` 审计结果已恢复为:
|
||||
- `Editor source headers 122/122`
|
||||
- `失效 .md 链接 0`
|
||||
- `Stale editor doc tokens 0`
|
||||
- `Stale editor canonical pages 0`
|
||||
|
||||
## T08 Rendering / RenderCameraData 与 builtin forward 材质契约补齐
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P2`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Rendering/RenderCameraData/**`
|
||||
- `docs/api/XCEngine/Rendering/RenderSceneUtility/**`
|
||||
- `docs/api/XCEngine/Rendering/RenderMaterialUtility/**`
|
||||
- 主要源码依据:
|
||||
- `engine/include/XCEngine/Rendering/RenderCameraData.h`
|
||||
- `engine/include/XCEngine/Rendering/RenderSceneUtility.h`
|
||||
- `engine/src/Rendering/RenderSceneUtility.cpp`
|
||||
- `engine/include/XCEngine/Rendering/RenderMaterialUtility.h`
|
||||
- `tests/Rendering/unit/test_render_scene_extractor.cpp`
|
||||
- `tests/Rendering/unit/test_render_scene_utility.cpp`
|
||||
- 当前缺口:
|
||||
- 已重写 `RenderCameraData.md`,补齐此前遗漏的 `clearFlags` 字段,以及 `RenderClearFlags` / `HasRenderClearFlag(...)` 的当前位标志语义;同时写清 `BuildRenderCameraData()` 不负责 clear mode 推导,真正的 per-request clear 规则由 `CameraRenderer` 回写。
|
||||
- 已重写 `RenderSceneUtility.md` 中 `BuildRenderCameraData()` 的职责边界,明确它只构建矩阵、世界位置、默认清屏色和 viewport,不直接决定相机 request 的 clear 规则。
|
||||
- 已补齐 `ResolveBuiltinBaseColorFactor.md`、`ResolveBuiltinBaseColorTexture.md`、`BuildBuiltinForwardMaterialData.md`,并更新 `RenderMaterialUtility.md`,把 builtin forward 当前公开消费的 base-color 因子 / 贴图契约、semantic 优先级、别名回退与 alpha-only fallback 写到当前实现。
|
||||
- 完成标准:
|
||||
- 用户只看 `RenderCameraData` / `RenderSceneUtility` / `RenderMaterialUtility`,也能得出当前正确结论:
|
||||
- clear flags 不是 extractor 里按相机直接定死的,而是 request 层再覆盖写回
|
||||
- builtin forward 当前公开消费的材质契约至少包括 `baseColorFactor` 与 base-color 贴图解析规则
|
||||
|
||||
## T09 Editor / EditorConsoleSink 生命周期与 Managers 总览口径复核
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P2`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Editor/Core/EditorConsoleSink/**`
|
||||
- `docs/api/XCEngine/Editor/Managers/Managers.md`
|
||||
- `docs/api/_tools/audit_api_docs.py`
|
||||
- 必要时 `docs/api/_meta/rebuild-status.md`
|
||||
- 必要时 `docs/plan/API文档实时同步任务池_2026-04-03.md`
|
||||
- 主要源码依据:
|
||||
- `editor/src/Core/EditorConsoleSink.h`
|
||||
- `editor/src/Core/EditorConsoleSink.cpp`
|
||||
- `tests/Editor/test_editor_console_sink.cpp`
|
||||
- `editor/src/Managers/ProjectManager.h`
|
||||
- `editor/src/Managers/ProjectManager.cpp`
|
||||
- 当前缺口:
|
||||
- `EditorConsoleSink.md`、`GetInstance.md`、`Destructor.md` 仍把 `GetInstance()` 写成“无活动实例时回退到 fallback sink”,但当前实现只是直接返回 `s_instance`
|
||||
- 新增测试 `GetInstanceTracksRegisteredSinkOnly` 已明确要求:活动实例析构后 `GetInstance()` 返回 `nullptr`
|
||||
- `Managers.md` 仍把“场景资产引用迁移”写成 `ProjectManager` 的当前职责之一,与本轮已删除的旧迁移链路不一致
|
||||
- 完成标准:
|
||||
- `EditorConsoleSink` 生命周期相关页面全部对齐到当前实现:
|
||||
- `GetInstance()` 可能返回 `nullptr`
|
||||
- 没有静态 fallback sink
|
||||
- `Managers.md` 不再残留旧迁移职责表述
|
||||
- 审计工具新增轻量兜底,后续若 `EditorConsoleSink` 文档再次写回 fallback 语义,能够被自动报出
|
||||
- 完成记录:
|
||||
- 已修正 `EditorConsoleSink.md`、`GetInstance.md`、`Destructor.md`
|
||||
- 已修正 `Managers.md` 中 `ProjectManager` 的职责概述
|
||||
- `docs/api/_tools/audit_api_docs.py` 已新增针对 `EditorConsoleSink` 旧 fallback 生命周期表述的定向检测
|
||||
|
||||
## 现阶段优先级建议
|
||||
|
||||
- 当前这份实时任务池里的已知问题已全部收口
|
||||
- `T01`、`T02`、`T03`、`T05`、`T06`、`T07`、`T09` 都已完成,不再作为并行入口重复认领
|
||||
- 若工作树继续新增 API 或计划文件继续追加任务块,再按新增内容开新任务
|
||||
|
||||
## 一句话结论
|
||||
|
||||
旧任务池解决了“API 文档树有没有建起来”的问题;这份实时任务池目前已经把 Editor 旧迁移链路、Components 资产引用协议、跨模块总览口径、`SceneViewportRenderPlan.h` 的缺页,以及 `EditorConsoleSink` 生命周期文档失准全部收口,后续只需要继续跟踪新增 API 与新增计划任务。
|
||||
600
docs/used/API文档实时同步任务池_2026-04-03_第二轮归档.md
Normal file
600
docs/used/API文档实时同步任务池_2026-04-03_第二轮归档.md
Normal file
@@ -0,0 +1,600 @@
|
||||
# API 文档实时同步任务池(2026-04-03,第二轮)
|
||||
|
||||
## 文档定位
|
||||
|
||||
这份任务池接替已归档的第一轮计划:
|
||||
|
||||
- `docs/plan/used/API文档实时同步任务池_2026-04-03_第一轮归档.md`
|
||||
|
||||
第一轮已经解决的重点是:
|
||||
|
||||
- canonical 目录结构收口
|
||||
- 历史缺页补齐
|
||||
- 第一轮大规模内容重写
|
||||
|
||||
本轮重点不再是“补结构”,而是:
|
||||
|
||||
- 重新对照当前工作树源码与测试
|
||||
- 清理最近重构后重新出现的内容级失配
|
||||
- 继续维护一份适合多人并行认领的增量同步清单
|
||||
|
||||
## 当前复核快照
|
||||
|
||||
- 最近一次结构审计时间:`2026-04-03 16:21:55`
|
||||
- 审计命令:`python -B docs/api/_tools/audit_api_docs.py`
|
||||
- 当前结果:
|
||||
- `Public headers: 244`
|
||||
- `Editor source headers: 126`
|
||||
- `Invalid header refs: 0`
|
||||
- `Invalid source refs: 0`
|
||||
- `Broken .md links: 0`
|
||||
- `Stale canonical doc tokens: 0`
|
||||
- `Stale editor doc tokens: 0`
|
||||
- `Stale editor canonical pages: 0`
|
||||
|
||||
这说明当前结构层面已经恢复全绿;本轮已确认的内容级失配也已收口,后续以持续巡检为主。
|
||||
|
||||
## 认领规则
|
||||
|
||||
- 一次只认领 `1` 个任务块。
|
||||
- 先把 `状态` 改成 `DOING`,再写 `认领人`。
|
||||
- 只能改自己任务块的 `写入范围`。
|
||||
- 所有改动都必须以“当前源码 + 当前测试 + 当前真实调用链”为依据,不允许按旧文档续写旧行为。
|
||||
- 如果清理了过期 API 页面,必须同时清理交叉链接。
|
||||
|
||||
## 任务池
|
||||
|
||||
## T01 Editor / Viewport 渲染计划与宿主流程内容同步
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P0`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/ViewportHostService/**`
|
||||
- 必要时 `docs/api/XCEngine/Editor/Viewport/IViewportHostService/**`
|
||||
- 主要源码依据:
|
||||
- `editor/src/Viewport/SceneViewportRenderPlan.h`
|
||||
- `editor/src/Viewport/ViewportHostRenderFlowUtils.h`
|
||||
- `editor/src/Viewport/ViewportHostService.h`
|
||||
- `tests/editor/test_viewport_render_flow_utils.cpp`
|
||||
- 已关闭问题:
|
||||
- 旧文档仍把 Scene View 当前主路径写成 builtin post-process 主导
|
||||
- 没写清 grid / selection outline 现在已转为显式 `postScenePasses`
|
||||
- 没写清 overlay pass 是 `editorOverlayFrameData + transientOverlayFrameData` 合并后再创建
|
||||
- 没写清 `Scene object id shader view is unavailable` 是局部降级警告,不是整帧失败
|
||||
- 完成记录:
|
||||
- 已重写 `SceneViewportRenderPlan.md`、`BuildSceneViewportRenderPlan.md`、`ApplySceneViewportRenderPlan.md`
|
||||
- 已同步 `ViewportHostRenderFlowUtils.md`、`ViewportHostService.md`、`RenderRequestedViewports.md`
|
||||
- 已清理 `IViewportHostService` 中残留的旧表述
|
||||
|
||||
## T02 Core / Asset 缓存接口改名与语义重构同步
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P0`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Core/Asset/ResourceManager/**`
|
||||
- `docs/api/XCEngine/Core/Asset/AssetImportService/**`
|
||||
- `docs/api/XCEngine/Core/Asset/ProjectAssetIndex/**`
|
||||
- 必要时 `docs/api/XCEngine/Core/Asset/Asset.md`
|
||||
- 必要时 `docs/api/XCEngine/Core/Asset/ArtifactFormats/**`
|
||||
- 主要源码依据:
|
||||
- `engine/include/XCEngine/Core/Asset/ResourceManager.h`
|
||||
- `engine/src/Core/Asset/ResourceManager.cpp`
|
||||
- `engine/include/XCEngine/Core/Asset/AssetImportService.h`
|
||||
- `engine/src/Core/Asset/AssetImportService.cpp`
|
||||
- `engine/include/XCEngine/Core/Asset/ProjectAssetIndex.h`
|
||||
- `engine/src/Core/Asset/ProjectAssetIndex.cpp`
|
||||
- `tests/core/Asset/test_resource_manager.cpp`
|
||||
- 已关闭问题:
|
||||
- `RefreshAssetDatabase` 已经不存在,但旧文档仍在沿用
|
||||
- `RefreshProjectAssets` / `RebuildProjectAssetCache` / `GetProjectLibraryRoot` 缺页或未写清
|
||||
- `AssetImportService::EnsureArtifact()` 旧文档仍把输出写成 `ResolvedAsset`
|
||||
- `BuildLookupSnapshot()` 旧文档仍按“双 map 出参”描述,而不是 `LookupSnapshot`
|
||||
- `ImportedAsset::runtimeLoadPath` 语义未同步到上层文档
|
||||
- 完成记录:
|
||||
- 已删除过期页 `ResourceManager/RefreshAssetDatabase.md`
|
||||
- 已补齐 `RefreshProjectAssets.md`、`RebuildProjectAssetCache.md`、`GetProjectLibraryRoot.md`
|
||||
- 已补齐 `LookupSnapshot.md`、`ImportedAsset.md`、`GetLibraryRoot.md`、`RebuildLibraryCache.md`
|
||||
- 已同步 `Asset.md`、`ArtifactFormats.md`、`ResourceManager/Load.md` 的 `runtimeLoadPath` 口径
|
||||
|
||||
## T03 Scripting / Mono 托管销毁入口同步
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Scripting/Mono/MonoScriptRuntime/**`
|
||||
- 主要源码依据:
|
||||
- `engine/include/XCEngine/Scripting/Mono/MonoScriptRuntime.h`
|
||||
- `engine/src/Scripting/Mono/MonoScriptRuntime.cpp`
|
||||
- `tests/scripting/test_mono_script_runtime.cpp`
|
||||
- 已关闭问题:
|
||||
- `DestroyManagedObject(MonoObject*)` 已进入头文件与测试,但文档树没有对应页面
|
||||
- `MonoScriptRuntime.md` 没写清 `Object.Destroy(...)` 会回落到原生对象 / 组件销毁
|
||||
- 完成记录:
|
||||
- 已新增 `DestroyManagedObject.md`
|
||||
- 已更新 `MonoScriptRuntime.md` 的 internal call 说明与方法总表
|
||||
|
||||
## T04 Cross-Module / 教程层与模块总览口径持续复核
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P2`
|
||||
- 写入范围:
|
||||
- `docs/api/_guides/**`
|
||||
- `docs/api/XCEngine/*/*.md`
|
||||
- 仅限与本轮已确认 API 变更直接相关的总览页
|
||||
- 任务目标:
|
||||
- 继续检查教程页、模块总览页是否仍在传播旧心智模型
|
||||
- 尤其关注:
|
||||
- Scene View 仍被写成 builtin post-process 主导
|
||||
- 资源导入链仍被写成 `artifactMainPath` / `RefreshAssetDatabase` 时代的口径
|
||||
- 托管对象销毁路径未在教程层被解释
|
||||
- 产出要求:
|
||||
- 只修正已确认失配的 guide / overview 页面
|
||||
- 不做与当前源码无关的泛化扩写
|
||||
- 完成记录:
|
||||
- 已完成一轮 guide / overview 复核
|
||||
- 已确认 `GameObject / Scene` 教程层仍在传播“tag 只是 name 别名”的旧心智
|
||||
- 已把后续需要实改的页面收口到 `T08`
|
||||
|
||||
## T05 增量变更监控 / 新一轮差异发现
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P2`
|
||||
- 写入范围:
|
||||
- 只读检查 `engine/include/**`、`engine/src/**`、`editor/src/**`、`tests/**`
|
||||
- 必要时只向本任务池追加新任务块
|
||||
- 任务目标:
|
||||
- 继续结合工作树最新改动,找出新的“源码已变但文档还没跟上”的内容级失配
|
||||
- 优先检查:
|
||||
- 最近改动过的 public headers
|
||||
- 最近改动过的 Editor source headers
|
||||
- 最近新增或更新过的测试
|
||||
- 产出要求:
|
||||
- 只记录已确认的问题
|
||||
- 每条新任务都要写明:
|
||||
- 受影响文档
|
||||
- 主要源码依据
|
||||
- 真实失配点
|
||||
- 建议写入范围
|
||||
- 完成记录:
|
||||
- 已重新扫描当前工作树改动过的 public header、Editor source header、实现文件和测试
|
||||
- 已确认并追加 `T08` 与 `T09` 两组新的内容级失配
|
||||
|
||||
## T06 Rendering / Camera request、Passes 与执行链旧口径清理
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Rendering/CameraRenderRequest/**`
|
||||
- `docs/api/XCEngine/Rendering/CameraRenderer/**`
|
||||
- `docs/api/XCEngine/Rendering/Passes/**`
|
||||
- `docs/api/XCEngine/Rendering/ObjectIdPass/**`
|
||||
- `docs/api/XCEngine/Rendering/RenderPipeline/**`
|
||||
- `docs/api/XCEngine/Rendering/SceneRenderer/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/Passes/**`
|
||||
- 必要时 `docs/api/XCEngine/Editor/Viewport/Viewport.md`
|
||||
- 必要时 `docs/api/XCEngine/XCEngine.md`
|
||||
- 必要时 `docs/api/_tools/audit_api_docs.py`
|
||||
- 主要源码依据:
|
||||
- `engine/include/XCEngine/Rendering/CameraRenderRequest.h`
|
||||
- `engine/include/XCEngine/Rendering/CameraRenderer.h`
|
||||
- `engine/include/XCEngine/Rendering/Passes/BuiltinObjectIdPass.h`
|
||||
- `engine/include/XCEngine/Rendering/Passes/BuiltinObjectIdOutlinePass.h`
|
||||
- `engine/include/XCEngine/Rendering/Passes/BuiltinInfiniteGridPass.h`
|
||||
- `engine/include/XCEngine/Rendering/ObjectIdPass.h`
|
||||
- `engine/include/XCEngine/Rendering/RenderPipeline.h`
|
||||
- `engine/include/XCEngine/Rendering/SceneRenderer.h`
|
||||
- `engine/src/Rendering/CameraRenderer.cpp`
|
||||
- `engine/src/Rendering/SceneRenderer.cpp`
|
||||
- `tests/Rendering/unit/test_camera_scene_renderer.cpp`
|
||||
- `editor/src/Viewport/SceneViewportRenderPlan.h`
|
||||
- `editor/src/Viewport/Passes/SceneViewportGridPass.cpp`
|
||||
- `editor/src/Viewport/Passes/SceneViewportSelectionOutlinePass.cpp`
|
||||
- `editor/src/Viewport/ViewportHostRenderFlowUtils.h`
|
||||
- `tests/Editor/test_viewport_render_flow_utils.cpp`
|
||||
- `tests/Editor/test_scene_viewport_overlay_renderer.cpp`
|
||||
- 已关闭问题:
|
||||
- `CameraRenderRequest.md` 仍描述已删除的 `builtinPostProcess` 子请求
|
||||
- 页面仍链接到不存在的 `BuiltinPostProcessRequest/BuiltinPostProcessRequest.md`
|
||||
- Scene View 已改为通过 `postScenePasses` / `overlayPasses` 写回 request,但该页口径未同步
|
||||
- `CameraRenderer.md` 仍保留已删除的 `m_builtinPostProcessBuilder` 历史口径
|
||||
- `Passes.md` 的典型链路只写了 `postScenePasses`,遗漏当前 `overlayPasses` 组装路径
|
||||
- `Rendering/Passes` 下仍残留已删除的 `BuiltinPostProcessPassPlan` / `BuiltinPostProcessPassSequenceBuilder` 页面
|
||||
- `BuiltinObjectIdPass`、`BuiltinInfiniteGridPass` 多个公开入口缺页
|
||||
- `ObjectIdPass.md`、`RenderPipeline.md`、`SceneRenderer.md` 与顶层 `XCEngine.md` 仍在传播 builtin-post-process 心智模型
|
||||
- 完成记录:
|
||||
- 已重写 `CameraRenderRequest.md`
|
||||
- 已清理 `2` 个失效 `.md` 链接
|
||||
- 已同步 `CameraRenderer.md` 与 `Passes.md` 的当前执行链路表述
|
||||
- 已删除 `BuiltinPostProcessPassPlan.md`、`BuiltinPostProcessPassSequenceBuilder.md`
|
||||
- 已补齐 `BuiltinObjectIdPass` / `BuiltinInfiniteGridPass` 缺失页面,并补充 `SceneViewportRenderPlan` 下 grid / selection outline pass factory 页面
|
||||
- 已新增 `SceneViewportGridPass` / `SceneViewportSelectionOutlinePass` 页面,并同步 `Editor/Viewport/Passes/Passes.md` 与 `Viewport.md` 的当前口径
|
||||
- 已同步 `ObjectIdPass.md`、`RenderPipeline.md`、`SceneRenderer.md` 与 `XCEngine.md` 的当前口径
|
||||
- 已补充 Rendering guide、`CameraRenderer::Render` 与 `ViewportHostService::RenderRequestedViewports` 的 request 级 pass 注入说明
|
||||
- 已为 `builtinPostProcess` / `BuiltinPostProcessRequest` / `m_builtinPostProcessBuilder` 增加 canonical 过期符号审计
|
||||
- 已复跑结构审计并确认 `Broken .md links: 0`
|
||||
|
||||
## T07 Editor / Core `EditorConsoleSink` 生命周期说明同步
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Editor/Core/EditorConsoleSink/**`
|
||||
- 必要时 `docs/api/XCEngine/Editor/Managers/Managers.md`
|
||||
- 必要时 `docs/api/_tools/audit_api_docs.py`
|
||||
- 主要源码依据:
|
||||
- `editor/src/Core/EditorConsoleSink.h`
|
||||
- `editor/src/Core/EditorConsoleSink.cpp`
|
||||
- `editor/src/panels/ConsolePanel.cpp`
|
||||
- `editor/src/Core/EditorLoggingSetup.h`
|
||||
- `tests/Editor/test_editor_console_sink.cpp`
|
||||
- 已关闭问题:
|
||||
- `EditorConsoleSink::GetInstance()` 旧文档仍把它写成会返回 fallback 实例
|
||||
- 相关 overview 页面没有写清活动 sink 销毁后会返回 `nullptr`
|
||||
- 审计脚本此前无法自动拦截这类旧生命周期表述
|
||||
- 完成记录:
|
||||
- 已同步 `EditorConsoleSink.md`、`GetInstance.md`、`Destructor.md`
|
||||
- 已同步 `Managers.md` 中对控制台 sink 生命周期的引用口径
|
||||
- 已为 `fallback 实例` 与“不会返回空指针”旧表述增加定向审计
|
||||
|
||||
## T08 Components / Scene / Scripting `GameObject` tag-layer 语义同步
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P0`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Components/GameObject/**`
|
||||
- `docs/api/XCEngine/Scene/Scene/**`
|
||||
- `docs/api/XCEngine/Scripting/Mono/MonoScriptRuntime/**`
|
||||
- 必要时 `docs/api/_guides/Components/GameObject-Component-Lifecycle-And-Serialization.md`
|
||||
- 必要时 `docs/api/_guides/Scene/Scene-Lifecycle-And-Serialization.md`
|
||||
- 主要源码依据:
|
||||
- `engine/include/XCEngine/Components/GameObject.h`
|
||||
- `engine/src/Components/GameObject.cpp`
|
||||
- `engine/src/Scene/Scene.cpp`
|
||||
- `engine/src/Scripting/Mono/MonoScriptRuntime.cpp`
|
||||
- `managed/XCEngine.ScriptCore/GameObject.cs`
|
||||
- `managed/XCEngine.ScriptCore/Component.cs`
|
||||
- `managed/XCEngine.ScriptCore/InternalCalls.cs`
|
||||
- `tests/Components/test_game_object.cpp`
|
||||
- `tests/Scene/test_scene.cpp`
|
||||
- `tests/scripting/test_mono_script_runtime.cpp`
|
||||
- 已确认问题:
|
||||
- `GameObject.md` 仍写“没有真正的 tag 系统”,并把 `FindGameObjectsWithTag()` 描述成按名字匹配;这与当前 `m_tag` / `CompareTag()` / `SetTag()` 实现已不符
|
||||
- `Scene.md` 与 `FindGameObjectWithTag.md` 仍在传播“按名字查 tag”的旧口径
|
||||
- `GameObject` 目录缺少 `GetTag.md`、`SetTag.md`、`CompareTag.md`、`GetLayer.md`、`SetLayer.md`
|
||||
- `Serialize.md` / `Deserialize.md` 尚未同步 `tag=` 字段、默认 `Untagged` 以及 layer clamp 语义
|
||||
- `MonoScriptRuntime` 总览页尚未解释 Unity 风格 `GameObject.tag` / `layer` / `CompareTag()` 已通过 internal call 暴露到托管侧
|
||||
- 产出要求:
|
||||
- 类型页与方法页都要明确区分当前原生实现、场景查询语义和托管暴露语义
|
||||
- 教程页要从“tag 只是名字别名”改成“当前已有独立 tag 字段,但仍是轻量 Unity 风格模型”
|
||||
- 需要写清:空 tag 会回落到 `Untagged`,layer 会 clamp 到 `[0, 31]`
|
||||
- 完成记录:
|
||||
- 已重写 `GameObject.md`、`Scene.md`、`FindGameObjectWithTag.md`
|
||||
- 已补齐 `GetTag.md`、`SetTag.md`、`CompareTag.md`、`GetLayer.md`、`SetLayer.md`
|
||||
- 已同步 `Serialize.md` / `Deserialize.md` 的 `tag=`、`layer=`、`Untagged` 与 clamp 语义
|
||||
- 已同步 `MonoScriptRuntime.md` 对托管 `GameObject.tag` / `layer` / `CompareTag()` 的 internal call 桥接说明
|
||||
- 已同步 `GameObject-Component-Lifecycle-And-Serialization.md` 与 `Scene-Lifecycle-And-Serialization.md` 的心智模型口径
|
||||
- 已补充 `Constructor`、`AddComponent`、`SetActive`、`SetParent`、`IsActive`、`IsActiveInHierarchy`、`Find`、`FindObjectsOfType`、`Awake`、`Start`、`Update`、`FixedUpdate`、`LateUpdate`、`OnDestroy`、`Destroy` 的真实生命周期与查询语义
|
||||
|
||||
## T09 Resources / Material 与材质 Artifact v2 语义同步
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P0`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Resources/Material/**`
|
||||
- `docs/api/XCEngine/Core/Asset/ArtifactFormats/**`
|
||||
- `docs/api/XCEngine/Core/Asset/AssetDatabase/**`
|
||||
- 必要时 `docs/api/XCEngine/Core/Asset/Asset.md`
|
||||
- 主要源码依据:
|
||||
- `engine/include/XCEngine/Resources/Material/Material.h`
|
||||
- `engine/src/Resources/Material/Material.cpp`
|
||||
- `engine/src/Resources/Material/MaterialLoader.cpp`
|
||||
- `engine/include/XCEngine/Core/Asset/ArtifactFormats.h`
|
||||
- `engine/src/Core/Asset/AssetDatabase.cpp`
|
||||
- `tests/Resources/Material/test_material.cpp`
|
||||
- `tests/Resources/Material/test_material_loader.cpp`
|
||||
- 已确认问题:
|
||||
- `Resources/Material/Material.md` 仍是旧模板式总览,没有覆盖当前公开语义
|
||||
- `Material` 目录缺少 `SetTextureAssetRef.md`、`GetTextureBindingAssetRef.md`、`GetTextureBindingLoadedTexture.md`
|
||||
- `ArtifactFormats.md` 仍写 `kMaterialArtifactSchemaVersion = 1`、magic `XCMAT01`,与当前 schema v2 / `XCMAT02` 不符
|
||||
- 材质 artifact 文档还没写清每个 texture binding 现在会序列化“编码后的 `AssetRef` + 可选 artifact/path 字符串”
|
||||
- `Material` 文档尚未解释纹理绑定现在既有 loaded handle,也有稳定 `AssetRef` 元数据,并且 `GetTexture()` 可在首次访问时通过 `TryResolveAssetPath()` 兑现延迟资源
|
||||
- 产出要求:
|
||||
- 重写 `Material.md`,把 shader 属性、texture binding 元数据、lazy resolve、路径与 `AssetRef` 的边界写清
|
||||
- 为新增公开方法补页,并把现有 `SetTexture` / `GetTexture` / `GetTextureBindingCount` 等页面更新到当前实现
|
||||
- 更新 `ArtifactFormats.md` 与 `AssetDatabase` 相关页面,写清材质 artifact v2 的字段顺序、兼容边界和设计动机
|
||||
- 完成记录:
|
||||
- 已重写 `docs/api/XCEngine/Resources/Material/Material.md` 与 `docs/api/XCEngine/Resources/Material/Material/Material.md`
|
||||
- 已新增 `SetTextureAssetRef.md`、`SetTexturePath.md`、`GetTextureBindingName.md`、`GetTextureBindingAssetRef.md`、`GetTextureBindingPath.md`、`GetTextureBindingLoadedTexture.md`、`GetTextureBindingTexture.md`
|
||||
- 已同步 `SetTexture.md`、`GetTexture.md`、`GetTextureBindingCount.md` 的当前 lazy-load 与 binding metadata 语义
|
||||
- 已更新 `ArtifactFormats.md`,把材质 artifact 修正到 schema v2 / `XCMAT02`,并写清 texture binding 三元组布局
|
||||
- 已更新 `AssetDatabase.md` 的当前 importerVersion 常量,并在 `Asset.md` 补充 `.xcmat` v2 的跨模块说明
|
||||
- 已为旧 `kMaterialArtifactSchemaVersion = 1` / `XCMAT01` 文案增加审计回归保护
|
||||
- 已复跑结构审计并确认 `Broken .md links: 0`
|
||||
|
||||
## T10 Editor / Viewport `SceneViewportShaderPaths` canonical 补页
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportShaderPaths/**`
|
||||
- 必要时 `docs/api/XCEngine/Editor/Viewport/Viewport.md`
|
||||
- 主要源码依据:
|
||||
- `editor/src/Viewport/SceneViewportShaderPaths.h`
|
||||
- `editor/src/Viewport/Passes/SceneViewportGridPass.cpp`
|
||||
- `editor/src/Viewport/Passes/SceneViewportSelectionOutlinePass.cpp`
|
||||
- 已关闭问题:
|
||||
- `editor/src/Viewport/SceneViewportShaderPaths.h` 新进入工作树后还没有 canonical 页面
|
||||
- 结构审计一度出现 `Editor source headers: 125` 但 `Valid source refs (Editor canonical): 124`
|
||||
- 完成记录:
|
||||
- 已新增 `SceneViewportShaderPaths.md` 与 5 个 helper/function 页面
|
||||
- 已同步 `Viewport.md` 的目录结构总览
|
||||
- 已复跑结构审计并确认 `Valid source refs (Editor canonical): 125`
|
||||
|
||||
## T11 Platform / 概述页与方法页模板化表述清理
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Platform/**`
|
||||
- 主要源码依据:
|
||||
- `engine/include/XCEngine/Platform/GameTime.h`
|
||||
- `engine/include/XCEngine/Platform/PlatformTypes.h`
|
||||
- `engine/include/XCEngine/Platform/IClock.h`
|
||||
- `engine/include/XCEngine/Platform/IWindow.h`
|
||||
- `engine/include/XCEngine/Platform/IFileSystem.h`
|
||||
- `engine/include/XCEngine/Platform/IPlatform.h`
|
||||
- `engine/include/XCEngine/Platform/IDynamicLibrary.h`
|
||||
- `engine/include/XCEngine/Platform/IDisplayEnumerator.h`
|
||||
- `engine/include/XCEngine/Platform/Window.h`
|
||||
- `engine/include/XCEngine/Platform/Windows/WindowsWindow.h`
|
||||
- `engine/include/XCEngine/Platform/Windows/WindowsInputModule.h`
|
||||
- `engine/src/Platform/Window.cpp`
|
||||
- `engine/src/Platform/Windows/WindowsWindow.cpp`
|
||||
- `engine/src/Platform/Windows/WindowsInputModule.cpp`
|
||||
- 已关闭问题:
|
||||
- `Platform` 下多组概述页仍把自己写成“canonical 总览”,没有说明符号本身的职责和边界
|
||||
- 大量方法页仍残留“获取相关状态或对象”“公开方法,详见头文件声明”“参数语义详见头文件声明”等模板废话
|
||||
- `WindowsInputModule::PumpEvents()` 当前是空实现,但旧页没有说明,容易误导成真实消息泵入口
|
||||
- `WindowsWindow` 的 Win32 当前实现路径没有写清,例如 `Create()`、`Destroy()`、`PumpEvents()`、`SetFullscreen()` 与 `ShouldClose()`
|
||||
- 完成记录:
|
||||
- 已重写 `GameTime`、`PlatformTypes`、`IClock`、`IWindow`、`IFileSystem`、`IPlatform`、`IDynamicLibrary`、`IDisplayEnumerator`、`Window`、`WindowsWindow`、`WindowsInputModule` 相关 overview 与方法页
|
||||
- 已把 `Platform` 下残留模板短语、参数占位语和 canonical 占位说明清理到 `0`
|
||||
- 已写清 `Window` / `WindowsWindow` / `WindowsInputModule` 的当前实现语义与输入桥接关系
|
||||
- 已复跑结构审计并确认 `Old template pages: 0`、`Broken .md links: 0`
|
||||
|
||||
## T12 Cross-Module / canonical 式概述废话清理
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/RHI/D3D12/**`
|
||||
- `docs/api/XCEngine/Resources/**`
|
||||
- 主要源码依据:
|
||||
- `engine/include/XCEngine/RHI/D3D12/D3D12Types.h`
|
||||
- `engine/include/XCEngine/RHI/D3D12/D3D12Common.h`
|
||||
- `engine/include/XCEngine/RHI/D3D12/D3D12Enums.h`
|
||||
- `engine/include/XCEngine/RHI/D3D12/D3D12RootSignature.h`
|
||||
- `engine/include/XCEngine/RHI/D3D12/D3D12PipelineState.h`
|
||||
- `engine/include/XCEngine/Resources/Resources.h`
|
||||
- `engine/include/XCEngine/Resources/Texture/Texture.h`
|
||||
- `engine/include/XCEngine/Resources/Texture/TextureLoader.h`
|
||||
- `engine/include/XCEngine/Resources/Texture/TextureImportSettings.h`
|
||||
- `engine/include/XCEngine/Resources/Mesh/Mesh.h`
|
||||
- `engine/include/XCEngine/Resources/Mesh/MeshLoader.h`
|
||||
- `engine/include/XCEngine/Resources/Mesh/MeshImportSettings.h`
|
||||
- `engine/include/XCEngine/Resources/Shader/Shader.h`
|
||||
- `engine/include/XCEngine/Resources/Shader/ShaderLoader.h`
|
||||
- `engine/include/XCEngine/Resources/AudioClip/AudioClip.h`
|
||||
- `engine/include/XCEngine/Resources/AudioClip/AudioLoader.h`
|
||||
- 已关闭问题:
|
||||
- `RHI/D3D12` 与 `Resources` 下仍有一批 overview 页把“概述”写成“当前页面作为平行目录中的 canonical 总览”,没有解释符号本身做什么
|
||||
- `Texture`、`Mesh`、`Shader`、`AudioClip` 等资源类型页没有把类型边界、持有的数据和辅助声明写清
|
||||
- `D3D12Types`、`D3D12Common`、`D3D12Enums` 这类 helper header 页没有说明它们是转换 / 构造 / 检查函数集合
|
||||
- 完成记录:
|
||||
- 已重写 `RHI/D3D12` 与 `Resources` 下全部 `16` 个 canonical 式 overview 页
|
||||
- 已把全仓库 `docs/api/XCEngine/**` 中“当前页面作为平行目录中的 canonical 总览”这类概述废话清理到 `0`
|
||||
- 已复跑结构审计并确认 `Broken .md links: 0`、`Old template pages: 0`
|
||||
|
||||
## T13 Components / `GameObject` 剩余辅助页内容化补齐
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P2`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Components/GameObject/DetachChildren.md`
|
||||
- `docs/api/XCEngine/Components/GameObject/DetachFromParent.md`
|
||||
- `docs/api/XCEngine/Components/GameObject/Destructor.md`
|
||||
- `docs/api/XCEngine/Components/GameObject/GetChild.md`
|
||||
- `docs/api/XCEngine/Components/GameObject/GetChildCount.md`
|
||||
- `docs/api/XCEngine/Components/GameObject/GetChildren.md`
|
||||
- `docs/api/XCEngine/Components/GameObject/GetComponent.md`
|
||||
- `docs/api/XCEngine/Components/GameObject/GetComponentInChildren.md`
|
||||
- `docs/api/XCEngine/Components/GameObject/GetComponentInParent.md`
|
||||
- `docs/api/XCEngine/Components/GameObject/GetComponents.md`
|
||||
- `docs/api/XCEngine/Components/GameObject/GetComponentsInChildren.md`
|
||||
- `docs/api/XCEngine/Components/GameObject/GetID.md`
|
||||
- `docs/api/XCEngine/Components/GameObject/GetName.md`
|
||||
- `docs/api/XCEngine/Components/GameObject/GetParent.md`
|
||||
- `docs/api/XCEngine/Components/GameObject/GetScene.md`
|
||||
- `docs/api/XCEngine/Components/GameObject/GetTransform.md`
|
||||
- `docs/api/XCEngine/Components/GameObject/GetUUID.md`
|
||||
- `docs/api/XCEngine/Components/GameObject/RemoveComponent.md`
|
||||
- `docs/api/XCEngine/Components/GameObject/SetName.md`
|
||||
- 主要源码依据:
|
||||
- `engine/include/XCEngine/Components/GameObject.h`
|
||||
- `engine/src/Components/GameObject.cpp`
|
||||
- `tests/Components/test_game_object.cpp`
|
||||
- `tests/Scene/test_scene.cpp`
|
||||
- `tests/scripting/test_mono_script_runtime.cpp`
|
||||
- 已关闭问题:
|
||||
- `GameObject` 模块的核心生命周期、tag/layer 与场景边界已经完成,但上述辅助页仍残留模板式表述
|
||||
- 这些页面尚未写清模板接口的真实语义,例如 `Transform` 特例、层级递归查询、观察指针返回与移除边界
|
||||
- 产出要求:
|
||||
- 把这些方法页全部改成基于当前源码的行为说明
|
||||
- 优先写清组件查询模板、层级辅助接口和对象身份访问器的真实边界
|
||||
- 不重复改动本轮已经完成内容化的生命周期和 tag/layer 页面
|
||||
- 完成记录:
|
||||
- 已重写 `DetachChildren.md`、`DetachFromParent.md`、`Destructor.md`、`GetChild.md`、`GetChildCount.md`、`GetChildren.md`
|
||||
- 已重写 `GetComponent.md`、`GetComponentInChildren.md`、`GetComponentInParent.md`、`GetComponents.md`、`GetComponentsInChildren.md`、`RemoveComponent.md`
|
||||
- 已重写 `GetID.md`、`GetName.md`、`GetParent.md`、`GetScene.md`、`GetTransform.md`、`GetUUID.md`、`SetName.md`
|
||||
- 已写清 `Transform` 特例、层级查询顺序、`Scene` / registry 观察指针语义,以及 `RemoveComponent` 当前不会补发 `OnDestroy()`
|
||||
|
||||
## T14 Rendering / `RenderMaterialUtility` schema-driven 材质常量 payload 语义同步
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Rendering/RenderMaterialUtility/**`
|
||||
- `docs/api/XCEngine/Rendering/Pipelines/BuiltinForwardPipeline/**`
|
||||
- 必要时 `docs/api/_tools/audit_api_docs.py`
|
||||
- 主要源码依据:
|
||||
- `engine/include/XCEngine/Rendering/RenderMaterialUtility.h`
|
||||
- `engine/include/XCEngine/Rendering/Pipelines/BuiltinForwardPipeline.h`
|
||||
- `engine/src/Rendering/Pipelines/BuiltinForwardPipeline.cpp`
|
||||
- `engine/include/XCEngine/Resources/Material/Material.h`
|
||||
- `tests/Rendering/unit/test_render_scene_extractor.cpp`
|
||||
- 已关闭问题:
|
||||
- `RenderMaterialUtility` 总览页尚未覆盖新进入 public header 的 `MaterialConstantPayloadView` 与 `ResolveSchemaMaterialConstantPayload(...)`
|
||||
- `BuiltinForwardPipeline.md` 仍把逐材质常量写成“目前只写入 `baseColorFactor`”,没有同步当前优先消费 schema-driven payload、仅在缺失时回退 fallback 的实现
|
||||
- `BuildBuiltinForwardMaterialData.md` 还没把自己定位成兼容 fallback helper,容易与当前主路径混淆
|
||||
- 完成记录:
|
||||
- 已新增 `BuiltinForwardMaterialData.md`、`MaterialConstantPayloadView.md`、`ResolveSchemaMaterialConstantPayload.md`
|
||||
- 已重写 `RenderMaterialUtility.md` 与 `BuildBuiltinForwardMaterialData.md`,写清 schema payload 与 builtin forward fallback 的边界
|
||||
- 已同步 `BuiltinForwardPipeline.md` 与 `Render.md`,补入 `Material::GetConstantBufferData()` 主路径和 `FallbackPerMaterialConstants` 回退逻辑
|
||||
- 已为“逐材质常量目前只写入 `baseColorFactor`”等旧口径增加 canonical 审计回归保护
|
||||
- 已复跑结构审计并确认 `Stale canonical doc tokens: 0`
|
||||
|
||||
## T15 Editor / Scripting 脚本程序集重建与运行时锁语义同步
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Editor/Scripting/EditorScriptAssemblyBuilder/**`
|
||||
- `docs/api/XCEngine/Editor/Application/RebuildScriptingAssemblies.md`
|
||||
- 必要时 `docs/api/XCEngine/Editor/Application/Application.md`
|
||||
- 主要源码依据:
|
||||
- `editor/src/Scripting/EditorScriptAssemblyBuilder.cpp`
|
||||
- `editor/src/Application.cpp`
|
||||
- `tests/Editor/test_editor_script_assembly_builder.cpp`
|
||||
- 已关闭问题:
|
||||
- `EditorScriptAssemblyBuilder` 文档仍把 `mscorlib.dll` 写成“每次重建都复制”,没有同步当前“首次复制、后续复用项目本地 corlib”的实现
|
||||
- `RebuildProjectAssemblies.md` 没写清活动 Mono runtime 仍持有 `GameScripts.dll` 时可能出现文件锁失败
|
||||
- `Application::RebuildScriptingAssemblies` 文档仍写“构建失败会保留旧 runtime”,与当前先 `ShutdownScriptingRuntime()` 再构建的实现不符
|
||||
- 完成记录:
|
||||
- 已同步 `EditorScriptAssemblyBuilder.md` 与 `RebuildProjectAssemblies.md`,补入项目本地 `mscorlib.dll` 复用策略、Mono 文件锁失败路径与测试锚点
|
||||
- 已同步 `Application::RebuildScriptingAssemblies` 与 `Application.md`,写清“先卸载当前 runtime 释放程序集锁,再重建并在成功后重载”的真实顺序
|
||||
- 已复跑结构审计并确认 `Broken .md links: 0`、`Stale canonical doc tokens: 0`
|
||||
|
||||
## T16 Resources / Rendering Passes SceneView shader ownership 口径同步
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Resources/BuiltinResources/**`
|
||||
- `docs/api/XCEngine/Rendering/Passes/BuiltinInfiniteGridPass/**`
|
||||
- `docs/api/XCEngine/Rendering/Passes/BuiltinObjectIdOutlinePass/**`
|
||||
- 主要源码依据:
|
||||
- `engine/include/XCEngine/Resources/BuiltinResources.h`
|
||||
- `engine/src/Resources/BuiltinResources.cpp`
|
||||
- `engine/include/XCEngine/Rendering/Passes/BuiltinInfiniteGridPass.h`
|
||||
- `engine/src/Rendering/Passes/BuiltinInfiniteGridPass.cpp`
|
||||
- `engine/include/XCEngine/Rendering/Passes/BuiltinObjectIdOutlinePass.h`
|
||||
- `engine/src/Rendering/Passes/BuiltinObjectIdOutlinePass.cpp`
|
||||
- `editor/src/Viewport/SceneViewportShaderPaths.h`
|
||||
- 已关闭问题:
|
||||
- `BuiltinResources.md` 仍把 `object-id-outline` / `infinite-grid` 写成 engine `builtin://shaders/*` helper 与 builtin shader 工厂的一部分,但当前头文件与实现已只保留 `forward-lit`、`object-id`
|
||||
- `BuiltinInfiniteGridPass` 与 `BuiltinObjectIdOutlinePass` 已改为由调用方注入 `shaderPath`,文档却仍在传播“固定 builtin shader”口径
|
||||
- 两个 pass 的文档树缺少 `SetShaderPath.md`、`GetShaderPath.md`;`BuiltinInfiniteGridPass` 还缺少 `Constructor.md` 与 `Destructor.md`
|
||||
- 完成记录:
|
||||
- 已更新 `BuiltinResources.md`,把 builtin shader 集合收口到 `forward-lit` / `object-id`,并写清 Scene View grid / outline shader 现在由 editor 侧 `SceneViewportShaderPaths` 提供
|
||||
- 已重写 `BuiltinInfiniteGridPass.md`、`Render.md`、`Shutdown.md`,补上 `Constructor.md`、`Destructor.md`、`SetShaderPath.md`、`GetShaderPath.md`
|
||||
- 已重写 `BuiltinObjectIdOutlinePass.md`、`Constructor.md`、`Render.md`、`Shutdown.md`,补上 `SetShaderPath.md` 与 `GetShaderPath.md`
|
||||
|
||||
## T17 Editor / Viewport `SceneViewportOverlayProviders` canonical 补页
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportOverlayProviders/**`
|
||||
- 主要源码依据:
|
||||
- `editor/src/Viewport/SceneViewportOverlayProviders.h`
|
||||
- `editor/src/Viewport/SceneViewportOverlayProviders.cpp`
|
||||
- `editor/src/Viewport/SceneViewportOverlayBuilder.h`
|
||||
- `tests/editor/test_scene_viewport_overlay_providers.cpp`
|
||||
- 已关闭问题:
|
||||
- `editor/src/Viewport/SceneViewportOverlayProviders.h` 新进入工作树后还没有 canonical 页面
|
||||
- 结构审计出现 `Editor source headers: 126` 但 `Valid source refs (Editor canonical): 125`
|
||||
- 缺少对 overlay build context、provider registry 和默认相机 / 灯光 provider 工厂的当前语义说明
|
||||
- 完成记录:
|
||||
- 已新增 `SceneViewportOverlayProviders.md`、`SceneViewportOverlayBuildContext.md`、`ISceneViewportOverlayProvider.md`、`SceneViewportOverlayProviderRegistry.md`
|
||||
- 已新增 `CreateSceneViewportCameraOverlayProvider.md`、`CreateSceneViewportLightOverlayProvider.md`、`BuildDefaultSceneViewportOverlayProviderRegistry.md`
|
||||
- 已复跑结构审计并确认 `Valid source refs (Editor canonical): 126`、`Broken .md links: 0`
|
||||
|
||||
## T18 Editor / Viewport overlay builder provider 化口径同步
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围:
|
||||
- `docs/api/XCEngine/Editor/Viewport/SceneViewportOverlayBuilder/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/ViewportHostService/**`
|
||||
- `docs/api/XCEngine/Editor/Viewport/Viewport.md`
|
||||
- 必要时 `docs/api/_guides/Editor/**`
|
||||
- 主要源码依据:
|
||||
- `editor/src/Viewport/SceneViewportOverlayBuilder.h`
|
||||
- `editor/src/Viewport/SceneViewportOverlayBuilder.cpp`
|
||||
- `editor/src/Viewport/SceneViewportOverlayProviders.h`
|
||||
- `editor/src/Viewport/ViewportHostService.h`
|
||||
- `tests/editor/test_scene_viewport_overlay_providers.cpp`
|
||||
- 已关闭问题:
|
||||
- `SceneViewportOverlayBuilder` 文档仍把类型写成“无状态构建器 + static Build(...)”,没有同步当前实例化 builder + provider registry 的实现
|
||||
- `SceneViewportOverlayBuilder` 目录缺少 `Constructor.md` 与 `GetProviderRegistry.md`
|
||||
- `ViewportHostService.md` 仍把基础 overlay 来源写成 `SceneViewportOverlayBuilder::Build(...)`,没有同步当前成员 `m_sceneViewportOverlayBuilder`
|
||||
- guide 层仍在传播 `overlay builder -> overlay pass` 与“先把 scene icon 塞进 builder”的旧扩展口径
|
||||
- 完成记录:
|
||||
- 已重写 `SceneViewportOverlayBuilder.md` 与 `Build.md`,把默认 registry、build context 和 provider 聚合链路写清
|
||||
- 已新增 `Constructor.md` 与 `GetProviderRegistry.md`
|
||||
- 已同步 `ViewportHostService.md`、`Viewport.md` 以及两篇 Editor guide 的当前 provider 化心智模型
|
||||
- 已把新扩展建议改成 `overlay provider -> overlay builder -> overlay pass`
|
||||
|
||||
## 当前结论
|
||||
|
||||
- 本轮已经关掉十七组明确的内容级失配:
|
||||
- `Viewport` 渲染计划与宿主流程
|
||||
- `Core/Asset` 缓存接口与导入服务语义
|
||||
- `MonoScriptRuntime` 托管销毁入口
|
||||
- `Rendering` 相机请求、Passes 与单相机执行链旧口径
|
||||
- `EditorConsoleSink` 生命周期与空指针返回语义
|
||||
- 跨模块 guide / overview 漂移的本轮复核与拆分
|
||||
- `Material` / `ArtifactFormats` / `AssetDatabase` 的材质 artifact v2 与 texture `AssetRef` 语义
|
||||
- `GameObject` / `Scene` / `Mono` 的 tag-layer 与托管暴露语义
|
||||
- `GameObject` 剩余辅助访问器 / 层级辅助页的内容化补齐
|
||||
- `SceneViewportShaderPaths` canonical 缺页
|
||||
- `Platform` 模块概述页与方法页的模板化废话清理
|
||||
- `RHI/D3D12` 与 `Resources` 的 canonical 式概述废话清理
|
||||
- `RenderMaterialUtility` / `BuiltinForwardPipeline` 的 schema-driven 材质常量 payload 语义
|
||||
- `Editor` 脚本程序集重建流程中的 corlib 复用与 runtime 文件锁语义
|
||||
- `BuiltinResources` 与 Scene View grid / outline shader ownership、`shaderPath` 注入口径
|
||||
- `SceneViewportOverlayProviders` canonical 缺页
|
||||
- `SceneViewportOverlayBuilder` / `ViewportHostService` / guide 层的 provider 化心智模型同步
|
||||
- 当前结构审计为全绿。
|
||||
- 当前仍建议保留 `T04` 与 `T05` 作为持续性复核入口,用来承接后续源码变更带来的新文档漂移。
|
||||
590
docs/used/API文档并行更新任务池_2026-04-02.md
Normal file
590
docs/used/API文档并行更新任务池_2026-04-02.md
Normal file
@@ -0,0 +1,590 @@
|
||||
# API 文档并行更新任务池(2026-04-02)
|
||||
|
||||
## 目的
|
||||
|
||||
基于 `2026-04-02` 当前工作树,这份清单用于把 API 文档更新任务拆成可并行认领的独立块,供多个会话同时推进。
|
||||
|
||||
## 认领规则
|
||||
|
||||
- 一次只认领 `1` 个任务块,先改 `状态` 和 `认领人`。
|
||||
- 只修改自己任务块的 `写入范围`,不要跨任务顺手改别的模块页。
|
||||
- 除 `T09` 之外,其他任务不要更新 `docs/api/_meta/rebuild-status.md`,避免多人冲突。
|
||||
- 每个任务都要以源码、实现、测试、真实调用点为依据,不允许只按命名猜测行为。
|
||||
- 如果任务执行中发现需要新增 guide,统一放到 `docs/api/_guides/<Module>/` 下。
|
||||
|
||||
## 当前并行推荐
|
||||
|
||||
- 历史任务 `T01-T20` 已完成,本轮文档内容同步与收口已落地。
|
||||
- 如果继续并行推进,重点不再是补历史缺页,而是:
|
||||
- 跟踪新增源码 API
|
||||
- 继续人工抽样审阅审计中提示的高风险单页目录
|
||||
- `2026-04-03 00:24:08` 这轮复核后,已新增 `T21-T27`;优先从 `Input`、`Editor` 项目工作流、`Game View -> Runtime Input` 三块并行切入。
|
||||
|
||||
## 任务池
|
||||
|
||||
## T01 Editor / Viewport 子模块补齐与重写
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex-Viewport`
|
||||
- 优先级: `P0`
|
||||
- 写入范围: `docs/api/XCEngine/Editor/Viewport/**`、`docs/api/XCEngine/Editor/panels/SceneViewPanel/**`、`docs/api/XCEngine/Editor/panels/ViewportPanelContent/**`
|
||||
- 主要源码依据: `editor/src/Viewport/**`、`editor/src/panels/SceneViewPanel.*`、`editor/src/panels/ViewportPanelContent.h`、`tests/editor/test_scene_viewport_camera_controller.cpp`
|
||||
- 当前缺口: `Viewport` 整个 canonical 树尚未建立;以下页面当前缺失: `SceneViewportCameraController`、`SceneViewportMoveGizmo`、`SceneViewportRotateGizmo`、`SceneViewportScaleGizmo`、`SceneViewportOverlayRenderer`、`ViewportHostService`、`ViewportHostRenderFlowUtils`、`SceneViewportEditorOverlayData`、`SceneViewportOverlayBuilder`、`ViewportPanelContent`
|
||||
- 完成标准: 补齐 `Viewport/Viewport.md` 与所有类型页;`SceneViewPanel` 文档重写到当前 gizmo / overlay / host flow 实现;写清楚生命周期、交互链路、渲染路径和测试覆盖
|
||||
|
||||
## T02 Editor / ScriptComponentEditor 补齐
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P0`
|
||||
- 写入范围: `docs/api/XCEngine/Editor/ComponentEditors/ScriptComponentEditor/**`、`docs/api/XCEngine/Editor/ComponentEditors/ScriptComponentEditorUtils/**`、`docs/api/XCEngine/Editor/ComponentEditors/ComponentEditors.md`、`docs/api/XCEngine/Editor/ComponentEditors/ComponentEditorRegistry/**`
|
||||
- 主要源码依据: `editor/src/ComponentEditors/ScriptComponentEditor.h`、`editor/src/ComponentEditors/ScriptComponentEditorUtils.h`、`editor/src/ComponentEditors/ComponentEditorRegistry.cpp`
|
||||
- 当前缺口: `ScriptComponentEditor` 与 `ScriptComponentEditorUtils` 还没有 canonical 页面;组件编辑器总览也需要纳入脚本组件编辑器
|
||||
- 完成标准: 补齐缺页;说明 Inspector 侧脚本字段绘制、字段元数据来源、与 `ScriptEngine` / `ScriptComponent` 的关系
|
||||
|
||||
## T03 Core / AssetDatabase 新建与资产数据库链路说明
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex-Asset`
|
||||
- 优先级: `P0`
|
||||
- 写入范围: `docs/api/XCEngine/Core/Asset/AssetDatabase/**`、`docs/api/XCEngine/Core/Asset/Asset.md`
|
||||
- 主要源码依据: `engine/include/XCEngine/Core/Asset/AssetDatabase.h`、相关 `.cpp` 实现、项目目录下新增的 `.meta` 与 `Library` 资产缓存变化
|
||||
- 当前缺口: `AssetDatabase` 对应的 canonical 类型页完全缺失;`Core/Asset` 模块总览需要反映新的数据库/导入缓存方向
|
||||
- 完成标准: 建立 `AssetDatabase` 页面,明确 GUID、path、meta、导入缓存、查询职责,以及它和 `ProjectPanel` / `ResourceManager` / 资源导入流程的关系
|
||||
|
||||
## T04 Rendering / Passes 子模块与 BuiltinObjectIdOutlinePass 补齐
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P0`
|
||||
- 写入范围: `docs/api/XCEngine/Rendering/Passes/**`
|
||||
- 主要源码依据: `engine/include/XCEngine/Rendering/Passes/BuiltinObjectIdOutlinePass.h`、`engine/src/Rendering/Passes/BuiltinObjectIdOutlinePass.cpp`
|
||||
- 当前缺口: `Rendering/Passes` 目录当前没有 canonical 文档树;`BuiltinObjectIdOutlinePass` 页面缺失
|
||||
- 完成标准: 新建 `Passes/Passes.md` 和 `BuiltinObjectIdOutlinePass` 类型页;写清楚对象 ID / 轮廓高亮的输入输出、依赖资源、典型使用位置和当前限制
|
||||
|
||||
## T05 Scripting 模块内容重构
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围: `docs/api/XCEngine/Scripting/**`、`docs/api/_guides/Scripting/**`
|
||||
- 主要源码依据: `engine/include/XCEngine/Scripting/IScriptRuntime.h`、`Mono/MonoScriptRuntime.h`、`NullScriptRuntime.h`、`ScriptComponent.h`、`ScriptEngine.h` 及对应 `.cpp`;`tests/scripting/**`
|
||||
- 当前缺口: 结构存在,但脚本运行时、字段同步、项目脚本程序集、空运行时回退等内容需要按当前实现重写
|
||||
- 完成标准: 明确运行时抽象、Mono 后端、Null 后端、字段存储与组件生命周期;必要时补一篇项目脚本程序集 / 字段同步 guide
|
||||
|
||||
## T06 Editor 运行时胶水层与面板内容更新
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围: `docs/api/XCEngine/Editor/Application/**`、`docs/api/XCEngine/Editor/Core/EventBus/**`、`docs/api/XCEngine/Editor/panels/InspectorPanel/**`、`docs/api/XCEngine/Editor/panels/ProjectPanel/**`、`docs/api/XCEngine/Editor/UI/Widgets/**`、`docs/api/XCEngine/Editor/Actions/HierarchyActionRouter/**`、`docs/api/XCEngine/Editor/Commands/EntityCommands/**`
|
||||
- 主要源码依据: `editor/src/Application.*`、`editor/src/Core/EventBus.h`、`editor/src/panels/InspectorPanel.*`、`editor/src/panels/ProjectPanel.*`、`editor/src/UI/Widgets.h`、`editor/src/Actions/HierarchyActionRouter.h`、`editor/src/Commands/EntityCommands.h`
|
||||
- 当前缺口: 这些页面虽然大多存在,但内容容易落后于当前交互链路;`ProjectPanel` 虽已较新,仍要根据这轮源码变化做二次核对
|
||||
- 完成标准: 把“Editor 主循环 -> EventBus -> 面板 -> Action/Command”这条链路写清楚;Inspector/Project/Hierarchy 相关页内容与当前实现严格对齐
|
||||
|
||||
## T07 Rendering 相机请求与对象 ID 渲染链路更新
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围: `docs/api/XCEngine/Rendering/CameraRenderRequest/**`、`docs/api/XCEngine/Rendering/CameraRenderer/**`、`docs/api/XCEngine/Rendering/RenderMaterialUtility/**`、`docs/api/XCEngine/Rendering/Rendering.md`
|
||||
- 主要源码依据: `engine/include/XCEngine/Rendering/CameraRenderRequest.h`、`engine/src/Rendering/CameraRenderer.cpp`、`engine/src/Resources/Material/MaterialLoader.cpp`、`engine/src/Rendering/Passes/BuiltinObjectIdOutlinePass.cpp`
|
||||
- 当前缺口: 文档需要反映这轮 renderer 里对象 ID、outline、camera request、材质 render state 的新关系
|
||||
- 完成标准: 写清楚 camera request 的职责边界、camera renderer 的主流程、object-id/outline 的接入点,以及材质 render state 对渲染路径的影响
|
||||
|
||||
## T08 Components / MeshFilterComponent 与资源绑定链路更新
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围: `docs/api/XCEngine/Components/MeshFilterComponent/**`、`docs/api/XCEngine/Components/Components.md`
|
||||
- 主要源码依据: `engine/include/XCEngine/Components/MeshFilterComponent.h`、相关 `.cpp`、`tests/Resources/Mesh/test_mesh_loader.cpp`、`tests/Resources/Material/test_material_loader.cpp`
|
||||
- 当前缺口: `MeshFilterComponent` 页面存在,但需要重新核对 mesh handle / path / 资源解析链路;模块总览也应补充 MeshFilter 在渲染和资产导入链路中的定位
|
||||
- 完成标准: 说明 `MeshFilterComponent` 如何保存 mesh 引用、如何与资源系统和渲染提取流程衔接,以及当前限制
|
||||
|
||||
## T09 根总览与最终审计
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P2`
|
||||
- 写入范围: `docs/api/XCEngine/XCEngine.md`、受影响的模块总览页、`docs/api/_meta/rebuild-status.md`
|
||||
- 主要源码依据: 前面所有任务的完成结果
|
||||
- 当前缺口: 已完成根总览与模块总览收口;`2026-04-02 23:22:27` 的最终审计结果显示 `246/246` 个 public headers 全量覆盖,结构性问题保持 `0`
|
||||
- 完成标准: 在 `T10-T13` 完成后统一调整总览页导航;重新执行 `audit_api_docs.py`、覆盖校验与链接校验;确认未覆盖 public headers 归零后写回最终 `rebuild-status.md`
|
||||
|
||||
## 审计结论(2026-04-02 23:22:27)
|
||||
|
||||
- 本轮全量审计已执行: `python docs/api/_tools/audit_api_docs.py`
|
||||
- 当前结构性问题为 `0`: 无失效 `.md` 链接、无非 `.md` 相对链接、无旧模板页面、无扁平 header 页面、无缺失目录总览页
|
||||
- 当前剩余覆盖缺口: `0` 个 public headers 未覆盖
|
||||
- 受影响模块:
|
||||
- `Core`: `0`
|
||||
- `Rendering`: `0`
|
||||
- `Resources`: `0`
|
||||
- `Scene`: `0`
|
||||
- 说明:
|
||||
- `T01-T13` 对应的结构重构、基础层补页与总览收口已全部落地
|
||||
- `AssetImportService` 与 `ProjectAssetIndex` 两个 `Core/Asset` 尾项已补齐
|
||||
- canonical API 文档树当前与 `engine/include/XCEngine` 的 public header 集合保持全量对齐
|
||||
|
||||
## T10 Core / Asset 标识与产物格式补齐
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex-Asset2`
|
||||
- 优先级: `P1`
|
||||
- 写入范围: `docs/api/XCEngine/Core/Asset/ArtifactFormats/**`、`docs/api/XCEngine/Core/Asset/AssetGUID/**`、`docs/api/XCEngine/Core/Asset/AssetRef/**`
|
||||
- 主要源码依据: `engine/include/XCEngine/Core/Asset/ArtifactFormats.h`、`engine/include/XCEngine/Core/Asset/AssetGUID.h`、`engine/include/XCEngine/Core/Asset/AssetRef.h`、相关使用点 `engine/src/Components/MeshFilterComponent.cpp`、`engine/src/Resources/*/*Loader.cpp`、`tests/core/Asset/test_resource_manager.cpp`、`tests/Resources/Texture/test_texture_loader.cpp`
|
||||
- 当前缺口: 已补齐 `ArtifactFormats`、`AssetGUID`、`AssetRef` 三个 canonical 页面,并将资产身份 / 引用 / artifact 格式链路并入 `Core/Asset` 模块叙述
|
||||
- 完成标准: 建立三个 canonical 类型页,写清楚 GUID 格式、AssetRef 结构语义、artifact 产物文件格式在资源导入与反序列化链路中的作用
|
||||
|
||||
## T11 Rendering / RenderPass 与 SceneRenderRequest 基础层补齐
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围: `docs/api/XCEngine/Rendering/ObjectIdEncoding/**`、`docs/api/XCEngine/Rendering/ObjectIdPass/**`、`docs/api/XCEngine/Rendering/RenderPass/**`、`docs/api/XCEngine/Rendering/RenderSceneUtility/**`、`docs/api/XCEngine/Rendering/SceneRenderRequestPlanner/**`、`docs/api/XCEngine/Rendering/SceneRenderRequestUtils/**`
|
||||
- 主要源码依据: `engine/include/XCEngine/Rendering/ObjectIdEncoding.h`、`ObjectIdPass.h`、`RenderPass.h`、`RenderSceneUtility.h`、`SceneRenderRequestPlanner.h`、`SceneRenderRequestUtils.h`,对应 `.cpp`,以及 `tests/Rendering/unit/test_render_pass.cpp`、`test_render_scene_utility.cpp`、`test_scene_render_request_planner.cpp`、`test_scene_render_request_utils.cpp`、`test_camera_scene_renderer.cpp`、`tests/Editor/test_viewport_render_flow_utils.cpp`
|
||||
- 当前缺口: 已补齐 `ObjectIdEncoding`、`ObjectIdPass`、`RenderPass`、`RenderSceneUtility`、`SceneRenderRequestPlanner`、`SceneRenderRequestUtils` 六个基础层页面,并回写 Rendering 总览导航
|
||||
- 完成标准: 补齐六个类型页,明确 render pass 生命周期、object-id 编解码语义、scene request 规划规则,以及这些基础设施与 `CameraRenderer` / editor viewport 的衔接
|
||||
|
||||
## T12 Resources / BuiltinResources 补齐
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围: `docs/api/XCEngine/Resources/BuiltinResources/**`
|
||||
- 主要源码依据: `engine/include/XCEngine/Resources/BuiltinResources.h`、`engine/src/Resources/BuiltinResources.cpp`、相关调用点 `editor/src/Commands/EntityCommands.h`、`engine/src/Rendering/Passes/BuiltinObjectIdPass.cpp`、`engine/src/Rendering/Passes/BuiltinObjectIdOutlinePass.cpp`、`engine/src/Rendering/Pipelines/BuiltinForwardPipeline.cpp`、`tests/Resources/Shader/test_shader_loader.cpp`
|
||||
- 当前缺口: 已建立 `BuiltinResources` canonical 页面,并纳入 `Resources` 模块总览
|
||||
- 完成标准: 建立 `BuiltinResources` 类型页,写清楚内置 mesh / material / shader / primitive display name 的职责边界、典型调用点与当前限制
|
||||
|
||||
## T13 Scene / RuntimeLoop 补齐
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围: `docs/api/XCEngine/Scene/RuntimeLoop/**`
|
||||
- 主要源码依据: `engine/include/XCEngine/Scene/RuntimeLoop.h`、`engine/src/Scene/RuntimeLoop.cpp`、`editor/src/Core/PlaySessionController.h`、`tests/Scene/test_runtime_loop.cpp`
|
||||
- 当前缺口: 已建立 `RuntimeLoop` canonical 页面,并把 fixed step / pause / step-frame 语义并入 `Scene` 模块导航
|
||||
- 完成标准: 建立 `RuntimeLoop` 类型页,说明 fixed step / max delta / max fixed steps 这些设置的语义,以及它与 play mode、scene tick 生命周期的关系
|
||||
|
||||
## T14 Core / Asset 服务与索引尾项补齐
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围: `docs/api/XCEngine/Core/Asset/AssetImportService/**`、`docs/api/XCEngine/Core/Asset/ProjectAssetIndex/**`、必要时补充 `docs/api/XCEngine/Core/Asset/Asset.md`
|
||||
- 主要源码依据: `engine/include/XCEngine/Core/Asset/AssetImportService.h`、`engine/src/Core/Asset/AssetImportService.cpp`、`engine/include/XCEngine/Core/Asset/ProjectAssetIndex.h`、`engine/src/Core/Asset/ProjectAssetIndex.cpp`、`tests/core/Asset/test_resource_manager.cpp`
|
||||
- 当前缺口: 已补齐 `AssetImportService`、`ProjectAssetIndex` 两个 canonical 页面,并把它们补入 `Core/Asset` 模块总览
|
||||
- 完成标准: 建立两个类型页,写清楚 `AssetDatabase -> AssetImportService -> ProjectAssetIndex -> ResourceManager` 这条项目资产查询链路
|
||||
|
||||
## 二次审核结论(2026-04-02 23:31:03)
|
||||
|
||||
- 本轮全量结构审计已执行: `python docs/api/_tools/audit_api_docs.py`
|
||||
- 当前结构性问题为 `0`: 无失效 `.md` 链接、无非 `.md` 相对链接、无旧模板页面、无扁平 header 页面、无缺失目录总览页
|
||||
- 当前剩余覆盖缺口: `0` 个 public headers 未覆盖
|
||||
- 审计口径说明:
|
||||
- 当前 `docs/api/_meta/rebuild-status.md` 的覆盖口径仍是 `engine/include/XCEngine` 的 public headers。
|
||||
- `Editor` 下基于 `editor/src/**` 的源文件页、方法页颗粒度,以及说明性内容是否跟随源码重构同步,仍需要人工复核。
|
||||
- 抽样确认出的实际遗留问题:
|
||||
- `Editor/Application` 目录当前只有 `Application.md`,`ReloadScriptingRuntime()`、`RebuildScriptingAssemblies()`、`GetScriptRuntimeStatus()` 只在总览页有概述,缺少按商业级 API 文档颗粒度拆出的独立方法页。
|
||||
- `Editor/panels/SceneViewPanel` 目录当前只有 `SceneViewPanel.md`,尚未把 pivot / center、global / local、scene icon 命中优先级、transient overlay 注入链路拆开讲透。
|
||||
|
||||
## T15 Components / MeshRendererComponent 内容同步
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P0`
|
||||
- 写入范围: `docs/api/XCEngine/Components/MeshRendererComponent/**`、必要时 `docs/api/XCEngine/Components/Components.md`
|
||||
- 主要源码依据: `engine/include/XCEngine/Components/MeshRendererComponent.h`、`engine/src/Components/MeshRendererComponent.cpp`、`tests/Components/test_mesh_render_components.cpp`
|
||||
- 当前缺口: 已核对 `MeshRendererComponent.md`、`Serialize.md`、`Deserialize.md`、`GetMaterial.md`、`GetMaterialHandle.md`、`SetMaterialPath.md` 与 `Components.md`;文档已覆盖 `materialPaths + materialRefs` 双轨序列化、deferred async material load 与首次访问触发加载的当前行为
|
||||
- 完成标准: 重写 `MeshRendererComponent.md`、`Serialize.md`、`Deserialize.md`、`GetMaterial.md`、`GetMaterialHandle.md`、`SetMaterialPath.md` 等核心页面,写清楚 deferred load、asset ref 回填与测试覆盖
|
||||
|
||||
## T16 Scripting / ScriptEngine 固定步长配置补齐
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P0`
|
||||
- 写入范围: `docs/api/XCEngine/Scripting/ScriptEngine/**`、必要时 `docs/api/XCEngine/Scripting/Scripting.md`、`docs/api/_guides/Scripting/**`
|
||||
- 主要源码依据: `engine/include/XCEngine/Scripting/ScriptEngine.h`、`engine/src/Scripting/ScriptEngine.cpp`、`tests/scripting/test_script_engine.cpp`
|
||||
- 当前缺口: 已补齐 `SetRuntimeFixedDeltaTime()`、`GetRuntimeFixedDeltaTime()`、`DefaultFixedDeltaTime` 页面,并把 fixed delta 配置、运行时启停复位语义与 `OnFixedUpdate()` 的关系补入 `ScriptEngine` 与 `Scripting` 总览
|
||||
- 完成标准: 补齐固定步长相关页面,并写清楚它与 `OnFixedUpdate()`、运行时启动/停止、脚本类重绑定之间的关系
|
||||
|
||||
## T17 Editor / Application 脚本运行时方法页补齐
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围: `docs/api/XCEngine/Editor/Application/**`、必要时 `docs/api/XCEngine/Editor/Scripting/**`
|
||||
- 主要源码依据: `editor/src/Application.h`、`editor/src/Application.cpp`、`editor/src/Scripting/EditorScriptAssemblyBuilder.h`、`editor/src/Scripting/EditorScriptRuntimeStatus.h`、`tests/Editor/test_editor_script_assembly_builder.cpp`
|
||||
- 当前缺口: 已补齐 `ReloadScriptingRuntime()`、`RebuildScriptingAssemblies()`、`GetScriptRuntimeStatus()` 独立页面,并补入“程序集缺失时如何降级到不可用状态”的明确说明
|
||||
- 完成标准: 为上述方法补齐独立页面,写清楚构建成功/失败路径、Mono 后端缺失时的回退、状态快照如何供 Inspector/脚本 UI 消费
|
||||
|
||||
## T18 Editor / SceneViewPanel 交互语义深化
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围: `docs/api/XCEngine/Editor/panels/SceneViewPanel/**`、必要时 `docs/api/XCEngine/Editor/Viewport/**`、`docs/api/_guides/Editor/**`
|
||||
- 主要源码依据: `editor/src/panels/SceneViewPanel.h`、`editor/src/panels/SceneViewPanel.cpp`、`editor/src/Viewport/SceneViewportOverlayHandleBuilder.h`、`editor/src/Viewport/SceneViewportOverlayHitTester.h`、`editor/src/Viewport/IViewportHostService.h`
|
||||
- 当前缺口: 已重写 `SceneViewPanel.md`,并新增 `SceneView Interaction And Gizmo Model` guide;文档已明确 pivot / center 的计算依据、global / local 轴向语义、scene icon 与 gizmo 的命中优先级,以及 cached / interaction / transient 三层 overlay 数据流
|
||||
- 完成标准: 把 Scene View 交互模型补成商业级说明,尤其是 selection pivot、transform space、overlay hit-test 与 scene icon 选择这几条链路
|
||||
|
||||
## T19 审计工具口径扩展
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P2`
|
||||
- 写入范围: `docs/api/_tools/audit_api_docs.py`、必要时 `docs/api/_meta/rebuild-status.md`
|
||||
- 主要源码依据: 当前审计脚本口径与 `docs/api/XCEngine/Editor/**` 的实际页面分布
|
||||
- 当前缺口: 自动审计目前能确认 public headers 与链接结构,但无法自动暴露 `Editor` 源文件页是否缺少方法页,也无法报告像 `Application`、`SceneViewPanel` 这种“只有总览页”的高风险目录
|
||||
- 完成标准: 让审计结果至少能额外报告 source-file 页覆盖概况或方法页缺口统计,降低后续人工抽样成本
|
||||
|
||||
## T20 二次内容收口与最终复核
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P2`
|
||||
- 写入范围: `docs/api/_meta/rebuild-status.md`、`docs/plan/API文档并行更新任务池_2026-04-02.md`、必要时受影响的模块总览页
|
||||
- 主要源码依据: `T15-T19` 的完成结果
|
||||
- 当前缺口: 已在 `2026-04-03 00:16:11` 重新执行 `python docs/api/_tools/audit_api_docs.py` 并回写 `rebuild-status.md`;结构性问题继续保持 `0`,`246/246` public headers 与 `120/120` Editor source headers 继续全量覆盖;审计中的 `Editor 高风险单页目录数: 19` 属于启发式抽样信号,不等同于仍有 19 处缺页
|
||||
- 完成标准: 在 `T15-T19` 完成后重新执行结构审计与人工抽样复核,把新的结论写回进度表
|
||||
|
||||
## 收口结论(2026-04-03 00:16:11)
|
||||
|
||||
- 本轮收口审计已执行: `python docs/api/_tools/audit_api_docs.py`
|
||||
- 当前结构性问题继续为 `0`:
|
||||
- 无失效 `.md` 链接
|
||||
- 无非 `.md` 相对链接
|
||||
- 无旧模板页面
|
||||
- 无扁平 header 页面
|
||||
- 无失效 header / source ref
|
||||
- 当前覆盖状态:
|
||||
- public headers `246/246`
|
||||
- Editor source headers `120/120`
|
||||
- 本轮内容级收口结果:
|
||||
- `MeshRendererComponent` 内容同步已完成
|
||||
- `ScriptEngine` 固定步长配置页已补齐
|
||||
- `Application` 脚本运行时方法页已补齐
|
||||
- `SceneViewPanel` 交互语义与 guide 已补齐
|
||||
- 审计提示解释:
|
||||
- `Editor 高风险单页目录数: 19` 是新增启发式报告,用于提示“目录只有单页但实现较大,建议继续人工抽样”
|
||||
- 它不是“当前仍缺 19 个 canonical 页面”的等价表达
|
||||
|
||||
## 三次审核结论(2026-04-03 00:24:08)
|
||||
|
||||
- 已重新执行 `python docs/api/_tools/audit_api_docs.py`
|
||||
- 当前结构性问题仍为 `0`
|
||||
- public headers `246/246`
|
||||
- Editor source headers `120/120`
|
||||
- 失效 `.md` 链接 `0`
|
||||
- 无效 header / source ref `0`
|
||||
- 本轮新增问题不在“结构覆盖”,而在“内容与源码同步”
|
||||
- 经过 `git diff`、源码抽样与文档抽样,当前确认的内容级缺口有:
|
||||
- `Input/InputManager` 文档已失准
|
||||
- `Input.md` / `InputManager.md` 仍把 `GetAxisRaw()` 解释成“按下边沿”语义
|
||||
- `GetButtonUp()` 的未注册按钮返回值说明仍是旧行为
|
||||
- 缺少 `IsKeyReleased.md`、`IsMouseButtonReleased.md`、`IsAnyKeyDown.md`、`IsAnyKeyPressed.md`
|
||||
- `Editor` 的 Game View 输入桥接链路没有写完整
|
||||
- [GameViewPanel](../api/XCEngine/Editor/panels/GameViewPanel/GameViewPanel.md) 还在按“薄视口壳层”描述
|
||||
- [EditorEvents](../api/XCEngine/Editor/Core/EditorEvents/EditorEvents.md) 还没纳入 `GameViewInputFrameEvent`
|
||||
- `GameViewPanel -> EventBus -> PlaySessionController -> InputManager` 这条运行时输入链路没有统一说明
|
||||
- `Editor` 项目工作流文档落后于当前功能
|
||||
- [MainMenuActionRouter](../api/XCEngine/Editor/Actions/MainMenuActionRouter/MainMenuActionRouter.md) 未写 `Scripts` 菜单与“迁移场景资产引用”
|
||||
- [ProjectCommands](../api/XCEngine/Editor/Commands/ProjectCommands/ProjectCommands.md) 未写 `MigrateSceneAssetReferences`
|
||||
- [IProjectManager](../api/XCEngine/Editor/Core/IProjectManager/IProjectManager.md) / [ProjectManager](../api/XCEngine/Editor/Managers/ProjectManager/ProjectManager.md) 未写迁移报告结构与批量重写场景流程
|
||||
- `Core/Asset` 局部页存在陈旧说明
|
||||
- [AssetDatabase](../api/XCEngine/Core/Asset/AssetDatabase/AssetDatabase.md) 仍提到已不存在的 `ResourceManager::m_ioMutex`
|
||||
- 新增的 artifact 依赖快照、`BuildLookupSnapshot()` 热路径、`AssetImportService + ProjectAssetIndex` 分层关系需要再校对一次叙述是否完全一致
|
||||
- `Scripting` 虽已补齐 fixed delta 页面,但托管输入桥接与类发现/类切换行为还没有在模块页和 guide 层讲透
|
||||
- 另外有一个文档组织问题需要收口:
|
||||
- `docs/api/_guides/Editor/Scene-View-Interaction-Model.md`
|
||||
- `docs/api/_guides/Editor/SceneView-Interaction-And-Gizmo-Model.md`
|
||||
- 这两篇主题重叠,当前链接入口分叉,需统一 canonical guide
|
||||
- `Editor 高风险单页目录数: 19` 仍保留为抽样队列,不等同于这 19 处都已确认失准
|
||||
|
||||
## T21 Input / InputManager 内容校准与方法补页
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P0`
|
||||
- 写入范围: `docs/api/XCEngine/Input/**`、必要时 `docs/api/_guides/Input/**`
|
||||
- 主要源码依据: `engine/include/XCEngine/Input/InputManager.h`、`engine/src/Input/InputManager.cpp`、`tests/Input/test_input_manager.cpp`
|
||||
- 当前缺口:
|
||||
- 已重写 `Input.md`、`InputManager.md` 与 `Input-Flow-and-Frame-Semantics.md`
|
||||
- 已补齐 `IsKeyReleased.md`、`IsMouseButtonReleased.md`、`IsAnyKeyDown.md`、`IsAnyKeyPressed.md`
|
||||
- 文档已按当前源码校正 `GetAxisRaw()`、`GetButtonUp()`、`ProcessKeyUp()`、`ProcessMouseButton()` 与 `Update()` 的帧语义
|
||||
- 已进一步补充 `IsKeyPressed()` / `GetButtonDown()` / `IsAnyKeyPressed()` 的 `repeat` 语义,以及 `IsKeyUp()` / `IsMouseButtonUp()` 和释放边沿接口的区别
|
||||
- 完成标准: 重写模块页与类型页,补齐 4 个方法页,并把键鼠释放态、any-key 语义、默认映射和测试覆盖按当前源码写清楚
|
||||
|
||||
## T22 Editor / Game View 输入桥接链路补写
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P0`
|
||||
- 写入范围: `docs/api/XCEngine/Editor/panels/GameViewPanel/**`、`docs/api/XCEngine/Editor/Core/EditorEvents/**`、`docs/api/XCEngine/Editor/Core/PlaySessionController/**`、必要时 `docs/api/_guides/Editor/**`
|
||||
- 主要源码依据: `editor/src/panels/GameViewPanel.cpp`、`editor/src/Core/EditorEvents.h`、`editor/src/Core/PlaySessionController.h`、`editor/src/Core/PlaySessionController.cpp`、`tests/editor/test_play_session_controller.cpp`
|
||||
- 当前缺口:
|
||||
- 已重写 `GameViewPanel.md`,补入 ImGui 键鼠采集、逐帧发布 `GameViewInputFrameEvent` 与空事件释放语义
|
||||
- `EditorEvents.md` 已纳入 `GameViewInputFrameEvent`
|
||||
- `PlaySessionController.md` 已明确“只有运行态 `Update()` 才会把 Game View 输入桥接到 `InputManager`”及 `hovered/focused` 门控规则
|
||||
- 已补齐 `GameViewPanel/Constructor.md` 与 `GameViewPanel/Render.md`
|
||||
- 已新增 `docs/api/_guides/Editor/Game-View-Runtime-Input-Bridge.md`,把 `GameViewPanel -> EventBus -> PlaySessionController -> InputManager` 收口成单条连续说明
|
||||
- 完成标准: 把 `GameViewPanel -> EventBus -> PlaySessionController -> InputManager` 这条桥接链路写成一组可追踪的 API 文档,明确 `hovered/focused`、键鼠状态快照与帧边界
|
||||
|
||||
## T23 Editor / 项目工作流与脚本菜单同步
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P0`
|
||||
- 写入范围: `docs/api/XCEngine/Editor/Actions/MainMenuActionRouter/**`、`docs/api/XCEngine/Editor/Actions/EditorActions/**`、`docs/api/XCEngine/Editor/Actions/ProjectActionRouter/**`、`docs/api/XCEngine/Editor/Commands/ProjectCommands/**`、`docs/api/XCEngine/Editor/Core/IProjectManager/**`、`docs/api/XCEngine/Editor/Managers/ProjectManager/**`、必要时 `docs/api/XCEngine/Editor/panels/ProjectPanel/**`
|
||||
- 主要源码依据: `editor/src/Actions/MainMenuActionRouter.h`、`editor/src/Commands/ProjectCommands.h`、`editor/src/Core/IProjectManager.h`、`editor/src/Managers/ProjectManager.h`、`editor/src/Managers/ProjectManager.cpp`、`tests/editor/test_action_routing.cpp`
|
||||
- 当前缺口:
|
||||
- 已重写 `MainMenuActionRouter.md`,补入 `Scripts` 菜单、`Migrate Scene AssetRefs` 文件菜单入口,以及菜单到 `ProjectCommands` / `EventBus` 的下游链路
|
||||
- 已重写 `ProjectCommands.md`,补入 `RebuildScriptAssemblies`、`MigrateSceneAssetReferences`、`SwitchProject` 与 `SaveProject` 的真实 guard 和执行流程
|
||||
- 已重写 `IProjectManager.md` / `ProjectManager.md`,补入 `SceneAssetReferenceMigrationReport` 结构、`Assets/**/*.xc` 批量迁移流程、`ResourceManager::ScopedDeferredSceneLoad` 与日志/刷新语义
|
||||
- 已进一步补充“菜单层不消费返回值”“脚本重建产物不在 `ProjectPanel` 视图内”“`.meta` sidecar 跟随规则”“迁移报告只给汇总计数”的边界说明
|
||||
- 已校对 `ProjectPanel.md` 与 `EditorActions.md`,明确面板只消费资源级命令,而项目保存 / 脚本重建 / 场景迁移入口位于主菜单
|
||||
- 完成标准: 把项目工作流文档升级到“菜单入口 -> command -> manager -> 场景重写报告”的完整链路,并校对 `ProjectPanel` 对这些命令的消费关系
|
||||
|
||||
## T24 Core / AssetDatabase 与项目资产快照链路复核
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围: `docs/api/XCEngine/Core/Asset/AssetDatabase/**`、`docs/api/XCEngine/Core/Asset/ResourceManager/**`、必要时 `docs/api/XCEngine/Core/Asset/Asset.md`
|
||||
- 主要源码依据: `engine/include/XCEngine/Core/Asset/AssetDatabase.h`、`engine/src/Core/Asset/AssetDatabase.cpp`、`engine/include/XCEngine/Core/Asset/ResourceManager.h`、`engine/src/Core/Asset/ResourceManager.cpp`、`engine/src/Resources/Material/MaterialLoader.cpp`、`tests/core/Asset/test_resource_manager.cpp`
|
||||
- 当前缺口:
|
||||
- 已移除 `AssetDatabase.md` 中陈旧的 `m_ioMutex` 叙述,并改成当前 `AssetImportService::recursive_mutex` 的真实封装关系
|
||||
- 已重写 `BuildLookupSnapshot()`、`TryGetAssetRef()`、`EnsureArtifact()` 和 `Asset.md` 中关于 snapshot 消费链路、cache miss 自刷新和 artifact 导入边界的说明
|
||||
- 已补入材质纹理绑定依赖、`.obj -> .mtl -> texture` 依赖快照,以及 `BuildLookupSnapshot()` 只导出主资产 path/GUID 表而不导出 artifact 路径的语义
|
||||
- 已继续重写 `ResourceManager` 下残留的通用占位方法页,补齐 `Get()`、`AddRef()/Release()`、`Find()/Exists()`、`Unload*()`、`ResolvePath()`、`LoadGroup()` 等真实行为与当前限制
|
||||
- 完成标准: 把 `AssetDatabase -> ResourceManager` 的当前链路与依赖快照行为写实,并消除与 `AssetImportService` / `ProjectAssetIndex` 相关的陈旧描述
|
||||
|
||||
## T25 Scripting / 托管输入桥接与类发现链路补强
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围: `docs/api/XCEngine/Scripting/**`、必要时 `docs/api/_guides/Scripting/**`
|
||||
- 主要源码依据: `engine/include/XCEngine/Scripting/IScriptRuntime.h`、`engine/include/XCEngine/Scripting/Mono/MonoScriptRuntime.h`、`engine/include/XCEngine/Scripting/NullScriptRuntime.h`、`engine/include/XCEngine/Scripting/ScriptComponent.h`、`engine/include/XCEngine/Scripting/ScriptEngine.h`、对应 `.cpp`、`managed/XCEngine.ScriptCore/Input.cs`、`managed/XCEngine.ScriptCore/Time.cs`、`managed/XCEngine.ScriptCore/KeyCode.cs`、`tests/scripting/test_mono_script_runtime.cpp`、`tests/scripting/test_script_engine.cpp`
|
||||
- 当前缺口:
|
||||
- 已重写 `Scripting.md`、`ScriptEngine.md` 与 `MonoScriptRuntime.md`,把托管 `Input` / `Time` internal call、`Time.fixedDeltaTime` 配置来源,以及 `InputManager` 消费边界收口到同一条说明链。
|
||||
- 已补强 `TryGetAvailableScriptClasses()`、`SetScriptClass()`、`ClearScriptClass()` 与 `IScriptRuntime` 契约页,明确排序、按程序集过滤、项目程序集发现和类切换重建语义。
|
||||
- 已重写两篇 `Scripting` guide,把 `project/Assets/**/*.cs -> GameScripts.dll -> ScriptClassDescriptor -> ScriptComponent::SetScriptClass()` 以及运行时切类后的实例销毁/重建流程串成连续入口。
|
||||
- 完成标准: 在不扩散成两套文档体系的前提下,把原生 `ScriptEngine`、Mono internal call、项目脚本类发现与类切换重建写成一组连续说明
|
||||
|
||||
## 四次审核结论(2026-04-03 11:39:21)
|
||||
|
||||
- 已重新执行 `python docs/api/_tools/audit_api_docs.py`
|
||||
- 当前结构性问题继续为 `0`
|
||||
- public headers `246/246`
|
||||
- Editor source headers `121/121`
|
||||
- 失效 `.md` 链接 `0`
|
||||
- 无效 header / source ref `0`
|
||||
- 本轮新增与收口结果:
|
||||
- `EditorConsoleSink` 已从单页目录重构为“类型页 + record 页 + 方法页”
|
||||
- `ConsoleFilterState` 已按真实字段与别名关系重写
|
||||
- 工作树新增的 `editor/src/Viewport/SceneViewportTransformGizmoFrameBuilder.h` 已补入 canonical 文档树
|
||||
- 审计抽样结果:
|
||||
- `Editor 高风险单页目录数` 已从 `14` 下降到 `10`
|
||||
- `ConsolePanel` 与 `EditorConsoleSink` 已移出高风险单页目录清单
|
||||
- 当前剩余抽样池见 `T26`
|
||||
|
||||
## 五次审核结论(2026-04-03 11:56:30)
|
||||
|
||||
- 已重新执行 `python docs/api/_tools/audit_api_docs.py`
|
||||
- 当前结构性问题继续为 `0`
|
||||
- public headers `246/246`
|
||||
- Editor source headers `121/121`
|
||||
- 失效 `.md` 链接 `0`
|
||||
- 无效 header / source ref `0`
|
||||
- 本轮新增与收口结果:
|
||||
- 已补齐 `GameViewPanel/Constructor.md` 与 `GameViewPanel/Render.md`
|
||||
- 已新增 `Game View Runtime Input Bridge` guide,并把 `GameViewPanel`、`EditorEvents`、`PlaySessionController` 和 `Editor-Architecture-And-Workflow` 串成统一入口
|
||||
- 审计抽样结果:
|
||||
- `Editor 高风险单页目录数` 已从 `10` 下降到 `5`
|
||||
- 当前剩余抽样池已进一步收缩到 `Viewport gizmo + SceneManager`
|
||||
|
||||
## 六次审核结论(2026-04-03 12:00:34)
|
||||
|
||||
- 已重新执行 `python docs/api/_tools/audit_api_docs.py`
|
||||
- 当前结构性问题继续为 `0`
|
||||
- public headers `246/246`
|
||||
- Editor source headers `121/121`
|
||||
- 失效 `.md` 链接 `0`
|
||||
- 无效 header / source ref `0`
|
||||
- 本轮新增与收口结果:
|
||||
- 已重写 `SceneManager.md`,并补齐实体编辑、场景文件生命周期、快照恢复相关方法页
|
||||
- `ISceneManager.md` 已按当前实现职责更新接口说明
|
||||
- 审计抽样结果:
|
||||
- `Editor 高风险单页目录数` 已从 `5` 下降到 `0`
|
||||
- `T26` 对应的启发式抽样队列已全部清空
|
||||
|
||||
## T26 Editor / 高风险单页目录抽样复核队列
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P2`
|
||||
- 写入范围: `docs/api/XCEngine/Editor/Managers/SceneManager/**`、`docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/**`、`docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/**`、`docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/**`、`docs/api/XCEngine/Editor/Viewport/SceneViewportOrientationGizmo/**`
|
||||
- 主要源码依据: `docs/api/_meta/rebuild-status.md` 中的高风险单页目录清单及对应 `editor/src/**`
|
||||
- 当前缺口:
|
||||
- `2026-04-03 12:00:34` 这轮复核后,审计中的 `Editor 高风险单页目录数` 已下降到 `0`。
|
||||
- 启发式抽样队列已收口完成,当前不再保留剩余目录。
|
||||
- 完成标准: 至少抽样复核一遍源码与现有页面;若发现失准则直接重写,若确认足够则在任务认领记录里注明“已复核”
|
||||
|
||||
## T27 Editor / Scene View 交互 guide 去重与入口收口
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P2`
|
||||
- 写入范围: `docs/api/_guides/Editor/Scene-View-Interaction-Model.md`、`docs/api/_guides/Editor/SceneView-Interaction-And-Gizmo-Model.md`、以及所有引用这两篇 guide 的 API 页面
|
||||
- 主要依据: 当前 guide 内容本身与 `SceneViewPanel` / `IViewportHostService` / `ViewportHostService` / `Viewport.md` 的交叉链接分布
|
||||
- 当前缺口:
|
||||
- 已确认 `SceneView-Interaction-And-Gizmo-Model.md` 作为唯一 canonical guide;旧 `Scene-View-Interaction-Model.md` 保留为兼容入口页,只负责跳转说明。
|
||||
- 已把残留的业务页引用统一切到 canonical guide,当前仓库里已无 API 页面继续把旧 guide 当主入口。
|
||||
- 完成标准: 统一保留一个 canonical guide 或明确拆分两篇职责,并把全部入口链接收口到一致命名
|
||||
|
||||
## 四次审核结论(2026-04-03 11:44:52)
|
||||
|
||||
- 已重新执行 `python docs/api/_tools/audit_api_docs.py`
|
||||
- 当前结构性问题仍为 `0`
|
||||
- public headers `246/246`
|
||||
- Editor source headers `121/121`
|
||||
- 失效 `.md` 链接 `0`
|
||||
- 无效 header / source ref `0`
|
||||
- 本轮新增收口结果:
|
||||
- `T21 Input / InputManager` 已补充 `Pressed` / `Up` / `Released` / `repeat` 的内容级语义说明
|
||||
- `Input-Flow-and-Frame-Semantics.md` 已提升为面向接入与设计理解的 canonical guide
|
||||
- 当前自动审计提示:
|
||||
- `Editor high-risk single-page dirs: 10`
|
||||
- 这仍是人工抽样优先队列,不等同于已经确认存在 10 处失准
|
||||
- 后续并行优先级建议保持为:
|
||||
- `T23`
|
||||
- `T24` / `T25`
|
||||
- `T26` / `T27`
|
||||
|
||||
## 五次审核结论(2026-04-03 11:53:48)
|
||||
|
||||
- 已重新执行 `python docs/api/_tools/audit_api_docs.py`
|
||||
- 当前结构性问题仍为 `0`
|
||||
- public headers `246/246`
|
||||
- Editor source headers `121/121`
|
||||
- 失效 `.md` 链接 `0`
|
||||
- 无效 header / source ref `0`
|
||||
- 本轮新增收口结果:
|
||||
- `T23 Editor / 项目工作流与脚本菜单同步` 已继续补强内容级说明
|
||||
- 已明确主菜单层只负责触发项目维护动作,不消费 `RebuildScriptAssemblies` / `MigrateSceneAssetReferences` 的返回结果
|
||||
- 已明确 `ProjectPanel` 只投影 `<Project>/Assets`,因此脚本重建成功后不保证出现可见树变化
|
||||
- 已明确 `ProjectManager` 的 `.meta` sidecar 跟随语义、resource root 临时切换 / 恢复,以及迁移报告只提供汇总计数
|
||||
- 当前自动审计提示:
|
||||
- `Editor high-risk single-page dirs: 6`
|
||||
- 仍属于人工抽样队列,不等同于已经确认失准
|
||||
- 后续并行优先级建议调整为:
|
||||
- `T24` / `T25`
|
||||
- `T26`
|
||||
- `T27`
|
||||
|
||||
## 六次审核结论(2026-04-03 11:57:51)
|
||||
|
||||
- 已重新执行 `python docs/api/_tools/audit_api_docs.py`
|
||||
- 当前结构性问题仍为 `0`
|
||||
- public headers `246/246`
|
||||
- Editor source headers `121/121`
|
||||
- 失效 `.md` 链接 `0`
|
||||
- 无效 header / source ref `0`
|
||||
- 本轮新增收口结果:
|
||||
- `T24 Core / AssetDatabase 与项目资产快照链路复核` 已完成
|
||||
- 已修正 `AssetDatabase` 的锁模型、`BuildLookupSnapshot()` 的真实消费链路、`TryGetAssetRef()` 与 `EnsureArtifact()` 的职责边界
|
||||
- 已把材质贴图依赖与模型依赖快照的真实采集方式补入文档
|
||||
- 当前自动审计提示:
|
||||
- `Editor high-risk single-page dirs: 4`
|
||||
- 仍属于人工抽样队列,不等同于已经确认失准
|
||||
|
||||
## 七次审核结论(2026-04-03 12:16:18)
|
||||
|
||||
- 已重新执行 `python docs/api/_tools/audit_api_docs.py`
|
||||
- 当前结构性问题仍为 `0`
|
||||
- public headers `246/246`
|
||||
- Editor source headers `121/121`
|
||||
- 失效 `.md` 链接 `0`
|
||||
- 无效 header / source ref `0`
|
||||
- 本轮新增收口结果:
|
||||
- `T24` 已继续补齐 `ResourceManager` 目录下残留的占位方法页
|
||||
- `ResolvePath()`、`Exists()/Find()`、`Unload*()`、`LoadGroup()` 等方法页已改成按源码解释当前行为与限制
|
||||
- 当前自动审计提示:
|
||||
- `Editor high-risk single-page dirs: 0`
|
||||
- 当前追踪表中的内容级收口任务已全部落地
|
||||
- 后续并行优先级建议调整为:
|
||||
- `T25`
|
||||
- `T26`
|
||||
- `T27`
|
||||
|
||||
## 八次审核结论(2026-04-03 12:21:03)
|
||||
|
||||
- 已重新执行 `python docs/api/_tools/audit_api_docs.py`
|
||||
- 当前结构性问题仍为 `0`
|
||||
- public headers `246/246`
|
||||
- Editor source headers `121/121`
|
||||
- 失效 `.md` 链接 `0`
|
||||
- 无效 header / source ref `0`
|
||||
- 本轮新增收口结果:
|
||||
- `T25 Scripting / 托管输入桥接与类发现链路补强` 已完成最后一轮内容级重写
|
||||
- 已把托管 `Input` / `Time` internal call、`Time.fixedDeltaTime` 配置来源、`TryGetAvailableScriptClasses()` 的排序与按程序集过滤语义、`SetScriptClass()` / `ClearScriptClass()` 的运行时重建链路补入模块页、类型页与 guide
|
||||
- `MonoScriptRuntime` 与两篇 `Scripting` guide 已明确项目脚本程序集入口、类发现约束、字段默认值与本地覆盖同步的设计边界
|
||||
- 当前自动审计提示:
|
||||
- `Editor high-risk single-page dirs: 0`
|
||||
- 当前任务池中的内容级收口任务已全部完成
|
||||
- 后续并行优先级建议调整为:
|
||||
- 跟踪后续源码新增 API
|
||||
- 发现新的内容失准后再按模块开新任务
|
||||
- 保持 `docs/api/_meta/rebuild-status.md` 的周期性审计回写
|
||||
|
||||
## T28 Rendering / BuiltinForwardPipeline 资源契约与描述符布局同步
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围: `docs/api/XCEngine/Rendering/Pipelines/BuiltinForwardPipeline/**`、必要时 `docs/api/XCEngine/Rendering/Pipelines/Pipelines.md`、`docs/api/XCEngine/Rendering/Rendering.md`
|
||||
- 主要源码依据: `engine/include/XCEngine/Rendering/Pipelines/BuiltinForwardPipeline.h`、`engine/src/Rendering/Pipelines/BuiltinForwardPipeline.cpp`、`tests/Rendering/unit/test_builtin_forward_pipeline.cpp`
|
||||
- 当前缺口:
|
||||
- 已重写 `BuiltinForwardPipeline.md`、`Initialize.md`、`Render.md`、`Shutdown.md`,把 `RenderPassSequence`、`PassResourceLayout`、动态/静态 descriptor set 分流与 legacy binding 回退补齐到当前实现。
|
||||
- 已新增 `Constructor.md` 与 `BuildInputLayout.md`,补齐公开构造入口和 `StaticMeshVertex` 输入布局契约。
|
||||
- 已新增 `BuiltinForwardPipelineAsset/BuiltinForwardPipelineAsset.md`、`BuiltinForwardPipelineAsset/CreatePipeline.md`,补清默认 pipeline asset 工厂与 runtime pipeline 的衔接关系。
|
||||
- 已更新 `Pipelines.md`、`RenderPipeline.md`、`RenderPipelineAsset.md`、`RenderPipelineAsset/CreatePipeline.md`、`Rendering.md` 与渲染 guide,使 `ForwardLit` 资源契约、`visibleItems` 和默认 pipeline asset 链路保持一致。
|
||||
- 完成标准: 把 `BuiltinForwardPipeline` 类型页与核心方法页重写到当前实现,明确 shader pass 资源契约、descriptor set 生命周期、legacy 回退语义和当前限制
|
||||
|
||||
## T29 Rendering / SceneRenderer 与 RenderSceneExtractor 口径复核
|
||||
|
||||
- 状态: `DONE`
|
||||
- 认领人: `Codex`
|
||||
- 优先级: `P1`
|
||||
- 写入范围: `docs/api/XCEngine/Rendering/SceneRenderer/**`、`docs/api/XCEngine/Rendering/RenderSceneExtractor/**`、`docs/api/XCEngine/Rendering/VisibleRenderObject/**`
|
||||
- 主要源码依据: `engine/include/XCEngine/Rendering/SceneRenderer.h`、`engine/src/Rendering/SceneRenderer.cpp`、`engine/include/XCEngine/Rendering/RenderSceneExtractor.h`、`engine/src/Rendering/RenderSceneExtractor.cpp`、`tests/Rendering/unit/test_camera_scene_renderer.cpp`、`tests/Rendering/unit/test_scene_render_request_planner.cpp`
|
||||
- 当前缺口:
|
||||
- 已重写 `SceneRenderer.md`、`Constructor.md`、`Destructor.md`、`SetPipeline.md`、`GetPipeline.md`、`Render.md`,纠正“`SceneRenderer` 直接做 scene extraction / 直接创建 `BuiltinForwardPipeline`”的旧口径。
|
||||
- 已新增 `BuildRenderRequests.md`、`SetPipelineAsset.md`、`GetPipelineAsset.md`,补齐 `SceneRenderer` 当前公开方法页。
|
||||
- 已重写 `RenderSceneExtractor.md` 与 `Extract.md`,并新增 `ExtractForCamera.md`、`SelectCamera.md`,把 `visibleItems`、相机选择、光照提取与排序规则同步到当前实现。
|
||||
- 已重写 `VisibleRenderObject.md`,把它明确为 `VisibleRenderItem` 的兼容别名入口,并补齐 `material / section / renderQueue / cameraDistanceSq` 等当前字段。
|
||||
- 完成标准: 把 `SceneRenderer` 更新为“请求规划 + 转发到 `CameraRenderer`”的真实职责模型;把 `RenderSceneExtractor` 更新为 `visibleItems` 与当前排序 / 相机选择语义
|
||||
|
||||
## 九次审核结论(2026-04-03 13:30:05)
|
||||
|
||||
- 已重新执行 `python docs/api/_tools/audit_api_docs.py`
|
||||
- 当前结构性问题仍为 `0`
|
||||
- public headers `246/246`
|
||||
- Editor source headers `121/121`
|
||||
- 失效 `.md` 链接 `0`
|
||||
- 无效 header / source ref `0`
|
||||
- 本轮新增收口结果:
|
||||
- `T28 Rendering / BuiltinForwardPipeline 资源契约与描述符布局同步` 已完成
|
||||
- 已补齐 `BuiltinForwardPipeline/Constructor.md`、`BuiltinForwardPipeline/BuildInputLayout.md` 与 `BuiltinForwardPipelineAsset` 类目录
|
||||
- 已把默认 `BuiltinForwardPipelineAsset -> BuiltinForwardPipeline -> CameraRenderer` 链路补入 `Pipelines`、`RenderPipelineAsset`、`RenderPipeline`、`Rendering` 与 rendering guide
|
||||
- 当前自动审计提示:
|
||||
- `Editor high-risk single-page dirs: 0`
|
||||
- 当前 canonical API 树与 public headers / Editor source headers 仍保持全量覆盖
|
||||
|
||||
## 备注
|
||||
|
||||
- `T01-T20` 当前已全部完成
|
||||
- `T21-T27` 当前也已全部完成
|
||||
- 下一阶段重点已经从“补历史缺页”切换为“跟踪源码新增行为并持续校正文档内容”
|
||||
758
docs/used/C#脚本模块的设计与实现_阶段一归档_2026-04-03.md
Normal file
758
docs/used/C#脚本模块的设计与实现_阶段一归档_2026-04-03.md
Normal file
@@ -0,0 +1,758 @@
|
||||
# C#脚本模块的设计与实现
|
||||
|
||||
日期:3.27
|
||||
|
||||
## 1. 背景
|
||||
|
||||
XCEngine 的整体方向是模仿传统 Unity 引擎架构,而不是 DOTS/ECS-first 路线。
|
||||
在这一目标下,脚本系统应当满足以下基本预期:
|
||||
|
||||
- 脚本语言使用 `C#`
|
||||
- 脚本以“挂载到 `GameObject` 上的组件”形式工作
|
||||
- 脚本与引擎核心解耦,支持独立编译和运行时加载
|
||||
- 脚本可以逐步扩展到 Inspector、场景序列化、Play/Simulate 工作流
|
||||
|
||||
当前 `editor` 仍处于基础阶段,因此脚本系统第一阶段不应依赖 editor 完整落地。
|
||||
第一阶段的目标应当收敛为:
|
||||
|
||||
- 先完成原生运行时与托管运行时之间的桥接
|
||||
- 先完成 `ScriptComponent + C# MonoBehaviour` 的基本执行链路
|
||||
- 先完成单元测试和最小场景级验证
|
||||
- 将 editor 集成需求单独列为 issue,后续补齐
|
||||
|
||||
---
|
||||
|
||||
## 2. 设计目标
|
||||
|
||||
### 2.1 总体目标
|
||||
|
||||
脚本系统应当提供一条接近 Unity 的开发路径:
|
||||
|
||||
1. 用户在独立的 C# 项目中编写脚本
|
||||
2. C# 脚本编译为程序集
|
||||
3. Engine Core 在运行时加载程序集
|
||||
4. `GameObject` 上挂载 `ScriptComponent`
|
||||
5. `ScriptComponent` 驱动一个对应的 C# `MonoBehaviour` 实例
|
||||
6. 脚本通过引擎暴露的 API 调用原生功能
|
||||
|
||||
### 2.2 第一阶段目标
|
||||
|
||||
第一阶段只覆盖以下内容:
|
||||
|
||||
- `engine` 内部的脚本运行时抽象
|
||||
- 第一套 C# 运行时实现
|
||||
- `ScriptComponent` 原生组件
|
||||
- `ScriptCore` 托管基础库
|
||||
- 最小可用的 `InternalCall` 绑定
|
||||
- 单元测试与最小运行时测试
|
||||
|
||||
### 2.3 第一阶段非目标
|
||||
|
||||
第一阶段明确不做以下内容:
|
||||
|
||||
- editor Inspector 脚本字段编辑
|
||||
- editor 中的脚本类选择器
|
||||
- editor 的 Play/Simulate 集成
|
||||
- 自动编译、文件监听、热重载
|
||||
- 调试器接入
|
||||
- 发布态 AOT / IL2CPP
|
||||
- 大而全的引擎 API 暴露
|
||||
|
||||
---
|
||||
|
||||
## 3. 三方对比结论
|
||||
|
||||
### 3.1 Unity
|
||||
|
||||
Unity 的典型脚本模型有几个关键特征:
|
||||
|
||||
- 用户脚本通常继承 `MonoBehaviour`
|
||||
- 一段脚本本质上就是一个组件实例
|
||||
- 脚本字段可序列化、可在 Inspector 中编辑
|
||||
- 生命周期完整,且与 `GameObject active` / `Component enabled` 语义一致
|
||||
- Play 模式运行的是运行时场景副本,而不是直接修改编辑场景
|
||||
|
||||
### 3.2 参考项目 Fermion
|
||||
|
||||
参考项目已经实现了一套 C# 脚本模块,优点主要在于:
|
||||
|
||||
- 已经证明了 `Mono embedding + InternalCall + C# 程序集加载` 这条路线可行
|
||||
- 已经具备脚本类发现、脚本实例创建、字段反射、运行时调用
|
||||
- 已经有托管侧 API 包装层和原生侧 `ScriptGlue`
|
||||
|
||||
但它的对象模型并不是 Unity 风格:
|
||||
|
||||
- 托管脚本类继承的是 `Entity`
|
||||
- 原生挂载结构是 `ScriptContainerComponent`
|
||||
- 更像“一个实体挂多个脚本类名”,而不是“每个脚本本身就是一个组件”
|
||||
- 生命周期目前主要聚焦 `OnCreate/OnUpdate`
|
||||
|
||||
结论:
|
||||
|
||||
- Fermion 适合借鉴运行时技术路线
|
||||
- Fermion 不适合作为最终 API 形态的直接模板
|
||||
|
||||
### 3.3 XCEngine 当前情况
|
||||
|
||||
XCEngine 当前已经具备以下基础:
|
||||
|
||||
- 已有 `GameObject + Component + Scene` 模型
|
||||
- `Component` 已定义 Unity 风格生命周期接口
|
||||
- `Scene` 和 `GameObject` 已有序列化入口
|
||||
- `ComponentFactoryRegistry` 已支持按类型名恢复组件
|
||||
|
||||
但当前也存在会直接影响脚本系统设计的现实约束:
|
||||
|
||||
- `Scene::Update/FixedUpdate/LateUpdate` 目前只遍历根对象
|
||||
- `GameObject::Update/FixedUpdate/LateUpdate` 目前不递归子对象
|
||||
- `Start` 的场景级一次性调度路径还未完整建立
|
||||
- `SetActive` 尚未真正驱动 `OnEnable/OnDisable`
|
||||
- editor 的 Play/Simulate 工作流仍未落地
|
||||
- `GameObject UUID` 当前未进入场景序列化主路径
|
||||
|
||||
结论:
|
||||
|
||||
- XCEngine 适合走 Unity 风格脚本模型
|
||||
- 但脚本系统第一阶段必须连同一部分运行时地基一起建设
|
||||
|
||||
---
|
||||
|
||||
## 4. 总体设计结论
|
||||
|
||||
XCEngine 的 C# 脚本模块采用以下路线:
|
||||
|
||||
- **脚本语言**:C#
|
||||
- **脚本挂载模型**:原生 `ScriptComponent` 对应托管 `MonoBehaviour`
|
||||
- **程序集模型**:`ScriptCore` 与 `GameScripts` 分离
|
||||
- **运行时加载模式**:独立编译,运行时加载
|
||||
- **桥接方式**:`InternalCall`
|
||||
- **运行时抽象策略**:先抽象接口,再优先落 Mono 实现
|
||||
- **第一阶段验证方式**:单元测试优先,不依赖 editor
|
||||
|
||||
这条路线有两个核心原则:
|
||||
|
||||
1. API 形态尽量接近 Unity
|
||||
2. 第一阶段严格控制范围,只做运行时闭环和测试闭环
|
||||
|
||||
---
|
||||
|
||||
## 5. 运行时选型
|
||||
|
||||
### 5.1 第一阶段选型:Mono
|
||||
|
||||
第一阶段建议使用 `Mono` 作为第一套 C# 运行时实现,原因如下:
|
||||
|
||||
- 与现有规划文档保持一致
|
||||
- 参考项目已经证明这条技术路线可落地
|
||||
- `InternalCall` 路线成熟,适合快速建立最小可用系统
|
||||
- 便于在 Windows 环境中先做出可运行结果
|
||||
|
||||
### 5.2 选型边界
|
||||
|
||||
本设计不把 `Mono` 写死为脚本系统唯一实现,而是将其作为第一实现:
|
||||
|
||||
- 对外暴露 `IScriptRuntime` / `ScriptEngine` 抽象
|
||||
- `MonoScriptRuntime` 作为第一套后端
|
||||
- 后续如有需要,可以演进到 `CoreCLR` 或其他运行时
|
||||
|
||||
### 5.3 第一阶段不做的运行时能力
|
||||
|
||||
Mono 相关的以下复杂能力不进入第一阶段:
|
||||
|
||||
- 域热重载
|
||||
- 编辑器内自动重编译后重载
|
||||
- 托管调试器接入
|
||||
- 发布态 AOT
|
||||
|
||||
第一阶段仅要求:
|
||||
|
||||
- 初始化运行时
|
||||
- 加载核心程序集
|
||||
- 加载用户程序集
|
||||
- 发现脚本类
|
||||
- 实例化对象
|
||||
- 调用生命周期
|
||||
- 读写托管字段
|
||||
|
||||
---
|
||||
|
||||
## 6. 模块划分
|
||||
|
||||
### 6.1 原生侧模块
|
||||
|
||||
建议在 `engine` 内新增 `Scripting` 模块:
|
||||
|
||||
```text
|
||||
engine/
|
||||
├── include/XCEngine/Scripting/
|
||||
│ ├── ScriptEngine.h
|
||||
│ ├── IScriptRuntime.h
|
||||
│ ├── ScriptAssembly.h
|
||||
│ ├── ScriptClass.h
|
||||
│ ├── ScriptInstance.h
|
||||
│ ├── ScriptField.h
|
||||
│ ├── ScriptFieldStorage.h
|
||||
│ ├── ScriptGlue.h
|
||||
│ └── ScriptComponent.h
|
||||
└── src/Scripting/
|
||||
├── ScriptEngine.cpp
|
||||
├── ScriptGlue.cpp
|
||||
├── ScriptComponent.cpp
|
||||
└── Mono/
|
||||
├── MonoScriptRuntime.cpp
|
||||
├── MonoScriptClass.cpp
|
||||
└── MonoScriptAssembly.cpp
|
||||
```
|
||||
|
||||
### 6.2 托管侧模块
|
||||
|
||||
建议新增托管核心库 `ScriptCore`:
|
||||
|
||||
```text
|
||||
managed/
|
||||
├── XCEngine.ScriptCore/
|
||||
│ ├── XCEngine.ScriptCore.csproj
|
||||
│ ├── Object.cs
|
||||
│ ├── Component.cs
|
||||
│ ├── Behaviour.cs
|
||||
│ ├── MonoBehaviour.cs
|
||||
│ ├── GameObject.cs
|
||||
│ ├── Transform.cs
|
||||
│ ├── Debug.cs
|
||||
│ ├── Time.cs
|
||||
│ └── InternalCalls.cs
|
||||
└── GameScripts/
|
||||
├── GameScripts.csproj
|
||||
└── Scripts/*.cs
|
||||
```
|
||||
|
||||
### 6.3 程序集分层
|
||||
|
||||
程序集分为两层:
|
||||
|
||||
- `XCEngine.ScriptCore.dll`
|
||||
- 由引擎维护
|
||||
- 提供托管基类和引擎 API 包装
|
||||
- `GameScripts.dll`
|
||||
- 由项目侧维护
|
||||
- 编写具体游戏脚本
|
||||
|
||||
关系如下:
|
||||
|
||||
```text
|
||||
GameScripts.dll
|
||||
└── 引用 XCEngine.ScriptCore.dll
|
||||
|
||||
Engine Core
|
||||
├── 先加载 XCEngine.ScriptCore.dll
|
||||
└── 再加载 GameScripts.dll
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. 对象模型
|
||||
|
||||
### 7.1 托管侧模型
|
||||
|
||||
托管侧应当采用接近 Unity 的对象层次:
|
||||
|
||||
```text
|
||||
Object
|
||||
└── Component
|
||||
└── Behaviour
|
||||
└── MonoBehaviour
|
||||
```
|
||||
|
||||
其中:
|
||||
|
||||
- `Object`:基础托管对象
|
||||
- `Component`:挂载到 `GameObject` 上的托管组件基类
|
||||
- `Behaviour`:带 `enabled` 语义的组件
|
||||
- `MonoBehaviour`:用户脚本直接继承的基类
|
||||
|
||||
### 7.2 原生挂载模型
|
||||
|
||||
原生侧脚本挂载使用 `ScriptComponent`,而不是 `ScriptContainerComponent`。
|
||||
|
||||
原因如下:
|
||||
|
||||
- 更符合 Unity 认知模型
|
||||
- 更容易与现有 `GameObject::AddComponent<T>` 思路对齐
|
||||
- 更容易在未来做 Inspector 级脚本组件显示
|
||||
- 更容易把字段序列化与组件实例对应起来
|
||||
|
||||
建议 `ScriptComponent` 至少包含:
|
||||
|
||||
- `scriptComponentUUID`
|
||||
- `assemblyName`
|
||||
- `namespaceName`
|
||||
- `className`
|
||||
- `enabled`
|
||||
- `fieldStorage`
|
||||
|
||||
推荐接口示意:
|
||||
|
||||
```cpp
|
||||
class ScriptComponent : public Component {
|
||||
public:
|
||||
std::string GetName() const override { return "Script"; }
|
||||
|
||||
const std::string& GetAssemblyName() const;
|
||||
const std::string& GetNamespaceName() const;
|
||||
const std::string& GetClassName() const;
|
||||
std::string GetFullClassName() const;
|
||||
|
||||
uint64_t GetScriptComponentUUID() const;
|
||||
bool IsRuntimeValid() const;
|
||||
|
||||
void Serialize(std::ostream& os) const override;
|
||||
void Deserialize(std::istream& is) override;
|
||||
|
||||
private:
|
||||
uint64_t m_scriptComponentUUID = 0;
|
||||
std::string m_assemblyName = "GameScripts";
|
||||
std::string m_namespaceName;
|
||||
std::string m_className;
|
||||
ScriptFieldStorage m_fieldStorage;
|
||||
};
|
||||
```
|
||||
|
||||
### 7.3 多脚本挂载
|
||||
|
||||
一个 `GameObject` 应允许挂载多个 `ScriptComponent`。
|
||||
|
||||
这与 Unity 保持一致:
|
||||
|
||||
- 同一个对象可以挂多个不同脚本
|
||||
- 同一个脚本是否允许重复挂载,由后续属性或规则控制
|
||||
- 第一阶段不做“禁止重复挂载”的复杂策略
|
||||
|
||||
---
|
||||
|
||||
## 8. 身份模型与序列化要求
|
||||
|
||||
### 8.1 必须使用 UUID,而不是运行时 ID
|
||||
|
||||
脚本系统中,托管实例与原生对象的稳定绑定必须建立在 `UUID` 之上,而不是当前的自增 `ID`。
|
||||
|
||||
原因如下:
|
||||
|
||||
- 运行时场景复制不能依赖自增 ID 稳定
|
||||
- 脚本字段里的对象引用必须有稳定键
|
||||
- editor 与 runtime 之间的对象映射必须有稳定键
|
||||
- 单元测试和场景恢复也需要稳定身份
|
||||
|
||||
因此需要补齐以下要求:
|
||||
|
||||
- `GameObject UUID` 进入场景序列化
|
||||
- 场景反序列化时恢复 `UUID`
|
||||
- `ScriptComponent` 自身也应有持久化 UUID
|
||||
|
||||
### 8.2 第一阶段字段序列化策略
|
||||
|
||||
第一阶段的脚本字段序列化原则如下:
|
||||
|
||||
- 只序列化 `ScriptComponent` 的字段缓存
|
||||
- 只序列化脚本作者显式设置的字段值
|
||||
- 运行时脚本执行过程中修改的值,不自动回写场景
|
||||
|
||||
这与 Unity 的 Play 模式行为一致:
|
||||
|
||||
- Play 中的运行时改动不应直接污染编辑数据
|
||||
|
||||
### 8.3 第一阶段字段支持范围
|
||||
|
||||
建议第一阶段先支持:
|
||||
|
||||
- `float`
|
||||
- `double`
|
||||
- `bool`
|
||||
- `int32`
|
||||
- `uint64`
|
||||
- `string`
|
||||
- `Vector2`
|
||||
- `Vector3`
|
||||
- `Vector4`
|
||||
- `GameObject` 引用
|
||||
|
||||
第一阶段不要求支持:
|
||||
|
||||
- `List<T>`
|
||||
- 自定义托管结构体
|
||||
- 嵌套对象图
|
||||
- 泛型容器
|
||||
- 资源引用对象选择器
|
||||
|
||||
---
|
||||
|
||||
## 9. 生命周期设计
|
||||
|
||||
### 9.1 目标生命周期
|
||||
|
||||
脚本系统最终应支持以下 Unity 风格生命周期:
|
||||
|
||||
- `Awake`
|
||||
- `OnEnable`
|
||||
- `Start`
|
||||
- `FixedUpdate`
|
||||
- `Update`
|
||||
- `LateUpdate`
|
||||
- `OnDisable`
|
||||
- `OnDestroy`
|
||||
|
||||
### 9.2 第一阶段生命周期闭环
|
||||
|
||||
第一阶段就应当把上述生命周期的原生调度链路设计好,哪怕 editor 尚未接入。
|
||||
|
||||
建议运行时流程如下:
|
||||
|
||||
#### `Scene` 运行时启动
|
||||
|
||||
1. `ScriptEngine::OnRuntimeStart(scene)`
|
||||
2. 遍历场景中全部激活对象
|
||||
3. 找到所有 `ScriptComponent`
|
||||
4. 为每个组件创建托管 `MonoBehaviour` 实例
|
||||
5. 写入原生对象 UUID / 组件 UUID / 基础上下文
|
||||
6. 应用序列化字段缓存
|
||||
7. 调用 `Awake`
|
||||
8. 若对象激活且组件启用,调用 `OnEnable`
|
||||
9. 标记“等待 Start”
|
||||
|
||||
#### 每帧执行
|
||||
|
||||
- 物理阶段:`FixedUpdate`
|
||||
- 普通阶段:`Update`
|
||||
- 后处理阶段:`LateUpdate`
|
||||
- 对于尚未执行 `Start` 的脚本,在第一次普通帧前先调用 `Start`
|
||||
|
||||
#### 运行时停止
|
||||
|
||||
1. 对仍处于启用状态的脚本调用 `OnDisable`
|
||||
2. 对所有脚本调用 `OnDestroy`
|
||||
3. 清理托管实例表
|
||||
4. 清理运行时场景上下文
|
||||
|
||||
### 9.3 对现有引擎的前置要求
|
||||
|
||||
为了让脚本生命周期符合预期,现有引擎需要补齐以下地基:
|
||||
|
||||
- `Scene` 更新必须递归整个层级,而不是只更新根对象
|
||||
- `Start` 必须具备“一次且仅一次”语义
|
||||
- `SetActive` 必须驱动 `OnEnable/OnDisable`
|
||||
- 运行时场景启动与停止必须显式化
|
||||
- 创建对象时不应直接把“编辑态创建”与“运行态 Awake”混为一谈
|
||||
|
||||
这些工作虽然不都属于脚本模块,但它们是脚本模块的直接运行前提。
|
||||
|
||||
---
|
||||
|
||||
## 10. 原生与托管之间的桥接
|
||||
|
||||
### 10.1 桥接方式
|
||||
|
||||
第一阶段使用 `InternalCall`:
|
||||
|
||||
- 托管侧通过 `MethodImplOptions.InternalCall` 声明方法
|
||||
- 原生侧通过 `mono_add_internal_call` 注册
|
||||
|
||||
### 10.2 第一阶段最小 API 集
|
||||
|
||||
第一阶段建议只暴露最小必需 API:
|
||||
|
||||
- `Debug.Log / LogWarning / LogError`
|
||||
- `Time.deltaTime`
|
||||
- `GameObject.GetName / SetName`
|
||||
- `GameObject.GetTransform`
|
||||
- `Component.GetGameObject`
|
||||
- `GameObject.HasComponent<T>`
|
||||
- `GameObject.GetComponent<T>`
|
||||
- `Transform` 的本地位置 / 旋转 / 缩放
|
||||
|
||||
这套 API 足够覆盖以下测试与最小演示:
|
||||
|
||||
- 变换脚本
|
||||
- 旋转/移动脚本
|
||||
- 生命周期日志验证
|
||||
- 组件访问验证
|
||||
|
||||
第一阶段不建议优先暴露:
|
||||
|
||||
- 物理 API
|
||||
- 渲染 API
|
||||
- 音频 API
|
||||
- 输入系统
|
||||
- 资源系统
|
||||
|
||||
原因很简单:
|
||||
|
||||
- 第一阶段以单元测试闭环为主
|
||||
- 暴露面越大,绑定维护成本越高
|
||||
- 当前这些系统本身仍在演进
|
||||
|
||||
---
|
||||
|
||||
## 11. 类发现与实例管理
|
||||
|
||||
### 11.1 脚本类发现规则
|
||||
|
||||
用户脚本类应满足以下条件才被视为可挂载脚本:
|
||||
|
||||
- 定义在 `GameScripts.dll`
|
||||
- 非抽象类
|
||||
- 继承 `XCEngine.MonoBehaviour`
|
||||
|
||||
### 11.2 缓存结构
|
||||
|
||||
原生运行时需要缓存以下信息:
|
||||
|
||||
- 程序集表
|
||||
- 脚本类表
|
||||
- 方法句柄表
|
||||
- 字段元数据表
|
||||
- 运行时实例表
|
||||
|
||||
建议实例表键使用:
|
||||
|
||||
- `GameObjectUUID + ScriptComponentUUID`
|
||||
|
||||
而不是:
|
||||
|
||||
- 内存地址
|
||||
- 组件在容器中的索引
|
||||
- 自增 ID
|
||||
|
||||
### 11.3 方法缓存
|
||||
|
||||
每个脚本类应缓存常用生命周期方法句柄:
|
||||
|
||||
- `Awake`
|
||||
- `OnEnable`
|
||||
- `Start`
|
||||
- `FixedUpdate`
|
||||
- `Update`
|
||||
- `LateUpdate`
|
||||
- `OnDisable`
|
||||
- `OnDestroy`
|
||||
|
||||
这样可以避免每帧按字符串查找方法。
|
||||
|
||||
---
|
||||
|
||||
## 12. 单元测试优先策略
|
||||
|
||||
### 12.1 原则
|
||||
|
||||
第一阶段脚本模块不依赖 editor,因此验证策略以单元测试和最小运行时测试为主。
|
||||
|
||||
### 12.2 测试目录建议
|
||||
|
||||
```text
|
||||
tests/
|
||||
└── Scripting/
|
||||
├── unit/
|
||||
│ ├── test_script_runtime.cpp
|
||||
│ ├── test_script_metadata.cpp
|
||||
│ ├── test_script_component.cpp
|
||||
│ ├── test_script_fields.cpp
|
||||
│ └── CMakeLists.txt
|
||||
└── managed/
|
||||
├── XCEngine.ScriptCore/
|
||||
└── TestScripts/
|
||||
```
|
||||
|
||||
### 12.3 第一阶段必须覆盖的测试
|
||||
|
||||
#### 运行时初始化
|
||||
|
||||
- 能初始化脚本运行时
|
||||
- 能加载 `ScriptCore`
|
||||
- 能加载测试脚本程序集
|
||||
|
||||
#### 类发现
|
||||
|
||||
- 只发现继承 `MonoBehaviour` 的类
|
||||
- 忽略抽象类
|
||||
- 忽略普通工具类
|
||||
|
||||
#### 生命周期
|
||||
|
||||
- 能创建托管实例
|
||||
- 能按顺序触发 `Awake -> OnEnable -> Start -> Update`
|
||||
- 能在停止时触发 `OnDisable -> OnDestroy`
|
||||
|
||||
#### 组件桥接
|
||||
|
||||
- 脚本能访问 `GameObject`
|
||||
- 脚本能访问 `Transform`
|
||||
- 脚本能访问最小组件 API
|
||||
|
||||
#### 字段系统
|
||||
|
||||
- 能发现公共字段
|
||||
- 能读写字段
|
||||
- 字段缓存可回填到托管实例
|
||||
- 场景序列化后字段值不丢失
|
||||
|
||||
#### 多脚本对象
|
||||
|
||||
- 同一 `GameObject` 上多个 `ScriptComponent` 都可实例化
|
||||
- 不同脚本实例之间不会串字段
|
||||
|
||||
#### UUID 绑定
|
||||
|
||||
- 运行时复制或反序列化后仍可稳定恢复脚本绑定键
|
||||
|
||||
### 12.4 第一阶段不要求的测试
|
||||
|
||||
- editor Inspector UI
|
||||
- 热重载
|
||||
- 编译器输出面板
|
||||
- 文件监听
|
||||
- 资源拖拽
|
||||
|
||||
---
|
||||
|
||||
## 13. 建议的实现顺序
|
||||
|
||||
### 阶段 A:补运行时地基
|
||||
|
||||
先补以下基础能力:
|
||||
|
||||
- `GameObject UUID` 序列化
|
||||
- 层级递归更新
|
||||
- `Start` 一次性语义
|
||||
- `SetActive` 对生命周期的影响
|
||||
- `Scene` 运行时启动/停止接口
|
||||
|
||||
### 阶段 B:脚本最小闭环
|
||||
|
||||
完成:
|
||||
|
||||
- `Scripting` 模块骨架
|
||||
- `ScriptComponent`
|
||||
- `MonoScriptRuntime`
|
||||
- `XCEngine.ScriptCore.dll`
|
||||
- `GameScripts.dll`
|
||||
- 最小 `InternalCall`
|
||||
|
||||
### 阶段 C:字段与序列化
|
||||
|
||||
完成:
|
||||
|
||||
- 脚本字段元数据
|
||||
- 字段缓存
|
||||
- `ScriptComponent` 序列化/反序列化
|
||||
- 字段相关单元测试
|
||||
|
||||
### 阶段 D:最小运行时演示
|
||||
|
||||
在不依赖 editor 的前提下完成:
|
||||
|
||||
- 纯运行时测试场景
|
||||
- 一个或两个最小脚本示例
|
||||
- Play 级别运行验证
|
||||
|
||||
### 阶段 E:editor 集成
|
||||
|
||||
后续再做:
|
||||
|
||||
- 脚本组件 Inspector
|
||||
- 类选择器
|
||||
- 编译按钮
|
||||
- 错误输出
|
||||
- 重载流程
|
||||
|
||||
---
|
||||
|
||||
## 14. 与 editor 的关系
|
||||
|
||||
第一阶段文档明确规定:
|
||||
|
||||
- C# 脚本模块**不依赖 editor 完整落地**
|
||||
- editor 相关工作全部后置
|
||||
- editor 相关缺口统一记录在 `docs/issues`
|
||||
|
||||
第一阶段唯一允许与 editor 共用的内容是:
|
||||
|
||||
- 场景序列化格式
|
||||
- `GameObject UUID` 语义
|
||||
- 运行时场景副本的总体设计方向
|
||||
|
||||
除此之外,不应把脚本模块第一阶段实现建立在 editor 已具备以下能力的假设上:
|
||||
|
||||
- Play/Simulate 控制条
|
||||
- Inspector 自定义字段绘制
|
||||
- 项目内脚本自动编译
|
||||
- 脚本异常面板
|
||||
|
||||
---
|
||||
|
||||
## 15. 风险与权衡
|
||||
|
||||
### 15.1 Mono 依赖
|
||||
|
||||
风险:
|
||||
|
||||
- Windows 环境需要显式安装或打包 Mono
|
||||
- CMake 配置与发布路径管理会变复杂
|
||||
|
||||
权衡:
|
||||
|
||||
- 第一阶段优先解决“能跑起来”的问题
|
||||
- 运行时抽象保留未来替换空间
|
||||
|
||||
### 15.2 生命周期与现有引擎实现的偏差
|
||||
|
||||
风险:
|
||||
|
||||
- 如果继续保留当前“创建对象就立即 `Awake`”的行为,脚本生命周期会混乱
|
||||
|
||||
权衡:
|
||||
|
||||
- 脚本系统建设必须带动运行时生命周期整理
|
||||
|
||||
### 15.3 字段系统范围
|
||||
|
||||
风险:
|
||||
|
||||
- 一开始就追求完整序列化会让范围失控
|
||||
|
||||
权衡:
|
||||
|
||||
- 第一阶段只做基础类型与少量引用类型
|
||||
- 复杂容器和高级序列化后置
|
||||
|
||||
### 15.4 editor 后置
|
||||
|
||||
风险:
|
||||
|
||||
- 第一阶段用户体验不完整
|
||||
|
||||
权衡:
|
||||
|
||||
- 可以显著降低实现风险
|
||||
- 可以先通过单测和运行时样例把底层做稳
|
||||
|
||||
---
|
||||
|
||||
## 16. 最终结论
|
||||
|
||||
XCEngine 的 C# 脚本系统应当采用:
|
||||
|
||||
- `ScriptComponent + MonoBehaviour`
|
||||
- `ScriptCore + GameScripts` 双程序集结构
|
||||
- `InternalCall` 桥接
|
||||
- `Mono` 作为第一套运行时实现
|
||||
- `UUID` 作为绑定与序列化的稳定身份
|
||||
- 第一阶段只做运行时与单元测试,不依赖 editor
|
||||
|
||||
这条路线既保留了 Unity 风格的一致性,也能适配当前工程实际进度。
|
||||
|
||||
第一阶段的成功标准不是“Inspector 能编辑脚本字段”,而是:
|
||||
|
||||
- 能加载脚本程序集
|
||||
- 能发现脚本类
|
||||
- 能在场景运行时驱动 `MonoBehaviour`
|
||||
- 能通过单元测试验证生命周期、字段和绑定语义
|
||||
|
||||
达到这一点后,再进入 editor 集成阶段,工程风险会显著更低。
|
||||
128
docs/used/EditorViewport宿主渲染收口总结4.1.md
Normal file
128
docs/used/EditorViewport宿主渲染收口总结4.1.md
Normal file
@@ -0,0 +1,128 @@
|
||||
# Editor Viewport 宿主渲染收口总结 4.1
|
||||
|
||||
## 当前判断
|
||||
|
||||
截至 2026-04-01,这一阶段的主线应视为:
|
||||
|
||||
- 把 `Editor -> ViewportHost -> Renderer -> RHI` 这条链路接通
|
||||
- 把 editor viewport 的宿主层从 panel 内部逻辑中收出来
|
||||
- 把这层宿主代码压到“可继续演进,但先停止扩张”的状态
|
||||
|
||||
这一阶段的目标不是继续往 editor viewport 里塞更多功能,也不是提前做完未来 renderer 的全部能力。
|
||||
|
||||
如果继续在本阶段里混入 gizmo 完整体系、GPU picking 正式方案、多 pass 大改、后处理、光照系统等内容,只会让阶段边界再次失控。
|
||||
|
||||
## 已完成的收口结果
|
||||
|
||||
### 1. editor viewport 已经不再是空壳
|
||||
|
||||
当前 `SceneView` 与 `GameView` 已经能通过统一的 viewport host 路径请求离屏 render target,并把 renderer 输出展示到 editor 面板中。
|
||||
|
||||
当前已实际接通:
|
||||
|
||||
- Scene viewport 渲染
|
||||
- Game viewport 渲染
|
||||
- viewport resize 资源重建
|
||||
- backpack 等真实模型内容在 editor 中显示
|
||||
- grid / 选中 / 描边 / object id 读取链路
|
||||
|
||||
### 2. viewport host 的职责边界已经成型
|
||||
|
||||
当前 viewport 宿主层已经被拆成几块相对明确的职责:
|
||||
|
||||
- [editor/src/Viewport/ViewportHostSurfaceUtils.h](D:/Xuanchi/Main/XCEngine/editor/src/Viewport/ViewportHostSurfaceUtils.h)
|
||||
- viewport surface / texture / reuse 相关纯工具
|
||||
- [editor/src/Viewport/ViewportHostRenderTargets.h](D:/Xuanchi/Main/XCEngine/editor/src/Viewport/ViewportHostRenderTargets.h)
|
||||
- viewport render target 生命周期与创建销毁
|
||||
- [editor/src/Viewport/ViewportObjectIdPicker.h](D:/Xuanchi/Main/XCEngine/editor/src/Viewport/ViewportObjectIdPicker.h)
|
||||
- viewport object id 读取与像素映射
|
||||
- [editor/src/Viewport/ViewportHostRenderFlowUtils.h](D:/Xuanchi/Main/XCEngine/editor/src/Viewport/ViewportHostRenderFlowUtils.h)
|
||||
- scene/game viewport 的失败回退策略、request 组装、成功态迁移
|
||||
- [editor/src/Viewport/ViewportHostService.h](D:/Xuanchi/Main/XCEngine/editor/src/Viewport/ViewportHostService.h)
|
||||
- 保留真正的 orchestration、scene view camera、post pass 组装与 clear 执行
|
||||
|
||||
这意味着 viewport host 已经不再是“一个面板私有的大杂烩类”,而是一个有明确宿主边界的 editor 侧接入层。
|
||||
|
||||
### 3. 现阶段测试闭环已经补上
|
||||
|
||||
当前 editor 侧已经有明确的宿主层单测覆盖:
|
||||
|
||||
- [tests/editor/test_viewport_host_surface_utils.cpp](D:/Xuanchi/Main/XCEngine/tests/editor/test_viewport_host_surface_utils.cpp)
|
||||
- [tests/editor/test_viewport_render_targets.cpp](D:/Xuanchi/Main/XCEngine/tests/editor/test_viewport_render_targets.cpp)
|
||||
- [tests/editor/test_viewport_object_id_picker.cpp](D:/Xuanchi/Main/XCEngine/tests/editor/test_viewport_object_id_picker.cpp)
|
||||
- [tests/editor/test_viewport_render_flow_utils.cpp](D:/Xuanchi/Main/XCEngine/tests/editor/test_viewport_render_flow_utils.cpp)
|
||||
|
||||
本轮收口完成后,`editor_tests` 已覆盖 viewport host 中最容易回归的纯策略与资源管理逻辑。
|
||||
|
||||
## 为什么到这里应当停止继续拆
|
||||
|
||||
当前 [editor/src/Viewport/ViewportHostService.h](D:/Xuanchi/Main/XCEngine/editor/src/Viewport/ViewportHostService.h) 剩下的主要内容,是以下几类“真正属于宿主编排”的职责:
|
||||
|
||||
- scene view camera 的创建与驱动
|
||||
- focus / orientation axis 等 editor 专属视图控制
|
||||
- scene view post pass 的装配
|
||||
- scene/game viewport 的 render dispatch
|
||||
- clear 执行
|
||||
|
||||
这些逻辑如果继续硬拆,很容易为了“文件更小”而把真正依赖 editor 运行时状态的 orchestration 人为打散,收益已经明显下降。
|
||||
|
||||
所以这一阶段的明确结论是:
|
||||
|
||||
- `ViewportHostService` 继续保持为宿主编排入口是合理的
|
||||
- 不再以“继续拆文件”为本阶段目标
|
||||
- 下一阶段应把重点转移到 renderer 本身的演进,而不是继续挤压 editor host
|
||||
|
||||
## 本阶段的结束标准
|
||||
|
||||
这一阶段以以下标准视为完成:
|
||||
|
||||
1. `editor_tests` 全部通过
|
||||
2. `XCEditor` 能正常编译
|
||||
3. viewport host 的主要纯逻辑都有独立单测
|
||||
4. `ViewportHostService` 不再继续承载资源创建、object id 读取、失败策略等细碎职责
|
||||
5. 明确哪些问题属于后续 renderer 阶段,而不是继续留在当前阶段消耗
|
||||
|
||||
## 明确不属于本阶段的内容
|
||||
|
||||
以下内容不再计入“editor viewport 宿主渲染收口”阶段:
|
||||
|
||||
- GPU object id 正式拾取方案
|
||||
- renderer 内部通用多 pass / render graph 体系
|
||||
- 更正式的 editor outline 方案升级
|
||||
- gizmo 全量产品化
|
||||
- 光照、阴影、后处理
|
||||
- runtime 渲染管线的完整 SRP 式抽象
|
||||
|
||||
这些内容应进入 renderer 后续阶段,而不是继续塞回当前 viewport host 收口任务。
|
||||
|
||||
## 下一阶段建议
|
||||
|
||||
下一阶段主线应转为:
|
||||
|
||||
### 1. renderer 能力继续上移
|
||||
|
||||
把目前 editor 层为了接通 viewport 而保留的一些临时职责,逐步让 renderer 吸收为正式能力,例如:
|
||||
|
||||
- 多 pass 组织能力
|
||||
- 正式的 object id / editor helper pass 接口
|
||||
- editor 与 runtime 共享的 camera render path
|
||||
|
||||
### 2. editor 只消费 renderer 提供的正式输出
|
||||
|
||||
editor viewport 后续应更多扮演:
|
||||
|
||||
- render target 宿主
|
||||
- 输入转发
|
||||
- overlay / gizmo 宿主
|
||||
- editor 专属交互入口
|
||||
|
||||
而不是继续承载 renderer 内部演进本体。
|
||||
|
||||
## 阶段性结论
|
||||
|
||||
这一阶段现在可以正式收口:
|
||||
|
||||
- editor viewport 已经从“空面板”进入“真实宿主层”
|
||||
- renderer 与 RHI 已经能稳定把离屏结果送进 editor
|
||||
- viewport host 的边界已经明确
|
||||
- 后续不应继续在本阶段内部无限拆分,而应切换到 renderer 下一阶段
|
||||
78
docs/used/Editor模块_CMake直链Release版XCEngine库破坏配置一致性3.28.md
Normal file
78
docs/used/Editor模块_CMake直链Release版XCEngine库破坏配置一致性3.28.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# Editor模块 CMake直链Release版XCEngine库破坏配置一致性
|
||||
## 1. 问题定义
|
||||
|
||||
当前 editor 可执行目标的链接方式仍然是硬编码文件路径:
|
||||
|
||||
- [`editor/CMakeLists.txt`](D:\Xuanchi\Main\XCEngine\editor\CMakeLists.txt)
|
||||
|
||||
当前写法:
|
||||
|
||||
- `target_link_libraries(... ${CMAKE_CURRENT_SOURCE_DIR}/../build/engine/Release/XCEngine.lib)`
|
||||
|
||||
这不是正常的 CMake target 依赖,而是直接绑死到一个磁盘上的 `Release` 静态库文件。
|
||||
|
||||
---
|
||||
|
||||
## 2. 当前影响
|
||||
|
||||
这会导致几个非常实际的问题:
|
||||
|
||||
1. Debug editor 也可能链接到旧的 Release 版引擎库
|
||||
2. editor 对 `XCEngine` 目标没有真实依赖关系
|
||||
3. 引擎库变更后,editor 可能不会按正确配置自动重建
|
||||
4. Debug / Release 混链风险被隐藏
|
||||
|
||||
当前本地状态就能看到:
|
||||
|
||||
- `build/engine/Debug/XCEngine.lib`
|
||||
- `build/engine/Release/XCEngine.lib`
|
||||
|
||||
两者时间戳和体积明显不同,但 editor 目标仍然硬连 Release 文件。
|
||||
|
||||
---
|
||||
|
||||
## 3. 为什么这是重大缺陷
|
||||
|
||||
这条会直接污染后续 Viewport 对接的开发过程:
|
||||
|
||||
- 你以为 editor 正在吃最新的 Renderer / RHI 改动
|
||||
- 实际上它可能仍在链接旧的 Release 库
|
||||
|
||||
这样一来:
|
||||
|
||||
- viewport 接入问题很难调
|
||||
- Debug 行为和 Release 行为可能不一致
|
||||
- CI / 新机器 / 干净构建环境也更容易炸
|
||||
|
||||
它不是“代码风格问题”,而是构建依赖关系本身不正确。
|
||||
|
||||
---
|
||||
|
||||
## 4. 建议方案
|
||||
|
||||
应改成标准 CMake target 依赖:
|
||||
|
||||
1. editor 直接链接 `XCEngine`
|
||||
2. 不再手写 `../build/engine/Release/XCEngine.lib`
|
||||
3. 由 CMake 自己处理 Debug / Release / RelWithDebInfo 的库选择
|
||||
4. editor/include 路径和 link 关系都从 target 传播,而不是继续手写 build 输出路径
|
||||
|
||||
---
|
||||
|
||||
## 5. 验收标准
|
||||
|
||||
完成后至少应满足:
|
||||
|
||||
1. `editor` 目标通过 `target_link_libraries(... XCEngine)` 链接引擎
|
||||
2. Debug editor 自动吃 Debug `XCEngine`
|
||||
3. Release editor 自动吃 Release `XCEngine`
|
||||
4. 修改 engine 后重新构建 editor 时,依赖关系正确生效
|
||||
5. 干净构建环境不依赖预先存在的某个磁盘库文件
|
||||
|
||||
---
|
||||
|
||||
## 6. 优先级
|
||||
|
||||
中高。
|
||||
|
||||
它未必第一时间阻塞面板 UI 开发,但会显著污染后续所有 viewport / renderer 联调结果,建议尽快修。
|
||||
94
docs/used/Editor模块_宿主渲染与EngineRHI未统一导致Viewport纹理无法接入3.28.md
Normal file
94
docs/used/Editor模块_宿主渲染与EngineRHI未统一导致Viewport纹理无法接入3.28.md
Normal file
@@ -0,0 +1,94 @@
|
||||
# Editor模块 宿主渲染与EngineRHI未统一导致Viewport纹理无法接入
|
||||
## 1. 问题定义
|
||||
|
||||
当前 editor 的窗口宿主渲染仍然是一套独立的原生 D3D12 路径:
|
||||
|
||||
- [`editor/src/Application.h`](D:\Xuanchi\Main\XCEngine\editor\src\Application.h)
|
||||
- [`editor/src/Application.cpp`](D:\Xuanchi\Main\XCEngine\editor\src\Application.cpp)
|
||||
- [`editor/src/Platform/D3D12WindowRenderer.h`](D:\Xuanchi\Main\XCEngine\editor\src\Platform\D3D12WindowRenderer.h)
|
||||
|
||||
这套路径只负责:
|
||||
|
||||
- 创建 Win32 窗口交换链
|
||||
- 创建独立的 `ID3D12Device / ID3D12CommandQueue`
|
||||
- 渲染 ImGui 主界面
|
||||
|
||||
而当前引擎的 RHI / Renderer 则是另一套独立设备与上下文体系。
|
||||
|
||||
这意味着后续即使 Renderer 能把 `SceneView/GameView` 渲染到离屏目标,editor 侧也没有稳定的统一设备桥接层把那张纹理安全地贴到 ImGui。
|
||||
|
||||
---
|
||||
|
||||
## 2. 当前现状
|
||||
|
||||
当前 `Application::InitializeWindowRenderer()` 直接创建原生 D3D12 宿主:
|
||||
|
||||
- editor 只知道 `Platform::D3D12WindowRenderer`
|
||||
- editor 并不持有 `RHIDevice / RenderContext / RenderSurface`
|
||||
- `SceneViewPanel / GameViewPanel` 也没有可复用的 viewport host 对象
|
||||
|
||||
结果是:
|
||||
|
||||
- editor 主界面渲染和引擎 Renderer 渲染仍然分裂
|
||||
- 未来 viewport 要么走不通
|
||||
- 要么被迫写一层高风险的 D3D12 私有纹理互拷/句柄桥接
|
||||
- 要么反向污染 Renderer,使其去适配 editor 私有宿主
|
||||
|
||||
---
|
||||
|
||||
## 3. 为什么这是重大缺陷
|
||||
|
||||
这不是“面板里还没把图显示出来”的小缺口,而是 viewport 接入的根部边界问题。
|
||||
|
||||
如果不先统一宿主层,后面很容易走成错误路线:
|
||||
|
||||
- Editor 继续维护一套私有 D3D12 设备
|
||||
- Renderer 再维护一套引擎 RHI 设备
|
||||
- `SceneView` 和 `GameView` 为了显示纹理被迫做后端专用互操作
|
||||
- Vulkan / OpenGL 路径在 editor 中天然失去接入可能
|
||||
|
||||
这会直接破坏:
|
||||
|
||||
- RHI 抽象边界
|
||||
- Renderer 的后端无关性
|
||||
- 后续 editor viewport 与 runtime 共用同一渲染链路的目标
|
||||
|
||||
---
|
||||
|
||||
## 4. 建议方案
|
||||
|
||||
正确方向应该是:
|
||||
|
||||
1. editor 宿主层只保留“窗口 + ImGui 宿主”职责
|
||||
2. viewport 输出统一来自引擎 Renderer 的 `RenderSurface`
|
||||
3. editor 增加专门的 viewport bridge / host 层,而不是把渲染实现塞进 panel
|
||||
4. 该 bridge 层需要明确处理:
|
||||
- 使用哪个 RHI backend
|
||||
- 如何创建离屏 color/depth 目标
|
||||
- 如何把离屏结果暴露为 ImGui 可显示纹理
|
||||
- resize 生命周期
|
||||
- device/context 所有权
|
||||
|
||||
建议不要继续扩张 `D3D12WindowRenderer` 的职责。
|
||||
|
||||
它可以继续作为 editor 主窗口 UI 宿主,但不应成为 viewport 真实渲染实现本体。
|
||||
|
||||
---
|
||||
|
||||
## 5. 验收标准
|
||||
|
||||
完成后至少应满足:
|
||||
|
||||
1. editor 可以不依赖私有 D3D12 纹理路径来显示 viewport
|
||||
2. `SceneView` 和 `GameView` 都走统一的 viewport host 接口
|
||||
3. viewport 输出来自引擎 `RenderSurface`
|
||||
4. editor 不需要因为切换 OpenGL / D3D12 / Vulkan 而重写面板逻辑
|
||||
5. Renderer 不需要反向依赖 editor 平台实现
|
||||
|
||||
---
|
||||
|
||||
## 6. 优先级
|
||||
|
||||
高。
|
||||
|
||||
在开始正式做 Scene/Game Viewport 之前必须先收敛这个边界,否则后面的接入实现会天然带着架构债。
|
||||
87
docs/used/Editor模块_项目根路径仍绑定可执行目录阻塞真实场景与资源加载3.28.md
Normal file
87
docs/used/Editor模块_项目根路径仍绑定可执行目录阻塞真实场景与资源加载3.28.md
Normal file
@@ -0,0 +1,87 @@
|
||||
# Editor模块 项目根路径仍绑定可执行目录阻塞真实场景与资源加载
|
||||
## 1. 问题定义
|
||||
|
||||
当前 editor 初始化 `EditorContext` 时,把 project path 直接设成了可执行文件目录:
|
||||
|
||||
- [`editor/src/Application.cpp`](D:\Xuanchi\Main\XCEngine\editor\src\Application.cpp)
|
||||
|
||||
具体行为是:
|
||||
|
||||
- 通过 `GetExecutableDirectoryUtf8()` 拿 exe 目录
|
||||
- 用这个目录初始化 `EditorContext`
|
||||
- `ProjectPanel` 和 `SceneManager::LoadStartupScene()` 都基于这个路径工作
|
||||
|
||||
这意味着 editor 当前没有“真实工程根目录”的概念。
|
||||
|
||||
---
|
||||
|
||||
## 2. 当前影响
|
||||
|
||||
基于当前实现:
|
||||
|
||||
- `ProjectManager::Initialize()` 会把 `<projectPath>/Assets` 当作项目资源根
|
||||
- [`editor/src/Managers/ProjectManager.cpp`](D:\Xuanchi\Main\XCEngine\editor\src\Managers\ProjectManager.cpp)
|
||||
- [`editor/src/Core/EditorWorkspace.h`](D:\Xuanchi\Main\XCEngine\editor\src\Core\EditorWorkspace.h)
|
||||
|
||||
但 `projectPath` 现在是 `editor/bin/...`
|
||||
|
||||
结果就是:
|
||||
|
||||
- Project 面板看到的是 exe 目录下的 `Assets`
|
||||
- Startup Scene 也是从 exe 目录下找 `Assets/Scenes/Main.xc`
|
||||
- viewport 后面如果要加载真实 scene / material / texture / mesh,也会默认走错根目录
|
||||
|
||||
对“真正接引擎工程内容”来说,这是实打实的阻塞项。
|
||||
|
||||
---
|
||||
|
||||
## 3. 为什么这是重大缺陷
|
||||
|
||||
Scene/Game Viewport 一旦接 Renderer,就不再只是“显示一个空测试图”。
|
||||
|
||||
它需要基于当前工程:
|
||||
|
||||
- 加载场景
|
||||
- 找到 mesh / material / texture / shader 资产
|
||||
- 正确解析 `Assets/...` 相对路径
|
||||
|
||||
如果 editor 的项目根仍然绑定在 exe 目录:
|
||||
|
||||
- 资源加载结果会和实际工程目录脱钩
|
||||
- Editor 和运行时看到的资产树不是同一棵
|
||||
- 后续 Project 面板、Scene 保存、Viewport 渲染都会形成伪项目环境
|
||||
|
||||
---
|
||||
|
||||
## 4. 建议方案
|
||||
|
||||
建议尽快引入明确的工程根路径入口,而不是继续默认 exe 目录:
|
||||
|
||||
1. `Application` 启动时明确解析 editor project root
|
||||
2. 最少先支持:
|
||||
- 命令行传入工程根
|
||||
- 或固定读取 workspace/project 配置
|
||||
3. `EditorContext / ProjectManager / SceneManager` 统一只认这一份 project root
|
||||
4. `ProjectPanel`、startup scene、future viewport asset loading 全部复用同一来源
|
||||
|
||||
在没有真实 project root 之前,不建议开始做 viewport 里的正式资源接入。
|
||||
|
||||
---
|
||||
|
||||
## 5. 验收标准
|
||||
|
||||
完成后至少应满足:
|
||||
|
||||
1. editor 能明确知道当前工程根目录,而不是推断 exe 目录
|
||||
2. Project 面板显示的是工程真实 `Assets`
|
||||
3. Startup Scene 从真实工程根加载
|
||||
4. Scene/Game Viewport 后续使用的资源路径与 Project 面板一致
|
||||
5. Debug / Release / editor/bin 变化不会改变 editor 看到的项目内容
|
||||
|
||||
---
|
||||
|
||||
## 6. 优先级
|
||||
|
||||
高。
|
||||
|
||||
这条不解决,Viewport 接入后只会跑在一个“伪项目目录”里,后面越做越难回收。
|
||||
BIN
docs/used/Editor资源缓存.png
Normal file
BIN
docs/used/Editor资源缓存.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
165
docs/used/Editor重构3.26.md
Normal file
165
docs/used/Editor重构3.26.md
Normal file
@@ -0,0 +1,165 @@
|
||||
# Editor 重构 3.26
|
||||
|
||||
## 当前判断
|
||||
|
||||
截至 2026-03-27,如果只看 editor 的 UI 架构与编辑器壳层整理,不把 `Viewport / RHI` 和 `Scene / Game` 的真实内容算进去,这一轮重构大约已经完成 **96%**。
|
||||
|
||||
如果把“编辑器整体可用度”一起算进去,则仍然没有结束,因为:
|
||||
|
||||
- `Scene` panel 仍然是空壳。
|
||||
- `Game` panel 仍然是空壳。
|
||||
- `Viewport` 尚未跟随 RHI 重构完成回归。
|
||||
|
||||
所以现在的真实状态是:
|
||||
|
||||
- **UI 架构已经基本收稳**
|
||||
- **编辑器产品功能还没有做完**
|
||||
|
||||
## 已经完成的核心重构
|
||||
|
||||
### 1. 分层已经基本建立
|
||||
|
||||
当前 editor 已经形成比较稳定的职责划分:
|
||||
|
||||
- `UI` 负责主题、token、共享控件、popup、property-grid。
|
||||
- `Actions` 负责菜单、快捷键、右键菜单、按钮动作的共享路由。
|
||||
- `Commands` 负责 scene/project/entity/component 的编辑行为。
|
||||
- `Layout` 负责 dock host、默认布局、布局重置与持久化。
|
||||
- `Panels` 逐步退化为窗口壳层。
|
||||
- `Core / Managers` 负责 editor context、selection、undo、scene、project 等共享状态。
|
||||
- `ComponentEditors` 负责 inspector 中各组件的编辑器与注册体系。
|
||||
|
||||
这说明 editor 已经从“每个 panel 自己堆逻辑”的结构,切换到“共享层驱动”的结构。
|
||||
|
||||
### 2. 共享 UI 基础层已经落稳
|
||||
|
||||
已经把大量原先散落在 panel 内部的视觉和控件逻辑收口到 shared UI 层,包括:
|
||||
|
||||
- 主题和样式 token
|
||||
- panel chrome
|
||||
- toolbar/search/button
|
||||
- popup / modal state
|
||||
- empty state
|
||||
- asset tile
|
||||
- hierarchy tree node
|
||||
- component section
|
||||
- property grid / scalar / vector 编辑控件
|
||||
|
||||
这部分的意义是:后面再调 editor 外观,不应该回到 panel 内部逐个修补。
|
||||
|
||||
### 3. Action 路由已经成型
|
||||
|
||||
当前已形成两条主路由:
|
||||
|
||||
- `MainMenuActionRouter`
|
||||
- `EditActionRouter`
|
||||
|
||||
并且 `Hierarchy / Project / Inspector / Console / MenuBar` 的主要菜单和快捷键语义已经接入共享 action/router。
|
||||
|
||||
当前已经做到:
|
||||
|
||||
- `Edit` 菜单不再只是一套写死逻辑,而是跟随 active action route 切换。
|
||||
- menu / shortcut / context menu / toolbar 的动作开始共用同一套 action 定义。
|
||||
- rename、popup、about、exit、reset layout 等交互已不再零散写在 panel 内部。
|
||||
|
||||
### 4. Commands 层已经承担主要编辑语义
|
||||
|
||||
当前主要编辑行为已进入 command 层:
|
||||
|
||||
- 新建 / 打开 / 保存场景
|
||||
- 脏场景 fallback 保存
|
||||
- 创建 / 删除 / 复制 / 粘贴 / duplicate / rename / reparent entity
|
||||
- 创建文件夹 / 删除资源 / 打开资源 / 移动资源
|
||||
- 添加 / 删除组件
|
||||
|
||||
同时,undo / dirty / selection reset 等关键边界,已经尽量不再散落在 panel。
|
||||
|
||||
### 5. Dock / Workspace / Application 壳层已收口
|
||||
|
||||
当前已经完成:
|
||||
|
||||
- `EditorWorkspace` 统一 panel 装配与生命周期调度
|
||||
- `DockLayoutController` 统一 dockspace 和 layout reset
|
||||
- ImGui layout 持久化到项目 `.xceditor/imgui_layout.ini`
|
||||
- `Application.cpp` 中的窗口、renderer、ImGui session、layer attach/detach 已完成明显拆分
|
||||
|
||||
这说明 editor 顶层壳层已经不再像之前那样把 UI、layout、backend、panel 生命周期混在一起。
|
||||
|
||||
### 6. Inspector 的 ComponentEditor 注册体系已稳定
|
||||
|
||||
当前 inspector 不再直接硬编码全部组件逻辑,而是通过:
|
||||
|
||||
- `IComponentEditor`
|
||||
- `ComponentEditorRegistry`
|
||||
- 各具体 `Transform / Camera / Light` component editor
|
||||
|
||||
来统一:
|
||||
|
||||
- 组件显示
|
||||
- Add Component 菜单构建
|
||||
- 组件可添加性 / 可删除性判断
|
||||
|
||||
这部分已经是后续扩展自定义组件 inspector 的正确落点。
|
||||
|
||||
### 7. 回归测试基础已补齐
|
||||
|
||||
当前已新增 `editor_tests`,并已覆盖关键 editor 行为,包括:
|
||||
|
||||
- hierarchy edit route 的 copy / paste / duplicate / delete / rename request
|
||||
- project edit route 的 open / back / delete
|
||||
- scene dirty save + load 后的 selection / undo reset
|
||||
- reparent 时的 parent 切换、cycle 拦截与 world transform 保持
|
||||
- main menu 的 exit / reset layout / about popup request
|
||||
- hierarchy rename helper
|
||||
- project create-folder / move-asset / open-folder helper
|
||||
|
||||
本轮收尾继续补充后,测试会进一步覆盖:
|
||||
|
||||
- clean scene 下的新建场景重置行为
|
||||
- clean scene 下 fallback save 的 no-op 路径
|
||||
- project move-asset 的非法输入保护
|
||||
|
||||
## 当前仍然剩下什么
|
||||
|
||||
### 架构收尾项
|
||||
|
||||
1. 继续压缩少量 panel 本地瞬时状态
|
||||
目标是把还能共享的 popup / router / state 再往 shared 层收一点。
|
||||
|
||||
2. 继续补 editor 回归测试
|
||||
重点补 command/router 边界,而不是 UI 像素测试。
|
||||
|
||||
3. 为 viewport 回归保留 editor shell 接口
|
||||
但暂时不把 RHI/renderer 接进来。
|
||||
|
||||
### 暂缓项
|
||||
|
||||
以下内容不计入当前这一轮 UI 架构收尾:
|
||||
|
||||
- `Scene` panel 真正内容
|
||||
- `Game` panel 真正内容
|
||||
- `Viewport` 渲染接入
|
||||
|
||||
原因不是不做,而是这些工作和 renderer / RHI 重构直接绑定,应该放到后续阶段。
|
||||
|
||||
## 本轮新增文档
|
||||
|
||||
本次已补正式架构说明:
|
||||
|
||||
- `docs/plan/Editor架构说明.md`
|
||||
|
||||
这个文档用于明确:
|
||||
|
||||
- 各层职责边界
|
||||
- 允许依赖方向
|
||||
- panel / action / command / manager / component editor 的落点规则
|
||||
- event bus、undo、dirty、selection 的统一约定
|
||||
|
||||
## 阶段性结论
|
||||
|
||||
当前 editor 可以明确地说:
|
||||
|
||||
- **UI 架构层面已经基本重构完成**
|
||||
- **剩余主要是封口、验证和后续 viewport 接入准备**
|
||||
|
||||
也就是说,后面不应该再回到“看到一个 panel 问题就地补一段特殊逻辑”的方式,而应该继续沿着现有分层做增量完善。
|
||||
536
docs/used/Library资产导入与缓存系统收口计划_完成归档_2026-04-03.md
Normal file
536
docs/used/Library资产导入与缓存系统收口计划_完成归档_2026-04-03.md
Normal file
@@ -0,0 +1,536 @@
|
||||
# Library资产导入与缓存系统收口计划
|
||||
|
||||
归档状态:2026-04-03,当前 `project` 范围内的 Library 导入与缓存系统收口已完成,本文档转为归档记录。
|
||||
|
||||
## 0. 文档定位
|
||||
|
||||
这份文档不是上一轮“从零搭一套 Unity 式 Library 体系”的继续描述,而是当前阶段的正式收口文档。
|
||||
|
||||
### 0.1 当前执行进度(2026-04-03)
|
||||
|
||||
| 阶段 | 状态 | 当前结果 |
|
||||
| --- | --- | --- |
|
||||
| 阶段 A:协议定稿与旧兼容删除 | 已完成 | 已删除 `mesh=` / `materials=` 旧兼容读取,项目资产序列化正式收敛到 `AssetRef`,路径字段仅保留给虚拟资源;scene 迁移工具链已移除。 |
|
||||
| 阶段 B:导入与缓存边界收口 | 已完成 | `AssetImportService` 已接管 Library 根目录、快照构建、缓存重建与 artifact 保证入口;`ProjectAssetIndex` 已只消费服务快照;`ResourceManager` 已收口为运行时缓存/异步调度入口,并提供 `RefreshProjectAssets` / `RebuildProjectAssetCache`。 |
|
||||
| 阶段 C:进行中 | 已完成 `xcmat` 纹理绑定的 `AssetRef + lazy resolve` 首轮收口;下一步继续压缩缓存命中后的恢复成本,并检查是否还存在主线程等待点。 |
|
||||
| 阶段 D:最小工具闭环 | 已完成 | 已完成 `Reimport Selected Asset / Reimport All Assets / Clear Library` 正式入口;已补 `Project` 面板最小导入状态输出;已接入 orphan artifact 清理。 |
|
||||
|
||||
### 0.2 当前已完成的收口结果(2026-04-03)
|
||||
|
||||
- 阶段 A 已完成并验证通过:
|
||||
- `MeshFilterComponent` 对项目 mesh 只序列化 `meshRef`,`meshPath` 只保留给 `builtin://...`
|
||||
- `MeshRendererComponent` 对项目 material 只序列化 `materialRefs`,`materialPaths` 只保留给 `builtin://...`
|
||||
- 旧的 `mesh=` / `materials=` 兼容读取已移除
|
||||
- scene 迁移命令、菜单、report 链路已删除
|
||||
- 阶段 B 已完成并验证通过:
|
||||
- `AssetImportService` 对外新增 `LookupSnapshot`、`ImportedAsset`、`GetLibraryRoot()`、`RebuildLibraryCache()`
|
||||
- `ProjectAssetIndex` 不再直接拼装 `AssetDatabase` 细节,而是只刷新服务快照
|
||||
- `ResourceManager` 不再暴露旧式导入数据库心智,新增 `RefreshProjectAssets()`、`RebuildProjectAssetCache()`、`GetProjectLibraryRoot()`
|
||||
- `AssetDatabase` 初始化后会落盘 `ArtifactDB/artifacts.db`,使空 Library 结构稳定成型
|
||||
- 阶段 C 已开始并完成首个子项:
|
||||
- `Material` 纹理绑定新增稳定 `AssetRef` 元数据,运行时按需把 `AssetRef` 解析为加载路径
|
||||
- `xcmat` 协议已升级为纹理绑定写入 `AssetRef + load path hint`
|
||||
- `AssetDatabase` importer version 已提升,旧 material artifact 将自动失效并重建
|
||||
- 阶段 D 已开始并完成首轮工具口:
|
||||
- `AssetDatabase` 已新增 `TryGetImportableResourceType()`、`ReimportAsset()`、`ReimportAllAssets()`
|
||||
- `AssetImportService` 已新增 `ClearLibraryCache()`、`ReimportAllAssets()`、`ReimportAsset()`
|
||||
- `ResourceManager` 已新增 `CanReimportProjectAsset()`、`ReimportProjectAsset()`、`ClearProjectLibraryCache()`
|
||||
- editor `Assets` 菜单已新增 `Reimport Selected Asset`、`Reimport All Assets`、`Clear Library`
|
||||
- `AssetImportService` 已新增导入状态快照,`Project` 面板工具栏会显示最近一次导入/清库/清理状态
|
||||
- `AssetDatabase` 已新增 orphan artifact 清理,`Refresh / Reimport / 自动重导入` 后都会回收未被 `ArtifactDB` 引用的 `Library/Artifacts/*` 目录
|
||||
- 已完成 focused 验证:
|
||||
- `asset_tests`:
|
||||
- `ResourceManager_Test.ConcurrentAsyncLoadsCoalesceSameMeshPath`
|
||||
- `ResourceManager_Test.AssetLookupFallbackRefreshesSnapshotForNewProjectAsset`
|
||||
- `ProjectAssetIndex_Test.RefreshesSnapshotThroughImportServiceOnCacheMiss`
|
||||
- `AssetImportService_Test.RebuildLibraryCacheKeepsStableAssetRefs`
|
||||
- `ResourceManager_Test.RebuildProjectAssetCacheRefreshesLookupState`
|
||||
- `AssetImportService_Test.ClearLibraryAndReimportAllAssetsManageArtifactsExplicitly`
|
||||
- `AssetImportService_Test.ImportStatusTracksExplicitOperationsAndRefreshCleanup`
|
||||
- `ResourceManager_Test.ReimportProjectAssetBuildsArtifactForSelectedPath`
|
||||
- `editor_tests`:
|
||||
- `EditorActionRoutingTest.ProjectCommandsExposeAssetCacheMaintenanceActions`
|
||||
- `EditorActionRoutingTest.ProjectCommandsReimportSelectedAssetAndClearLibraryDriveAssetCache`
|
||||
- `EditorActionRoutingTest.ProjectCommandsReportWhenScriptAssembliesCanBeRebuilt`
|
||||
- `components_tests`:
|
||||
- `MeshRendererComponent_Test.SerializeAndDeserializeLoadsProjectMaterialByAssetRef`
|
||||
- `MeshRendererComponent_Test.DeferredSceneDeserializeLoadsProjectMaterialAsync`
|
||||
- `material_tests`:46/46 通过
|
||||
- `mesh_tests`:33/33 通过
|
||||
- `scene_tests`:
|
||||
- `Scene_ProjectSample.DeferredLoadBackpackSceneEventuallyRestoresBackpackMesh`
|
||||
- `Scene_ProjectSample.DeferredLoadBackpackSceneEventuallyProducesVisibleRenderItems`
|
||||
- `XCEditor` Release 已成功编译
|
||||
|
||||
旧方案文档已经归档到:
|
||||
|
||||
- `docs/plan/used/Unity式Library资产导入与缓存系统重构方案.md`
|
||||
|
||||
归档原因很简单:
|
||||
|
||||
- 旧文档解决的是“从没有 Library,到建立 Library 基础设施”的问题。
|
||||
- 现在的问题已经不是“要不要做 Library”,而是“怎么把当前这套半过渡、半正式的实现收成一套干净的正式系统”。
|
||||
|
||||
本轮收口以以下前提为准:
|
||||
|
||||
- 只服务当前 `project` 这一个项目。
|
||||
- 不兼容旧版本 scene / component 资产引用格式。
|
||||
- 不再提供旧格式迁移工具。
|
||||
- 可以直接改写 `project` 下现有场景和资源源文件。
|
||||
- 目标不是继续堆补丁,而是形成一套边界清晰、行为稳定、可长期维护的正式实现。
|
||||
|
||||
---
|
||||
|
||||
## 1. 当前收口基线
|
||||
|
||||
当前系统已经具备以下基础,这些不是本轮要推倒重来,而是本轮收口的起点:
|
||||
|
||||
- 已有 Unity 风格的 `Library` 目录结构:
|
||||
- `Library/SourceAssetDB`
|
||||
- `Library/ArtifactDB`
|
||||
- `Library/Artifacts`
|
||||
- 已有 `.meta + AssetGUID` 机制,项目资产已经具备稳定身份。
|
||||
- 已有 `AssetRef` 结构,运行时已经可以通过 `AssetRef` 回查项目资产。
|
||||
- 已有纹理、材质、模型 artifact:
|
||||
- `xctex`
|
||||
- `xcmat`
|
||||
- `xcmesh`
|
||||
- 已有 `AssetImportService`,用于承接导入与 artifact 保证逻辑。
|
||||
- 已有 `ProjectAssetIndex`,用于承接项目资产路径与 `AssetRef` 快照索引。
|
||||
- `ResourceManager` 已不再直接承担全部导入数据库职责,而是开始回到运行时调度器角色。
|
||||
- scene 打开链路已经接入 deferred restore,`MeshFilterComponent` / `MeshRendererComponent` 能在反序列化后异步恢复项目资源。
|
||||
- 当前 `project/Assets/Scenes/Main.xc`、`project/Assets/Scenes/Backpack.xc` 已经具备 `AssetRef` 版本数据,可作为最终格式收口的直接修改对象。
|
||||
|
||||
当前真正没有收口的,不是“功能不存在”,而是下面这三类问题还在:
|
||||
|
||||
- 还保留着旧格式兼容和双写逻辑。
|
||||
- 组件 / scene / editor 工具链里还残留过渡期代码。
|
||||
- 材质与贴图恢复仍不够轻,缓存命中后仍有额外同步成本。
|
||||
|
||||
---
|
||||
|
||||
## 2. 本轮收口的核心原则
|
||||
|
||||
### 2.1 不保留旧版本兼容
|
||||
|
||||
这是本轮与上一轮最大的区别。
|
||||
|
||||
本轮明确不做以下事情:
|
||||
|
||||
- 不兼容历史 `mesh=` / `materials=` 场景字段。
|
||||
- 不兼容“项目资产仍按普通文件路径序列化”的旧格式。
|
||||
- 不保留 `path + AssetRef` 双写作为长期状态。
|
||||
- 不保留 `Migrate Scene AssetRefs` 之类的迁移工具与菜单。
|
||||
|
||||
允许保留的只有两类稳定引用:
|
||||
|
||||
- `AssetRef`
|
||||
- 用于 `project/Assets` 下的正式项目资产。
|
||||
- `builtin://...`
|
||||
- 用于内置几何体、内置默认材质等虚拟内置资源。
|
||||
|
||||
这里的 `builtin://` 不是旧版本兼容,而是引擎内部稳定资源协议,可以继续保留。
|
||||
|
||||
### 2.2 只对当前项目做干净落地
|
||||
|
||||
因为当前只服务一个项目,所以这轮不需要为了“以后可能导入旧项目”保留复杂迁移链路。
|
||||
|
||||
本轮允许直接做以下事情:
|
||||
|
||||
- 直接改写 `project/Assets/Scenes/*.xc`
|
||||
- 直接删除旧序列化字段的读写逻辑
|
||||
- 直接删除旧迁移命令、菜单、报告结构
|
||||
- 直接调整测试数据到最终格式
|
||||
|
||||
### 2.3 运行时只负责“用缓存”,不负责“解释历史”
|
||||
|
||||
收口完成后,运行时层要满足:
|
||||
|
||||
- scene 反序列化只恢复最终格式数据
|
||||
- `ResourceManager` 只做运行时缓存、异步调度、artifact 读取入口
|
||||
- 导入与索引职责留在 `AssetImportService` / `ProjectAssetIndex`
|
||||
- 不再在运行时主链路里背负旧协议兼容判断
|
||||
|
||||
### 2.4 收口优先级高于“继续设计更大系统”
|
||||
|
||||
本轮目标是把现有系统收干净,不追求继续扩成更庞大的框架。
|
||||
|
||||
因此本轮只做两件事:
|
||||
|
||||
- 删除过渡态
|
||||
- 补齐正式版闭环
|
||||
|
||||
不在本轮追求:
|
||||
|
||||
- prefab 全面资产管线化
|
||||
- 动画、音频、shader 全类型导入器
|
||||
- 远程缓存
|
||||
- 多项目兼容框架
|
||||
- 一步到位把所有内部类都拆到最细
|
||||
|
||||
---
|
||||
|
||||
## 3. 收口后的目标形态
|
||||
|
||||
### 3.1 最终数据协议
|
||||
|
||||
收口后,scene / component 的资产引用协议定为:
|
||||
|
||||
- 项目 mesh:只写 `meshRef`
|
||||
- 项目 material:只写 `materialRefs`
|
||||
- 内置 mesh:写 `meshPath=builtin://...`
|
||||
- 内置 material:写 `materialPaths=builtin://...`
|
||||
|
||||
不再允许以下状态作为正式协议存在:
|
||||
|
||||
- 项目资产依旧只存普通文件路径
|
||||
- 项目资产同时写路径和 `AssetRef`
|
||||
- 反序列化时优先猜测旧字段再兜底
|
||||
|
||||
### 3.2 最终运行时边界
|
||||
|
||||
收口后各层职责如下:
|
||||
|
||||
- `AssetImportService`
|
||||
- 工程扫描
|
||||
- `.meta` 管理
|
||||
- SourceAssetDB / ArtifactDB 维护
|
||||
- `EnsureArtifact`
|
||||
- `Refresh`
|
||||
- `Reimport` / `Clear Library` 入口
|
||||
- `ProjectAssetIndex`
|
||||
- 项目资产路径快照
|
||||
- `AssetRef <-> 项目路径` 映射
|
||||
- 项目资产查找缓存
|
||||
- `ResourceManager`
|
||||
- runtime object cache
|
||||
- async load coalescing
|
||||
- artifact runtime load dispatch
|
||||
- deferred scene load 控制
|
||||
- Component / Scene
|
||||
- 只保存最终资产引用
|
||||
- 不承担旧协议迁移职责
|
||||
|
||||
### 3.3 最终用户行为
|
||||
|
||||
收口后应达到以下体验:
|
||||
|
||||
- 第一次导入可能慢,但之后再打开同一个 scene,不应再同步重跑原始 `obj/png/jpg` 导入。
|
||||
- 打开含有大型 OBJ 的 scene 时,不应长时间卡死 editor 主窗口。
|
||||
- 命中 artifact 后,mesh/material 恢复应尽量走异步路径。
|
||||
- 关闭 editor 再打开后,项目资产引用应稳定恢复,不出现“模型丢失、材质丢失、内置 sphere 丢失”这类状态回退问题。
|
||||
- 用户能明确知道当前是“命中缓存”还是“正在导入/重建缓存”。
|
||||
|
||||
---
|
||||
|
||||
## 4. 本轮必须删除的过渡态
|
||||
|
||||
这部分是收口计划的关键,不删掉这些内容,系统就始终处于过渡状态。
|
||||
|
||||
### 4.1 删除旧序列化兼容
|
||||
|
||||
目标:
|
||||
|
||||
- 删除 `MeshFilterComponent` 对旧 `mesh=` 字段的长期兼容读取。
|
||||
- 删除 `MeshRendererComponent` 对旧 `materials=` 字段的长期兼容读取。
|
||||
- 删除“项目资产 path 与 `AssetRef` 双写”的长期行为。
|
||||
|
||||
允许保留:
|
||||
|
||||
- 对 `builtin://` 的显式处理。
|
||||
|
||||
禁止保留:
|
||||
|
||||
- “先读 path,不行再猜 `AssetRef`”
|
||||
- “为了兼容老场景继续支持项目文件路径”
|
||||
|
||||
### 4.2 删除场景迁移工具
|
||||
|
||||
以下过渡期工具应整体移除:
|
||||
|
||||
- `Migrate Scene AssetRefs` 菜单项
|
||||
- 对应 action / command / project manager migration report
|
||||
- 专门为旧场景迁移设计的 editor 流程
|
||||
|
||||
原因:
|
||||
|
||||
- 当前项目只有一个,已有 scene 可以直接重写。
|
||||
- 继续保留迁移工具,只会让新系统一直背着旧协议。
|
||||
|
||||
### 4.3 删除长期双轨测试
|
||||
|
||||
需要同步清理测试中的过渡态假设:
|
||||
|
||||
- 旧格式 scene 兼容测试
|
||||
- 双写格式测试
|
||||
- 迁移工具测试
|
||||
|
||||
替换成正式版测试:
|
||||
|
||||
- 最终 scene 协议测试
|
||||
- 关闭 editor 重开后的稳定恢复测试
|
||||
- artifact 命中路径测试
|
||||
- 异步恢复与渲染可见性测试
|
||||
|
||||
---
|
||||
|
||||
## 5. 本轮必须补齐的正式能力
|
||||
|
||||
### 5.1 材质与贴图真正 lazy 化
|
||||
|
||||
当前模型 artifact 虽然已经存在,但材质恢复后仍然容易把关联贴图一起拉进来,导致:
|
||||
|
||||
- 场景虽然不在反序列化阶段阻塞
|
||||
- 但资源真正恢复时仍然偏重
|
||||
|
||||
本轮必须补齐:
|
||||
|
||||
- `xcmat` 成为正式稳定 artifact
|
||||
- `Material` 运行时对象只持有 texture `AssetRef`
|
||||
- texture runtime handle 按槽位、按需解析
|
||||
- mesh 恢复不顺手触发整套材质贴图同步加载
|
||||
|
||||
这是“缓存命中了但还是觉得重”的核心收口项。
|
||||
|
||||
### 5.2 明确导入与运行时边界
|
||||
|
||||
虽然最近已经引入:
|
||||
|
||||
- `AssetImportService`
|
||||
- `ProjectAssetIndex`
|
||||
|
||||
但本轮要进一步明确:
|
||||
|
||||
- `ResourceManager` 外部不再暴露旧式导入心智
|
||||
- 项目资产查找统一经过 `ProjectAssetIndex`
|
||||
- artifact 生成统一经过 `AssetImportService`
|
||||
- `AssetDatabase` 作为底层实现细节继续收口到 service 后面
|
||||
|
||||
本轮的目标不是一定把 `AssetDatabase` 拆成三个类,而是先把“对外边界”收干净。
|
||||
|
||||
也就是说,本轮要求:
|
||||
|
||||
- 类内可暂时还偏胖
|
||||
- 但对外职责必须已经清晰
|
||||
|
||||
### 5.3 缓存运维闭环
|
||||
|
||||
正式版至少要有以下最小运维能力:
|
||||
|
||||
- 单资源 Reimport
|
||||
- `Reimport All`
|
||||
- `Clear Library`
|
||||
- 项目启动时检查并重建缺失缓存
|
||||
- 删除源资源后识别 orphan artifact
|
||||
|
||||
如果这些没有,系统虽然能工作,但一旦缓存脏掉就难以恢复,仍然不算收口。
|
||||
|
||||
### 5.4 可观测性闭环
|
||||
|
||||
本轮至少要做到用户能看见:
|
||||
|
||||
- 当前资源是命中 artifact 还是触发重导入
|
||||
- 正在导入哪个资源
|
||||
- 导入失败原因
|
||||
- scene 正在等待哪些资源恢复
|
||||
|
||||
不要求本轮先做完整面板,但至少要把日志、状态文案、必要的调试输出整理成稳定可用的最小版本。
|
||||
|
||||
---
|
||||
|
||||
## 6. 实施阶段
|
||||
|
||||
## 阶段 A:协议定稿与旧兼容删除
|
||||
|
||||
### 目标
|
||||
|
||||
把当前半兼容、半正式的 scene / component 数据协议收成最终格式。
|
||||
|
||||
### 任务
|
||||
|
||||
- 改 `MeshFilterComponent`:
|
||||
- 项目资产只写 `meshRef`
|
||||
- 只对 `builtin://` 保留 `meshPath`
|
||||
- 删除旧 `mesh=` 历史兼容读取
|
||||
- 改 `MeshRendererComponent`:
|
||||
- 项目资产只写 `materialRefs`
|
||||
- 只对 `builtin://` 保留 `materialPaths`
|
||||
- 删除旧 `materials=` 历史兼容读取
|
||||
- 直接改写 `project/Assets/Scenes/Main.xc`
|
||||
- 直接改写 `project/Assets/Scenes/Backpack.xc`
|
||||
- 如果项目里还有其他 scene / snapshot / prefab 使用旧项目资产路径,一并直接改成最终格式
|
||||
|
||||
### 同步删除
|
||||
|
||||
- `Migrate Scene AssetRefs` action
|
||||
- `ProjectCommands` 中对应 migration command
|
||||
- `ProjectManager` 中对应 migration report / migration logic
|
||||
- 相关测试
|
||||
|
||||
### 阶段完成标准
|
||||
|
||||
- 项目场景中不再存在旧项目资产路径协议
|
||||
- engine/editor 中不再存在迁移工具入口
|
||||
- 组件反序列化代码只处理最终协议与 builtin 协议
|
||||
|
||||
## 阶段 B:导入与缓存边界收口
|
||||
|
||||
### 目标
|
||||
|
||||
让 `Library` 系统对外呈现为一套明确的正式接口,而不是几个类拼在一起的过渡实现。
|
||||
|
||||
### 任务
|
||||
|
||||
- 把项目资产索引访问统一走 `ProjectAssetIndex`
|
||||
- 把 artifact 生成与保证统一走 `AssetImportService`
|
||||
- 收敛 `ResourceManager` 中剩余的导入数据库耦合
|
||||
- 梳理 `AssetDatabase` 内部接口,限制它作为 service 内部实现使用
|
||||
- 增加明确的 `Refresh / Reimport / Clear Library` 入口
|
||||
|
||||
### 阶段完成标准
|
||||
|
||||
- editor / runtime 外部调用时,心智模型已经稳定为:
|
||||
- 找项目资产:`ProjectAssetIndex`
|
||||
- 产出或校验 artifact:`AssetImportService`
|
||||
- 取 runtime object:`ResourceManager`
|
||||
|
||||
## 阶段 C:性能闭环
|
||||
|
||||
### 目标
|
||||
|
||||
把“看起来已经异步,但恢复仍然偏重”的成本继续压下去。
|
||||
|
||||
### 任务
|
||||
|
||||
- 材质贴图 lazy resolve
|
||||
- 减少 mesh 恢复时顺手加载整套关联资源
|
||||
- 校验首次导入、二次打开、关闭重开三种路径的时间差异
|
||||
- 清理仍可能在主线程触发的大锁与同步等待点
|
||||
- 必要时加入轻量 placeholder / loading state 文案
|
||||
|
||||
### 阶段完成标准
|
||||
|
||||
- 含 OBJ 的 scene 再次打开时,editor 主窗口不出现长时间假死
|
||||
- artifact 命中时恢复成本显著低于首次导入
|
||||
- 关闭 editor 重开后的恢复链路仍然稳定
|
||||
|
||||
## 阶段 D:最小工具闭环
|
||||
|
||||
### 目标
|
||||
|
||||
把这套系统变成“可维护”的,而不是只能靠调试日志救火。
|
||||
|
||||
### 任务
|
||||
|
||||
- 已完成:增加 `Reimport Asset`
|
||||
- 已完成:增加 `Reimport All`
|
||||
- 已完成:增加 `Clear Library`
|
||||
- 已完成:增加最小导入状态输出
|
||||
- 已完成:增加 orphan artifact 清理
|
||||
|
||||
### 阶段完成标准
|
||||
|
||||
- 用户可以主动重建缓存
|
||||
- 缓存脏掉时不需要手工删文件再碰运气
|
||||
- 导入失败时能直接看到原因
|
||||
|
||||
---
|
||||
|
||||
## 7. 验收标准
|
||||
|
||||
本轮收口完成,必须同时满足以下条件:
|
||||
|
||||
### 7.1 协议层
|
||||
|
||||
- 项目资产引用正式统一为 `AssetRef`
|
||||
- 不再保留旧 scene / component 项目资产路径兼容协议
|
||||
- 不再保留迁移工具
|
||||
|
||||
### 7.2 架构层
|
||||
|
||||
- `AssetImportService` / `ProjectAssetIndex` / `ResourceManager` 的对外职责稳定
|
||||
- 运行时不再承担旧协议解释职责
|
||||
- `Library` 已经是正式依赖,而不是临时缓存补丁
|
||||
|
||||
### 7.3 功能层
|
||||
|
||||
- OBJ / 贴图 / 材质二次打开优先命中 artifact
|
||||
- 关闭 editor 重开后项目 scene 能稳定恢复
|
||||
- builtin sphere / cube / default material 不会因为缓存系统而丢失
|
||||
|
||||
### 7.4 性能层
|
||||
|
||||
- 打开含大型 OBJ 的 scene 时不长时间卡死 editor
|
||||
- 二次打开与首次导入的体感耗时有明显区分
|
||||
- 命中 artifact 后不再退回源文件同步导入主路径
|
||||
|
||||
### 7.5 工具层
|
||||
|
||||
- 具备最小 `Reimport / Reimport All / Clear Library` 能力
|
||||
- 有最小可观测性输出
|
||||
|
||||
---
|
||||
|
||||
## 8. 本轮不做的内容
|
||||
|
||||
为了尽快收口,本轮明确不做以下扩展:
|
||||
|
||||
- prefab 全量资产协议翻新
|
||||
- 动画 / 音频 / shader 新 importer
|
||||
- 远程缓存
|
||||
- 多项目历史版本兼容框架
|
||||
- 完整图形化导入面板
|
||||
- 一次性把所有 `AssetDatabase` 内部实现拆到最细
|
||||
|
||||
这些内容后续可以继续做,但不应该阻塞当前正式收口。
|
||||
|
||||
---
|
||||
|
||||
## 9. 推荐执行顺序
|
||||
|
||||
建议按下面顺序推进,避免边做边反复回滚:
|
||||
|
||||
1. 先做阶段 A,直接把项目协议和旧兼容删干净。
|
||||
2. 再做阶段 B,把对外边界稳定下来。
|
||||
3. 然后做阶段 C,把“缓存命中了但恢复仍然重”的问题收掉。
|
||||
4. 最后做阶段 D,补齐最小运维与可观测性。
|
||||
|
||||
原因是:
|
||||
|
||||
- 不先删旧兼容,后面所有逻辑都要双轨维护。
|
||||
- 不先把边界定清,性能问题会一直和历史兼容问题缠在一起。
|
||||
- 不先把主链路收稳,工具做出来也只是给过渡态续命。
|
||||
|
||||
---
|
||||
|
||||
## 10. 本轮涉及的主要代码范围
|
||||
|
||||
本轮预计重点落在以下文件:
|
||||
|
||||
- `engine/src/Components/MeshFilterComponent.cpp`
|
||||
- `engine/src/Components/MeshRendererComponent.cpp`
|
||||
- `engine/include/XCEngine/Core/Asset/ResourceManager.h`
|
||||
- `engine/src/Core/Asset/ResourceManager.cpp`
|
||||
- `engine/include/XCEngine/Core/Asset/AssetImportService.h`
|
||||
- `engine/src/Core/Asset/AssetImportService.cpp`
|
||||
- `engine/include/XCEngine/Core/Asset/ProjectAssetIndex.h`
|
||||
- `engine/src/Core/Asset/ProjectAssetIndex.cpp`
|
||||
- `engine/include/XCEngine/Core/Asset/AssetDatabase.h`
|
||||
- `engine/src/Core/Asset/AssetDatabase.cpp`
|
||||
- `editor/src/Managers/ProjectManager.cpp`
|
||||
- `editor/src/Commands/ProjectCommands.h`
|
||||
- `editor/src/Actions/EditorActions.h`
|
||||
- `editor/src/Actions/MainMenuActionRouter.h`
|
||||
- `tests/core/Asset/test_resource_manager.cpp`
|
||||
- `tests/Components/test_mesh_render_components.cpp`
|
||||
- `tests/Scene/test_scene.cpp`
|
||||
- `project/Assets/Scenes/Main.xc`
|
||||
- `project/Assets/Scenes/Backpack.xc`
|
||||
|
||||
---
|
||||
|
||||
## 11. 一句话结论
|
||||
|
||||
从这一刻开始,这个模块的目标不再是“继续兼容旧系统”,而是:
|
||||
|
||||
把当前已经跑起来的 `Library`、artifact、`AssetRef`、异步恢复链路,收成一套只服务当前项目、无旧包袱、可稳定重开的正式资产系统。
|
||||
567
docs/used/Material Inspector与Shader属性面板收口计划_2026-04-07.md
Normal file
567
docs/used/Material Inspector与Shader属性面板收口计划_2026-04-07.md
Normal file
@@ -0,0 +1,567 @@
|
||||
# Material Inspector与Shader属性面板收口计划
|
||||
|
||||
日期:2026-04-07
|
||||
|
||||
## 1. 背景
|
||||
|
||||
当前 Rendering / Shader / Material 主线已经基本建立起正式架构:
|
||||
|
||||
- Shader 侧已经具备统一的 authoring/schema 能力。
|
||||
- Material 运行时与 artifact 路径已经逐步从旧兼容逻辑中收口。
|
||||
- Editor 中的 Material Inspector 仍然没有完全切换到“由 Shader schema 驱动”的正式工作流。
|
||||
|
||||
当前最突出的实际问题有两类:
|
||||
|
||||
1. Material 选择 Shader 后,Shader 中声明的属性没有被正式暴露到 Inspector 面板上。
|
||||
2. Material 面板上还残留了一些历史字段或临时 UI,用户无法清晰判断哪些是正式能力,哪些只是过渡产物。
|
||||
|
||||
此外,当前工程条件已经允许做更彻底的清理:
|
||||
|
||||
- `project/` 中旧材质资产可直接编辑。
|
||||
- 当前不存在必须长期兼容的历史材质资产包袱。
|
||||
|
||||
因此,这一阶段的目标不是“继续兼容旧面板”,而是把 Material 编辑链路彻底切换到正式路径,并为后续 Shader/Material 编辑器扩展打好基础。
|
||||
|
||||
## 2. 本阶段目标
|
||||
|
||||
本阶段要完成以下目标:
|
||||
|
||||
1. 让 Material Inspector 成为 Shader schema 驱动的正式编辑入口。
|
||||
2. 让材质面板只暴露当前正式架构中的概念,不再混入旧字段和误导性配置。
|
||||
3. 保证 Editor 面板、运行时 `Material`、源资产、artifact、reimport 之间的数据一致性。
|
||||
4. 用单测和必要的编辑器验证把这条链路收口,而不是停留在“能显示”层面。
|
||||
|
||||
## 3. 不在本阶段处理的内容
|
||||
|
||||
以下内容不属于本阶段主目标,避免范围失控:
|
||||
|
||||
- 自定义 Material Drawer 系统。
|
||||
- Shader Graph / 节点式材质编辑器。
|
||||
- 面向美术工作流的复杂 Material 预设库。
|
||||
- SRP 层级的材质检查器定制机制。
|
||||
- 完整的 Shader GUI 仿 Unity 高级扩展体系。
|
||||
|
||||
这些能力后续可以做,但必须建立在当前正式链路已经稳定收口的前提上。
|
||||
|
||||
## 4. 当前已确认的问题
|
||||
|
||||
### 4.1 Inspector 没有正式反射 Shader 属性
|
||||
|
||||
当前 Material Inspector 还没有完整读取 Shader schema 并按类型生成属性控件,导致:
|
||||
|
||||
- Shader 中声明的属性无法完整暴露。
|
||||
- 用户无法直接编辑当前材质真正生效的参数。
|
||||
- 材质默认值、覆盖值、纹理槽与资源引用状态之间关系不清晰。
|
||||
|
||||
### 4.2 材质面板仍存在历史路径残留
|
||||
|
||||
之前材质层面曾承担过一些本不应由材质承担的职责,例如:
|
||||
|
||||
- 材质自己选择 builtin pass。
|
||||
- Inspector 里出现与当前正式架构不一致的旧字段。
|
||||
|
||||
这类逻辑已经开始清理,但 Editor 面板仍需同步彻底收口。
|
||||
|
||||
### 4.3 Editor 与运行时 Material 状态可能脱节
|
||||
|
||||
如果面板的编辑状态不是直接围绕正式 `Material` 数据模型建立,就容易出现:
|
||||
|
||||
- Inspector 显示值与运行时实际值不一致。
|
||||
- 资源重载后 UI 状态失真。
|
||||
- artifact / reimport 后材质参数丢失或回退异常。
|
||||
|
||||
### 4.4 缺少围绕正式工作流的测试闭环
|
||||
|
||||
仅靠手工点 Inspector 验证不足以支撑后续迭代。必须补足以下覆盖:
|
||||
|
||||
- Shader 切换后属性集合重建。
|
||||
- 默认值与显式覆盖值的切换。
|
||||
- Texture 属性与资源引用链路。
|
||||
- Keyword 与 Render State 的持久化。
|
||||
- artifact/reimport 后数据一致性。
|
||||
|
||||
## 5. 设计原则
|
||||
|
||||
本阶段严格遵循以下原则:
|
||||
|
||||
### 5.1 Shader 定义什么,Material 就暴露什么
|
||||
|
||||
Material 不是独立定义属性结构的地方。属性结构必须由 Shader schema 决定,Inspector 只是将其可视化并允许编辑。
|
||||
|
||||
### 5.2 Material 只承载实例数据,不承载管线选择策略
|
||||
|
||||
材质应承载:
|
||||
|
||||
- Shader 引用
|
||||
- Shader schema 对应的属性值
|
||||
- Keyword 状态
|
||||
- 合法的 render state 覆盖
|
||||
|
||||
材质不应再承载:
|
||||
|
||||
- 独立指定 builtin pass 的旧路径
|
||||
- 与 Shader metadata 冲突的临时策略字段
|
||||
|
||||
### 5.3 Editor 不发明第二套数据模型
|
||||
|
||||
Inspector 的中间态必须服务于正式数据模型,而不是绕开 `Material` 自己维护一套平行逻辑。
|
||||
|
||||
### 5.4 面板必须可验证
|
||||
|
||||
每一步改动都必须能通过测试或明确的编辑器验证闭环证明正确,不接受只靠目测“看起来差不多”。
|
||||
|
||||
## 6. 分阶段执行计划
|
||||
|
||||
## Phase 1:现状审查与残留路径清点
|
||||
|
||||
### 目标
|
||||
|
||||
彻底梳理当前 Material Inspector、Material 资源、Shader schema、artifact 序列化之间的实际数据流。
|
||||
|
||||
### 任务
|
||||
|
||||
- 审查 `InspectorPanel` 当前 Material 面板的数据来源和写回路径。
|
||||
- 审查 `Material` 当前正式字段与历史遗留字段。
|
||||
- 审查 `MaterialLoader`、`AssetDatabase`、artifact schema 当前是否仍保留不必要兼容路径。
|
||||
- 识别 Material 面板中哪些字段是正式路径,哪些属于旧方案残留。
|
||||
|
||||
### 完成标准
|
||||
|
||||
- 列清楚当前正式数据流。
|
||||
- 列清楚必须删除的旧字段/旧 UI。
|
||||
- 列清楚缺失的 schema 反射入口。
|
||||
|
||||
## Phase 2:Material Inspector 数据模型收口
|
||||
|
||||
### 目标
|
||||
|
||||
让 Material 面板的数据模型只围绕正式架构组织。
|
||||
|
||||
### 任务
|
||||
|
||||
- 移除 Material 层面的旧 pass 选择 UI 与残余兼容路径。
|
||||
- 整理 Inspector 内部状态结构,只保留:
|
||||
- Shader 资源引用
|
||||
- Shader schema 对应属性
|
||||
- Keywords
|
||||
- Render Queue / Render State
|
||||
- Tags(仅保留当前正式允许暴露的部分)
|
||||
- 避免 Inspector 保存与运行时 `Material` 不一致的冗余字段。
|
||||
|
||||
### 完成标准
|
||||
|
||||
- 面板字段与正式 `Material` 模型一一对应。
|
||||
- 旧字段彻底不再出现在材质编辑界面和保存链路中。
|
||||
|
||||
## Phase 3:Shader schema 驱动的属性面板生成
|
||||
|
||||
### 目标
|
||||
|
||||
Material Inspector 能基于 Shader schema 动态生成属性编辑 UI。
|
||||
|
||||
### 任务
|
||||
|
||||
- 读取 Shader 声明的属性定义与默认值。
|
||||
- 按属性类型渲染控件:
|
||||
- `float`
|
||||
- `int`
|
||||
- `bool`
|
||||
- `float2/3/4`
|
||||
- `texture`
|
||||
- 正确显示每个属性的:
|
||||
- 属性名
|
||||
- 显示名
|
||||
- 默认值
|
||||
- 当前覆盖值
|
||||
- 纹理槽绑定状态
|
||||
- 资源引用路径/AssetRef 状态
|
||||
- 明确“未覆盖时使用 Shader 默认值”的表现形式。
|
||||
|
||||
### 完成标准
|
||||
|
||||
- 选定 Shader 后,Inspector 中能稳定暴露该 Shader 的正式属性集合。
|
||||
- 面板能正确编辑并持久化这些属性。
|
||||
|
||||
## Phase 4:Editor 与运行时一致性收口
|
||||
|
||||
### 目标
|
||||
|
||||
保证 Material Inspector 编辑结果与运行时 `Material`、artifact、reimport 行为一致。
|
||||
|
||||
### 任务
|
||||
|
||||
- 对齐 Inspector 写回逻辑与 `Material` 正式 API。
|
||||
- 验证 Shader 切换时属性重建、默认值回退、无效属性清理。
|
||||
- 验证纹理属性在源资产、artifact、异步资源加载中的一致性。
|
||||
- 验证关键词与 render state 在 reload/reimport 后不丢失。
|
||||
|
||||
### 完成标准
|
||||
|
||||
- Inspector 改动能被运行时正确读取。
|
||||
- Reload / Reimport / Artifact Round Trip 后材质数据不漂移。
|
||||
|
||||
## Phase 5:测试补齐与阶段验收
|
||||
|
||||
### 目标
|
||||
|
||||
为正式工作流建立可持续回归验证。
|
||||
|
||||
### 任务
|
||||
|
||||
- 补充或更新 `material_tests`。
|
||||
- 补充或更新 `asset_tests`。
|
||||
- 若材质解析或 builtin pass 匹配受影响,补充必要的 `rendering_unit_tests`。
|
||||
- 重新编译 `XCEditor`,执行人工冒烟验证。
|
||||
|
||||
### 验收项
|
||||
|
||||
- `material_tests` 全绿。
|
||||
- `asset_tests` 全绿。
|
||||
- 必要的 `rendering_unit_tests` 全绿。
|
||||
- `XCEditor` 编译通过。
|
||||
- Material Inspector 中 Shader 属性暴露、编辑、保存、重载行为正确。
|
||||
|
||||
## 7. 预期交付结果
|
||||
|
||||
本阶段完成后,工程应达到以下状态:
|
||||
|
||||
1. Material 面板正式切换为 Shader schema 驱动。
|
||||
2. 材质不再承担旧 pass 选择职责。
|
||||
3. Inspector 中只剩下当前正式架构允许存在的字段。
|
||||
4. 材质属性、纹理槽、关键词、render state 都能稳定编辑并正确持久化。
|
||||
5. Shader / Material 后续扩展拥有清晰入口,不再建立在旧兼容逻辑之上。
|
||||
|
||||
## 8. 风险与注意事项
|
||||
|
||||
### 8.1 Shader 切换会触发属性重建
|
||||
|
||||
必须定义清楚以下规则:
|
||||
|
||||
- 与新 Shader schema 匹配的属性如何保留。
|
||||
- 不匹配的旧属性如何移除。
|
||||
- 默认值何时回退,何时保留用户覆盖。
|
||||
|
||||
### 8.2 Texture 属性不仅是 UI 问题
|
||||
|
||||
Texture 属性同时涉及:
|
||||
|
||||
- Inspector 显示
|
||||
- AssetRef
|
||||
- 资源路径
|
||||
- artifact 存储
|
||||
- 延迟加载
|
||||
|
||||
因此不能只改面板显示,必须连同资源路径一起验证。
|
||||
|
||||
### 8.3 Render State 需要坚持“正式最小集”
|
||||
|
||||
Material 面板不应再次演化成随意堆字段的临时入口。所有 render state 暴露都必须建立在当前正式支持的能力之上。
|
||||
|
||||
## 9. 建议执行顺序
|
||||
|
||||
建议严格按以下顺序落地:
|
||||
|
||||
1. 先完成旧字段与旧路径清点。
|
||||
2. 再重构 Inspector 数据模型。
|
||||
3. 再接 Shader schema 驱动属性 UI。
|
||||
4. 再收口 Editor 与运行时一致性。
|
||||
5. 最后统一补测与验收。
|
||||
|
||||
不能反过来先堆 UI,再回头补数据模型,否则很容易再次生成新的临时方案。
|
||||
|
||||
## 10. 阶段结论
|
||||
|
||||
当前最应该推进的不是继续增加 Material 编辑功能花样,而是把 Material Inspector 这条正式链路做对、做稳、做干净。
|
||||
|
||||
只要这一阶段收口完成,后续无论是:
|
||||
|
||||
- 更完整的 Shader authoring
|
||||
- Material 默认面板
|
||||
- 针对 Renderer/SRP 的材质体系扩展
|
||||
- 更接近 Unity 的 Shader/Material 编辑工作流
|
||||
|
||||
都会建立在清晰、稳定、可验证的基础之上。
|
||||
|
||||
## 11. Phase 1 审查结果
|
||||
|
||||
状态:已完成
|
||||
|
||||
本阶段已对当前 Material Inspector、运行时 `Material`、Shader schema、material source/artifact 路径进行了实际代码审查,结论如下。
|
||||
|
||||
### 11.1 当前 Inspector 数据模型先天不完整
|
||||
|
||||
当前 `InspectorPanel::MaterialAssetState` 只维护了以下内容:
|
||||
|
||||
- `shaderPath`
|
||||
- `renderQueue`
|
||||
- `renderState`
|
||||
- `tags`
|
||||
|
||||
它没有正式承载以下关键数据:
|
||||
|
||||
- Shader schema 属性列表
|
||||
- 材质属性当前值
|
||||
- 纹理槽与贴图引用
|
||||
- 关键词状态
|
||||
- Render State Override 开关本身
|
||||
|
||||
这意味着当前 Inspector 不是“少画了几个控件”,而是其内部状态模型本身就无法表示正式的材质编辑数据。
|
||||
|
||||
### 11.2 当前 Inspector 保存链路会丢失材质的正式内容
|
||||
|
||||
当前 `BuildMaterialAssetFileText()` 仅写出:
|
||||
|
||||
- `shader`
|
||||
- `renderQueue`
|
||||
- `tags`
|
||||
- `renderState`
|
||||
|
||||
它不会写出:
|
||||
|
||||
- `properties`
|
||||
- `textures`
|
||||
- `keywords`
|
||||
|
||||
因此,只要一个材质已经拥有 Shader 属性、纹理槽或关键词,若用户通过当前 Inspector 保存一次,该材质源文件就可能被覆盖成一个严重简化后的版本,导致正式材质数据丢失。
|
||||
|
||||
### 11.3 当前 Inspector 的实时写回同样不完整
|
||||
|
||||
当前 `ApplyResolvedMaterialStateToResource()` 仅把面板状态写回到运行时 `Material` 的以下部分:
|
||||
|
||||
- `SetShader`
|
||||
- `SetRenderQueue`
|
||||
- `SetRenderState`
|
||||
- `ClearTags` / `SetTag`
|
||||
|
||||
它不会写回:
|
||||
|
||||
- Shader schema 属性值
|
||||
- 纹理绑定
|
||||
- 关键词
|
||||
|
||||
因此 Inspector 当前即使支持继续加控件,如果不先重构数据模型,运行时同步仍然会不完整。
|
||||
|
||||
### 11.4 Render State Override 当前没有被正式建模
|
||||
|
||||
运行时 `Material::SetRenderState()` 会自动把 `HasRenderStateOverride` 置为 `true`。
|
||||
|
||||
但当前 Inspector:
|
||||
|
||||
- 没有暴露 “是否启用 Render State Override”
|
||||
- 保存时始终写出完整 `renderState`
|
||||
- 应用时始终调用 `SetRenderState`
|
||||
|
||||
这意味着只要用户通过当前材质面板保存,材质就会被强制推进到显式 Render State Override 路径。这个行为不符合正式设计,必须在下一阶段一起修正。
|
||||
|
||||
### 11.5 运行时底层能力其实已经基本齐备
|
||||
|
||||
当前 runtime/resource 层已经具备正式所需的大部分能力:
|
||||
|
||||
- `ShaderPropertyDesc` 已包含 `name / displayName / type / defaultValue / semantic`
|
||||
- `Shader` 已提供 `GetProperties()` / `FindProperty()` / keyword declaration 能力
|
||||
- `Material` 已提供完整的 `SetFloat/SetInt/SetBool/SetTexture...`
|
||||
- `Material` 已支持 Shader schema 默认值同步
|
||||
- `MaterialLoader` 已支持解析 `properties / textures / keywords / tags / renderState`
|
||||
- material artifact 当前已支持这些正式数据的持久化
|
||||
|
||||
也就是说,当前问题的主要矛盾不在资源系统,而在 Editor 侧没有接入正式模型。
|
||||
|
||||
### 11.6 当前阶段的根本性结论
|
||||
|
||||
下一阶段不能直接在现有材质面板上继续堆控件。
|
||||
|
||||
必须先完成:
|
||||
|
||||
1. `MaterialAssetState` 的正式重构
|
||||
2. Save/Reload/Apply 链路对 `properties / textures / keywords / renderState override` 的建模
|
||||
3. Inspector 与运行时 `Material` 之间的一致性重建
|
||||
|
||||
只有先做完这些,后续的 Shader schema 驱动属性 UI 才不会继续建立在错误基础上。
|
||||
|
||||
### 11.7 Phase 2 的直接执行范围
|
||||
|
||||
基于本阶段审查结果,下一阶段将直接进入以下工作:
|
||||
|
||||
1. 扩展 `MaterialAssetState`,让其正式承载属性、纹理槽、关键词与 render state override。
|
||||
2. 重构 `Populate / Apply / Save / Reload` 这四条关键链路。
|
||||
3. 彻底消除当前“保存一次就丢属性”的结构性问题。
|
||||
|
||||
## 12. Phase 2 执行结果
|
||||
|
||||
状态:已完成
|
||||
|
||||
本阶段已经完成 Material Inspector 数据模型的第一轮正式收口,重点是先把状态模型与保存链路做正确,而不是提前堆属性 UI。
|
||||
|
||||
### 12.1 已完成内容
|
||||
|
||||
- `MaterialAssetState` 已扩展为正式承载:
|
||||
- `keywords`
|
||||
- `properties`
|
||||
- `texture bindings`
|
||||
- `renderState override`
|
||||
- `PopulateMaterialAssetStateFromResource()` 已从运行时 `Material` 同步:
|
||||
- Shader 路径
|
||||
- Render Queue
|
||||
- Render State
|
||||
- Render State Override 标志
|
||||
- Tags
|
||||
- Keywords
|
||||
- Properties / Texture Bindings
|
||||
- `ApplyResolvedMaterialStateToResource()` 已开始完整写回:
|
||||
- Shader
|
||||
- Render Queue
|
||||
- Render State
|
||||
- Render State Override
|
||||
- Tags
|
||||
- Keywords
|
||||
- Properties / Texture Bindings
|
||||
- `BuildMaterialAssetFileText()` 已开始正式写出:
|
||||
- `keywords`
|
||||
- `properties`
|
||||
- `textures`
|
||||
- 仅在启用 override 时才写 `renderState`
|
||||
- Inspector 已增加 `Render State Override` 开关,避免默认把材质强行推进到显式 override 路径。
|
||||
|
||||
### 12.2 本阶段解决的核心问题
|
||||
|
||||
本阶段已经解决了最危险的结构性问题:
|
||||
|
||||
- 当前 Inspector 再保存材质时,不会像之前那样天然丢掉 `properties / textures / keywords`。
|
||||
- Render State 是否为显式 override,已经不再是隐藏副作用,而成为正式状态的一部分。
|
||||
|
||||
### 12.3 本阶段仍未完成的部分
|
||||
|
||||
以下能力还没有在本阶段完成,这是下一阶段的工作重点:
|
||||
|
||||
- 基于 Shader schema 的属性 UI 自动生成
|
||||
- 各属性类型的可视化编辑控件
|
||||
- 默认值/覆盖值的明确表现
|
||||
- 纹理槽的正式资源选择 UI
|
||||
- 关键词与属性在 Inspector 中的可视化编辑
|
||||
|
||||
因此,Phase 2 的性质是“先把材质状态模型与保存链路做对”,而不是“材质面板功能已经完整”。
|
||||
|
||||
## 13. Phase 3 执行结果
|
||||
|
||||
状态:已完成
|
||||
|
||||
本阶段已经开始把正确的材质状态模型真正暴露到 Inspector 上,重点是基于 Shader schema 生成属性面板,并处理 Shader 切换时的状态重建。
|
||||
|
||||
### 13.1 已完成内容
|
||||
|
||||
- Inspector 已新增 `Properties` 区块。
|
||||
- 属性区会基于当前 Shader 的 schema 动态生成,而不是写死字段。
|
||||
- 当前已接入的属性类型包括:
|
||||
- `Float / Range`
|
||||
- `Int`
|
||||
- `Color`
|
||||
- `Vector`
|
||||
- `Texture2D / TextureCube`
|
||||
- Texture 类型已接入资源选择控件,不再只是文本占位。
|
||||
- 每个属性当前会直接显示 Shader 中声明的默认值文本,作为当前参数的基线提示。
|
||||
|
||||
### 13.2 Shader 切换行为已收口
|
||||
|
||||
本阶段同时处理了一个关键一致性问题:
|
||||
|
||||
- 当用户切换 Shader 时,Inspector 会先基于新 Shader schema 重建 `MaterialAssetState`
|
||||
- 能与新 Shader 对齐的同名属性会尽量保留原值
|
||||
- 已不被新 Shader 声明的旧属性不会继续残留在保存结果里
|
||||
- 与新 Shader 不匹配的旧关键词也会被清理
|
||||
|
||||
这样可以避免旧材质属性被继续写回到新 Shader 材质文件中,从而减少生成无效材质源文件的风险。
|
||||
|
||||
### 13.3 本阶段仍未完成的部分
|
||||
|
||||
以下内容还需要后续阶段继续收口:
|
||||
|
||||
- 属性默认值与显式覆盖值的正式“重置/回退”交互
|
||||
- 关键词的可视化编辑 UI
|
||||
- 更完整的属性类型与显示策略细化
|
||||
- 针对 Inspector 材质链路的专门自动化测试
|
||||
|
||||
因此,Phase 3 的完成标准是“Shader schema 驱动的属性面板已经建立起来”,但还不是最终形态。
|
||||
|
||||
## 14. Phase 4 执行结果
|
||||
|
||||
状态:已完成
|
||||
|
||||
本阶段重点处理的是 authoring-state 与 runtime-state 的一致性问题,避免 Inspector 因为单纯从运行时对象反推而破坏材质源文件的语义。
|
||||
|
||||
### 14.1 已完成内容
|
||||
|
||||
- Inspector 现在会回读材质源文件中实际 authored 的:
|
||||
- `properties`
|
||||
- `textures`
|
||||
- `keywords`
|
||||
- `renderState`
|
||||
- 材质状态中已加入“是否需要序列化回源文件”的 authored 标记。
|
||||
- 保存材质时,不再无条件把所有运行时属性都写回源文件。
|
||||
- 对于未在源文件中显式 authored 的属性,当前会继续保持“继承 Shader 默认值”的语义。
|
||||
- 当用户在 Inspector 中修改属性或贴图后,对应项才会被标记为显式 authored 并写回源文件。
|
||||
|
||||
### 14.2 本阶段解决的核心问题
|
||||
|
||||
本阶段解决的是一个架构层面的隐患:
|
||||
|
||||
- 如果只从运行时 `Material` 反推回材质源文件,打开并保存一次材质,就会把 Shader 默认值全部固化进 `.mat`。
|
||||
- 一旦默认值被固化,后续 Shader 默认值再调整,材质就不再继承新的默认值。
|
||||
|
||||
当前这条链路已经收口到更合理的状态:
|
||||
|
||||
- 只有显式 authored 的 override 才会写回
|
||||
- 默认值仍然可以继续作为 Shader 侧的基线被继承
|
||||
|
||||
### 14.3 本阶段仍未完成的部分
|
||||
|
||||
以下内容仍然需要下一阶段继续完成:
|
||||
|
||||
- 针对 Inspector 材质链路的专门自动化测试
|
||||
- 属性“重置到默认值”的正式交互
|
||||
- 关键词的可视化编辑 UI
|
||||
- 更完整的属性类型/显示策略覆盖
|
||||
|
||||
因此,Phase 4 的性质是“先把 authoring 语义做正确”,为最后的测试与收口创造条件。
|
||||
|
||||
## 15. Phase 5 执行结果
|
||||
|
||||
状态:已完成
|
||||
|
||||
本阶段重点不是继续扩材质面板功能,而是把已经形成的正式链路变成“可持续回归验证”的状态,并把测试面收口到 Inspector 实际依赖的核心逻辑上。
|
||||
|
||||
### 15.1 已完成内容
|
||||
|
||||
- 新增 `MaterialInspectorMaterialState` / `MaterialInspectorMaterialStateIO` 辅助模块,承载:
|
||||
- Material Inspector 状态结构
|
||||
- source authored presence 解析
|
||||
- Shader 切换时的属性/关键词重同步
|
||||
- 材质源文件序列化文本生成
|
||||
- 新增 `tests/editor/test_material_inspector_material_state_io.cpp`,覆盖:
|
||||
- authored 属性/纹理/关键词标记识别
|
||||
- Shader 切换时保留兼容 override、清理陈旧字段
|
||||
- 非 authored 默认值不写回源文件
|
||||
- 纹理 override 与 render state override 的正式序列化
|
||||
- `editor_tests` 构建链路已接入上述 helper 与新测试文件。
|
||||
|
||||
### 15.2 已执行验证
|
||||
|
||||
- `cmake --build build --config Debug --target XCEditor -j 8`
|
||||
- `cmake --build build --config Debug --target editor_tests -- /v:minimal`
|
||||
- `build/tests/Resources/Material/Debug/material_tests.exe`
|
||||
- `build/tests/Core/Asset/Debug/asset_tests.exe`
|
||||
- `build/tests/Editor/Debug/editor_tests.exe --gtest_filter=MaterialInspectorMaterialStateIOTest.*`
|
||||
|
||||
验证结果:
|
||||
|
||||
- `XCEditor` 编译通过
|
||||
- `material_tests`:61 / 61 通过
|
||||
- `asset_tests`:56 / 56 通过
|
||||
- `MaterialInspectorMaterialStateIOTest`:4 / 4 通过
|
||||
|
||||
### 15.3 当前剩余风险
|
||||
|
||||
- 全量 `editor_tests.exe` 在顺序执行 `EditorActionRoutingTest.*` 时仍存在既有的共享状态级别挂起现象。
|
||||
- 该挂起并非本次新增的材质面板测试本身触发:
|
||||
- 新增 `MaterialInspectorMaterialStateIOTest` 单独执行通过
|
||||
- `EditorActionRoutingTest.PlayModeAllowsRuntimeSceneUndoRedoButKeepsSceneDocumentCommandsBlocked` 单独执行通过
|
||||
- 因此,本阶段围绕 Material Inspector / Shader 属性面板的测试收口已经完成,但 Editor 其余历史测试链路仍需单独排查。
|
||||
656
docs/used/Renderer下一阶段_ShaderMaterial与Pass体系设计.md
Normal file
656
docs/used/Renderer下一阶段_ShaderMaterial与Pass体系设计.md
Normal file
@@ -0,0 +1,656 @@
|
||||
# Renderer 下一阶段:Shader、Material 与 Pass 体系设计
|
||||
|
||||
日期:`2026-04-02`
|
||||
|
||||
## 1. 阶段判断
|
||||
|
||||
当前 Renderer 阶段已经完成的事情,是把下面这条主链正式接通并收口:
|
||||
|
||||
`RHI -> Rendering -> Editor Scene/Game Viewport`
|
||||
|
||||
当前已经具备:
|
||||
|
||||
- `SceneRenderer -> CameraRenderer -> RenderPipeline` 的主执行边界
|
||||
- scene camera request 组织能力
|
||||
- built-in forward 主几何绘制
|
||||
- `object-id` 渲染与 editor picking
|
||||
- built-in post-process 入口
|
||||
- editor viewport 宿主接入
|
||||
- 对应的 renderer/editor 自动化测试闭环
|
||||
|
||||
这意味着 Renderer 已经不再是“RHI 之上的一堆零散 draw call”,而是已经形成了真实的模块边界。
|
||||
|
||||
但这并不意味着 Renderer 已经进入“可长期扩展”的状态。
|
||||
|
||||
当前阶段的真正短板,不是 render graph,而是:
|
||||
|
||||
- shader 还没有进入正式 renderer 主路径
|
||||
- material 还不是正式 GPU 参数绑定载体
|
||||
- pass contract 还不完整
|
||||
- 三后端虽然都能跑,但 shader authoring 仍是内建硬编码
|
||||
|
||||
所以 Renderer 的下一阶段主线,不应优先做 render graph,而应优先完成:
|
||||
|
||||
- `Shader`
|
||||
- `Material`
|
||||
- `Builtin Pass Contract`
|
||||
- `Renderer-owned Feature Contract`
|
||||
|
||||
---
|
||||
|
||||
## 2. 为什么下一阶段不是 Render Graph
|
||||
|
||||
`render graph` 不是简单优化项,它本质上是更高一层的资源依赖与多 pass 调度框架。
|
||||
|
||||
但当前工程还没有满足它最该承接的前提:
|
||||
|
||||
1. 还没有足够正式的 pass 分类体系
|
||||
2. 还没有正式的 shader / material 执行契约
|
||||
3. editor helper pass 与 runtime pass 还没有统一语义
|
||||
4. 还没有稳定的 renderer feature 输入输出边界
|
||||
|
||||
如果现在直接上 render graph,会出现一个问题:
|
||||
|
||||
- graph 框架先做了
|
||||
- 真正的 shader/material/pass 契约还没收紧
|
||||
- 最后 graph 里承载的还是一批语义松散的临时 pass
|
||||
|
||||
这会让架构“看起来高级”,但基础层仍然不稳。
|
||||
|
||||
因此下一阶段正确顺序应当是:
|
||||
|
||||
1. 先收紧 shader/material/pass contract
|
||||
2. 再把更多 renderer feature 统一为正式能力
|
||||
3. 等真正的多 pass 复杂度上来后,再引入 render graph
|
||||
|
||||
---
|
||||
|
||||
## 3. 当前 Renderer 的真实问题
|
||||
|
||||
### 3.1 Shader 仍未进入正式主路径
|
||||
|
||||
当前 built-in forward pipeline 的 shader 仍然是直接硬编码在 C++ 中:
|
||||
|
||||
- D3D12: HLSL
|
||||
- OpenGL: GLSL 430
|
||||
- Vulkan: GLSL 450
|
||||
|
||||
这意味着:
|
||||
|
||||
- `Material::GetShader()` 虽然存在,但不控制当前主渲染
|
||||
- shader 资源尚未成为正式运行时契约
|
||||
- 新增 pass 或 shader 变体时,仍然需要直接改 pipeline C++
|
||||
|
||||
这不符合后续 Unity 风格 SRP 的方向。
|
||||
|
||||
### 3.2 Material 还是“资源状态载体”,不是正式 GPU 材质实例
|
||||
|
||||
当前 `Material` 已具备:
|
||||
|
||||
- render queue
|
||||
- rasterizer / blend / depth-stencil render state
|
||||
- tag
|
||||
- property
|
||||
- texture binding
|
||||
- shader 引用
|
||||
|
||||
但真正进入 GPU 执行链路的内容,仍然很少:
|
||||
|
||||
- per-object constant
|
||||
- 一张主纹理
|
||||
- 一个 sampler
|
||||
- 少量 pass metadata 过滤
|
||||
|
||||
也就是说:
|
||||
|
||||
- material property 还没有正式映射到 GPU layout
|
||||
- material constant buffer 还没有进入正式绑定链路
|
||||
- texture binding 还没有从“约定名字查一张图”升级为“按 pass layout 正式绑定”
|
||||
|
||||
### 3.3 Pass contract 仍然不够完整
|
||||
|
||||
当前比较明确的 pass 只有:
|
||||
|
||||
- forward 主几何
|
||||
- object-id
|
||||
- grid
|
||||
- selection outline
|
||||
- debug mask
|
||||
|
||||
但如果后面要走 Unity 风格 renderer,至少需要明确区分:
|
||||
|
||||
- `ForwardLit`
|
||||
- `Unlit`
|
||||
- `DepthOnly`
|
||||
- `ShadowCaster`
|
||||
- `ObjectId`
|
||||
- editor helper pass
|
||||
|
||||
否则后面一旦加入阴影、深度预通道、材质分流、后处理和 SRP 注入,就会重新回到“if/else 管线”。
|
||||
|
||||
### 3.4 三后端能跑,但还不是正式 shader 资产体系
|
||||
|
||||
当前三后端运行没问题,不代表 shader 体系已经成熟。
|
||||
|
||||
当前缺的是:
|
||||
|
||||
- 统一的 shader 资产描述
|
||||
- 每个 shader pass 的 backend variant 管理
|
||||
- 统一的 descriptor / constant layout 描述
|
||||
- renderer 内部的 pipeline cache key 规范
|
||||
|
||||
现在只是“每个 backend 有一份能工作的内建 shader”,离正式体系还有明显距离。
|
||||
|
||||
---
|
||||
|
||||
## 4. 下一阶段的核心目标
|
||||
|
||||
下一阶段目标不是“把所有渲染功能做完”,而是建立正式可扩展的 renderer 执行契约。
|
||||
|
||||
核心目标分四层。
|
||||
|
||||
### 4.1 正式建立 Shader Asset Contract
|
||||
|
||||
下一阶段应把 `Shader` 从资源占位,提升为 renderer 正式消费的资源。
|
||||
|
||||
建议 shader 资产至少包含:
|
||||
|
||||
- shader 名称与 GUID
|
||||
- pass 列表
|
||||
- 每个 pass 的逻辑名称
|
||||
- 每个 pass 的 tag,例如 `LightMode`
|
||||
- 每个 pass 的 property layout
|
||||
- 每个 pass 的 resource binding layout
|
||||
- 每个 backend 的 shader variant
|
||||
|
||||
建议的概念模型:
|
||||
|
||||
```text
|
||||
ShaderAsset
|
||||
-> ShaderPassDesc[]
|
||||
-> passName
|
||||
-> tags
|
||||
-> propertyLayout
|
||||
-> backendVariants
|
||||
```
|
||||
|
||||
这里的关键点不是一开始就做复杂 shader graph,而是先明确:
|
||||
|
||||
- renderer 以后创建 pipeline,不再直接从 C++ 字符串取 shader
|
||||
- renderer 应从 shader asset 的某个 pass 中取当前 backend 对应 variant
|
||||
|
||||
### 4.2 正式建立 Material Instance Contract
|
||||
|
||||
`Material` 下一阶段要从“资源状态容器”升级为“可绑定的材质实例”。
|
||||
|
||||
Material 至少应当明确:
|
||||
|
||||
- 它引用哪个 shader
|
||||
- 它选择 shader 的哪个 pass
|
||||
- 它当前有哪些 property override
|
||||
- 它有哪些 texture binding
|
||||
- 它导出的 render state 是什么
|
||||
|
||||
下一阶段不要求一开始就做复杂材质编辑器,但必须完成:
|
||||
|
||||
- property -> GPU 常量区布局
|
||||
- texture binding -> descriptor binding
|
||||
- pass 过滤规则
|
||||
- material instance 的缓存与脏标记
|
||||
|
||||
### 4.3 正式建立 Builtin Pass Contract
|
||||
|
||||
下一阶段应当把当前 renderer 内建 pass 明确分层:
|
||||
|
||||
- 几何主 pass
|
||||
- 深度/阴影类 pass
|
||||
- object-id/editor helper pass
|
||||
- post-process / overlay pass
|
||||
|
||||
建议第一批正式化的 pass 名称:
|
||||
|
||||
- `ForwardLit`
|
||||
- `Unlit`
|
||||
- `DepthOnly`
|
||||
- `ShadowCaster`
|
||||
- `ObjectId`
|
||||
|
||||
说明:
|
||||
|
||||
- `ForwardLit` 支撑当前主线
|
||||
- `Unlit` 用于 editor helper、gizmo、调试对象、简单 UI mesh
|
||||
- `DepthOnly` 和 `ShadowCaster` 为后面阴影与可见性阶段铺路
|
||||
- `ObjectId` 让 editor/runtime picking 有正式 renderer 合约
|
||||
|
||||
### 4.4 正式建立 Renderer Feature Contract
|
||||
|
||||
当前 grid / outline / object-id / debug mask 已经部分进入 renderer,但仍然带有明显 editor 来路。
|
||||
|
||||
下一阶段应继续把它们定义为 renderer feature,而不是 editor 特判:
|
||||
|
||||
- object-id output
|
||||
- selection / mask debug
|
||||
- overlay helper contract
|
||||
- camera request 上的 feature request
|
||||
|
||||
目标不是马上做完整 feature graph,而是明确:
|
||||
|
||||
- 哪些 feature 属于 renderer
|
||||
- 哪些输入由 editor 组装
|
||||
- 哪些输出由 renderer 提供
|
||||
|
||||
---
|
||||
|
||||
## 5. 三后端 Shader 策略
|
||||
|
||||
这一节必须进一步说透两个问题:
|
||||
|
||||
1. 三后端语言不同,shader 资产到底怎么组织
|
||||
2. shader authoring 到底采用“Unity 式一份 shader 里写多个 stage”,还是把 vertex / fragment 拆成独立文件
|
||||
|
||||
### 5.1 当前阶段不建议直接追求“单源码全平台自动转译”
|
||||
|
||||
理论上可以追求:
|
||||
|
||||
- 统一 HLSL
|
||||
- 再编到 SPIR-V / GLSL
|
||||
|
||||
但这会立刻引入:
|
||||
|
||||
- 工具链依赖
|
||||
- shader reflection
|
||||
- backend 兼容差异处理
|
||||
- 调试复杂度
|
||||
|
||||
对于当前工程,这不是下一阶段最优先的问题。
|
||||
|
||||
### 5.2 下一阶段建议采用“统一逻辑资产 + 后端分 variant”的务实方案
|
||||
|
||||
建议下一阶段的 shader 策略是:
|
||||
|
||||
- 逻辑上一个 shader asset
|
||||
- 资产里按 pass 持有多个 backend variant
|
||||
- renderer 根据 backend 选择对应源码/二进制
|
||||
|
||||
例如:
|
||||
|
||||
```text
|
||||
BuiltinLit.shader
|
||||
Pass: ForwardLit
|
||||
D3D12 -> HLSL
|
||||
OpenGL -> GLSL 430
|
||||
Vulkan -> GLSL 450 / SPIR-V
|
||||
```
|
||||
|
||||
这样做的优点:
|
||||
|
||||
- 三后端路径清晰
|
||||
- 不引入过早的跨编译复杂度
|
||||
- 仍然能在资产层统一 shader 逻辑身份
|
||||
- 后续要切换成统一 authoring 也有演进空间
|
||||
|
||||
### 5.3 Vulkan 的长期方向
|
||||
|
||||
Vulkan 长期更适合进入:
|
||||
|
||||
- 预编译 SPIR-V
|
||||
- 反射生成 binding layout
|
||||
|
||||
但这属于再下一阶段的工程化增强。
|
||||
|
||||
当前下一阶段只要求:
|
||||
|
||||
- Vulkan 不再依赖 pipeline cpp 内嵌 shader 字符串的散乱模式
|
||||
- Vulkan variant 被纳入正式 shader asset contract
|
||||
|
||||
### 5.4 推荐的 Shader 资产组织方式
|
||||
|
||||
建议下一阶段采用:
|
||||
|
||||
- **逻辑上一个 ShaderAsset**
|
||||
- **资产内部按 Pass 组织**
|
||||
- **每个 Pass 内再按 Stage 与 Backend 持有 variant**
|
||||
|
||||
推荐概念模型:
|
||||
|
||||
```text
|
||||
ShaderAsset
|
||||
-> Pass: ForwardLit
|
||||
-> Stage: Vertex
|
||||
-> D3D12 : xxx.vs.hlsl
|
||||
-> OpenGL : xxx.vs.glsl
|
||||
-> Vulkan : xxx.vs.vk.glsl / xxx.vs.spv
|
||||
-> Stage: Fragment
|
||||
-> D3D12 : xxx.ps.hlsl
|
||||
-> OpenGL : xxx.fs.glsl
|
||||
-> Vulkan : xxx.fs.vk.glsl / xxx.fs.spv
|
||||
|
||||
-> Pass: DepthOnly
|
||||
-> ...
|
||||
```
|
||||
|
||||
也就是说:
|
||||
|
||||
- 对 renderer 来说,真正识别的是一个 `ShaderAsset`
|
||||
- 对 pass 来说,拿到的是“这个 pass 在当前 backend 下对应的各 stage 变体”
|
||||
- 对后端来说,最终看到的仍然是它自己能吃的 shader 源码或二进制
|
||||
|
||||
这样处理后:
|
||||
|
||||
- shader 逻辑身份是统一的
|
||||
- backend 差异被收进 variant 层
|
||||
- pass / stage / backend 三个维度都清楚
|
||||
|
||||
### 5.5 不建议直接照搬 Unity ShaderLab 的单文件大一统方案
|
||||
|
||||
如果完全模仿 Unity,最直观的形式是:
|
||||
|
||||
- 一份 shader 文件
|
||||
- 里面写 `Pass`
|
||||
- `Pass` 里面再写 `Vertex/Fragment`
|
||||
|
||||
这种方式的优点是:
|
||||
|
||||
- 对材质和 pass 关系表达很强
|
||||
- 很适合后续 editor / inspector / C# SRP 暴露
|
||||
|
||||
但它当前直接落地的缺点也很明显:
|
||||
|
||||
- 你现在有三个 backend
|
||||
- backend shader 语言并不统一
|
||||
- 还没有自己的 shader import / include / preprocess / reflection 工具链
|
||||
|
||||
如果现在直接做成 Unity 那种单文件 DSL,等于同时要解决:
|
||||
|
||||
- shader 语法设计
|
||||
- parser
|
||||
- include 系统
|
||||
- multi-pass 语义
|
||||
- backend variant 分发
|
||||
- material property layout
|
||||
|
||||
这会把下一阶段的复杂度一下子拉爆。
|
||||
|
||||
### 5.6 下一阶段更务实的做法
|
||||
|
||||
下一阶段建议采用“两层模型”:
|
||||
|
||||
#### 第一层:逻辑层接近 Unity
|
||||
|
||||
保留 Unity 风格的核心语义:
|
||||
|
||||
- 一个 shader 有多个 pass
|
||||
- 每个 pass 有名字和 tag
|
||||
- material 绑定的是 shader 与 pass
|
||||
|
||||
#### 第二层:物理文件层先按 stage 分开
|
||||
|
||||
实际文件先拆成:
|
||||
|
||||
- `*.vs.hlsl`
|
||||
- `*.ps.hlsl`
|
||||
- `*.vs.glsl`
|
||||
- `*.fs.glsl`
|
||||
- `*.vs.vk.glsl`
|
||||
- `*.fs.vk.glsl`
|
||||
|
||||
或者编译后:
|
||||
|
||||
- `*.spv`
|
||||
|
||||
也就是说:
|
||||
|
||||
- **逻辑上用 Unity 式“一个 shader 拥有多个 pass”**
|
||||
- **物理落地上暂时不用 Unity 式“一个文件里硬塞所有 backend/stage”**
|
||||
|
||||
这是当前阶段最稳妥的方案。
|
||||
|
||||
### 5.7 对“vertex / fragment 是合一还是分开”的明确结论
|
||||
|
||||
结论分两层:
|
||||
|
||||
#### 从逻辑资产视角看
|
||||
|
||||
应当是“合一”的。
|
||||
|
||||
也就是:
|
||||
|
||||
- 一个 `ShaderAsset`
|
||||
- 下面有一个或多个 `Pass`
|
||||
- 一个 `Pass` 同时拥有 vertex / fragment 等 stage
|
||||
|
||||
这和 Unity 的思路一致。
|
||||
|
||||
#### 从实际源码文件视角看
|
||||
|
||||
应当先“分开”。
|
||||
|
||||
也就是:
|
||||
|
||||
- vertex shader 单独文件
|
||||
- fragment shader 单独文件
|
||||
- backend variant 单独文件
|
||||
|
||||
原因:
|
||||
|
||||
- 更容易做 backend 分发
|
||||
- 更容易调试编译错误
|
||||
- 更容易做最小 shader import
|
||||
- 更适合你当前三后端并行维护
|
||||
|
||||
所以不要把“逻辑合一”和“源码物理文件合一”混为一谈。
|
||||
|
||||
最终建议是:
|
||||
|
||||
- **逻辑模型采用 Unity 风格**
|
||||
- **文件组织先采用分 stage、分 backend**
|
||||
|
||||
### 5.8 未来再向 Unity ShaderLab 靠拢的演进路径
|
||||
|
||||
等下一阶段把下面这些都做稳之后:
|
||||
|
||||
- shader asset contract
|
||||
- material property binding
|
||||
- backend variant 选择
|
||||
- pass contract
|
||||
|
||||
后面再往上加一层更接近 Unity ShaderLab 的 authoring 语法,就顺理成章:
|
||||
|
||||
```text
|
||||
ShaderLab-like Authoring
|
||||
-> Shader Importer
|
||||
-> ShaderAsset / Pass / Variant
|
||||
-> RenderPipeline Runtime
|
||||
```
|
||||
|
||||
也就是说:
|
||||
|
||||
- 现在先做 runtime contract
|
||||
- 以后再做更高级的 shader authoring front-end
|
||||
|
||||
这样不会把工程顺序做反。
|
||||
|
||||
---
|
||||
|
||||
## 6. 建议的新分层
|
||||
|
||||
建议 Renderer 下一阶段形成下面这套更稳定的分层:
|
||||
|
||||
```text
|
||||
Scene / Components / Resources
|
||||
-> RenderSceneExtractor / RenderRequestPlanner
|
||||
-> Shader & Material Runtime
|
||||
-> CameraRenderer / RenderPipeline
|
||||
-> Builtin Feature Passes
|
||||
-> RHI
|
||||
-> D3D12 / OpenGL / Vulkan
|
||||
```
|
||||
|
||||
其中新增的重点层是:
|
||||
|
||||
### 6.1 Shader & Material Runtime
|
||||
|
||||
负责:
|
||||
|
||||
- 解析 shader asset / material asset
|
||||
- 生成 pass 级 binding layout
|
||||
- 维护 material GPU 数据与脏标记
|
||||
- 提供 pipeline cache key
|
||||
|
||||
### 6.2 Builtin Feature Passes
|
||||
|
||||
负责:
|
||||
|
||||
- object-id
|
||||
- grid
|
||||
- outline
|
||||
- shadow/depth 等 builtin pass
|
||||
|
||||
这样可以让:
|
||||
|
||||
- `RenderPipeline` 更聚焦于场景主流程组织
|
||||
- 各 pass 更聚焦于自己真正的职责
|
||||
|
||||
---
|
||||
|
||||
## 7. 推荐的落地顺序
|
||||
|
||||
### 阶段 A:Formalize Builtin Pass Metadata
|
||||
|
||||
先完成:
|
||||
|
||||
- `ForwardLit`
|
||||
- `Unlit`
|
||||
- `DepthOnly`
|
||||
- `ObjectId`
|
||||
|
||||
需要落地的内容:
|
||||
|
||||
- pass name
|
||||
- pass tag
|
||||
- renderer 如何选择某个 material 的 pass
|
||||
- builtin pipeline 不再依赖模糊字符串判断
|
||||
|
||||
完成标志:
|
||||
|
||||
- `MatchesBuiltinPass(...)` 不再只是当前这种最小过滤,而是更接近正式 pass contract
|
||||
|
||||
### 阶段 B:Material GPU Binding 最小闭环
|
||||
|
||||
先完成:
|
||||
|
||||
- material 常量数据打包
|
||||
- texture binding 正式映射
|
||||
- sampler 策略统一
|
||||
- material 脏标记 -> GPU 缓存更新
|
||||
|
||||
完成标志:
|
||||
|
||||
- forward pipeline 不再只会找一张 `_MainTex` 风格贴图
|
||||
- material property 真正进入 shader 执行链
|
||||
|
||||
### 阶段 C:Shader Asset 真正进入 Render Pipeline
|
||||
|
||||
先完成:
|
||||
|
||||
- builtin shader 资产化
|
||||
- 每个 builtin shader 具备 backend variant
|
||||
- pipeline state 从 shader asset pass 创建
|
||||
|
||||
完成标志:
|
||||
|
||||
- `BuiltinForwardPipeline.cpp` 中的大段后端 shader 字符串不再是长期正式实现
|
||||
|
||||
### 阶段 D:Renderer-owned Feature Contract 收口
|
||||
|
||||
先完成:
|
||||
|
||||
- object-id request/output 正式化
|
||||
- outline/grid 继续从 editor 逻辑脱耦
|
||||
- camera request 上的 feature request 更明确
|
||||
|
||||
完成标志:
|
||||
|
||||
- editor 侧更多只做 request 装配,而不是 feature 逻辑承担者
|
||||
|
||||
### 阶段 E:验证与回归
|
||||
|
||||
必须补的测试:
|
||||
|
||||
- renderer unit tests
|
||||
- shader/material runtime unit tests
|
||||
- pass metadata 选择测试
|
||||
- backend integration smoke tests
|
||||
- editor viewport regression
|
||||
|
||||
---
|
||||
|
||||
## 8. 下一阶段明确不做的内容
|
||||
|
||||
以下内容不进入下一阶段主线:
|
||||
|
||||
- render graph
|
||||
- 完整 shader graph
|
||||
- 完整 deferred renderer
|
||||
- 大规模后处理栈
|
||||
- 完整阴影系统产品化
|
||||
- C# SRP 真正脚本驱动落地
|
||||
|
||||
原因不是这些不重要,而是它们依赖下一阶段先把基础契约做稳。
|
||||
|
||||
---
|
||||
|
||||
## 9. 与 Unity 风格架构的承接关系
|
||||
|
||||
如果后面目标是做 Unity 风格的 C# SRP,那么下一阶段必须先把“原生 renderer 可被脚本驱动”的基础层做好。
|
||||
|
||||
Unity 风格承接关系应理解为:
|
||||
|
||||
```text
|
||||
Shader / Material / Pass Contract
|
||||
-> Native Render Pipeline Runtime
|
||||
-> ScriptableRenderContext / CommandBuffer
|
||||
-> C# RenderPipelineAsset / RenderPipeline
|
||||
```
|
||||
|
||||
也就是说:
|
||||
|
||||
- 当前下一阶段做的不是 SRP 本身
|
||||
- 但做的是 SRP 能否成立的地基
|
||||
|
||||
如果这一层继续缺失,后面脚本层会直接耦合到一堆临时内建逻辑上,最后 SRP 只会沦为“脚本包装的硬编码 forward pipeline”。
|
||||
|
||||
---
|
||||
|
||||
## 10. 阶段成功标准
|
||||
|
||||
这一阶段完成时,至少应满足:
|
||||
|
||||
1. shader asset 已进入 renderer 主路径
|
||||
2. material property 与 texture binding 已形成正式 GPU 绑定链
|
||||
3. builtin pass contract 已具备最小完整集
|
||||
4. 三后端 shader 不再依赖 pipeline cpp 中散乱硬编码作为长期实现
|
||||
5. object-id / outline / grid 等 renderer feature 边界进一步明确
|
||||
6. renderer/editor 对应测试体系同步补齐
|
||||
|
||||
---
|
||||
|
||||
## 11. 一句话总结
|
||||
|
||||
Renderer 下一阶段的正确主线不是 render graph,而是:
|
||||
|
||||
- 先把 `Shader`
|
||||
- `Material`
|
||||
- `Pass Contract`
|
||||
- `Renderer Feature Contract`
|
||||
|
||||
做成正式能力。
|
||||
|
||||
只有这一层站稳之后,后面的:
|
||||
|
||||
- 阴影
|
||||
- 更多 pass
|
||||
- render graph
|
||||
- C# SRP
|
||||
|
||||
才会是顺势生长,而不是继续堆临时方案。
|
||||
841
docs/used/Renderer下一阶段_Unity风格Shader体系正式化计划_完成归档_2026-04-07.md
Normal file
841
docs/used/Renderer下一阶段_Unity风格Shader体系正式化计划_完成归档_2026-04-07.md
Normal file
@@ -0,0 +1,841 @@
|
||||
# Renderer 下一阶段:Unity 风格 Shader 体系正式化计划
|
||||
|
||||
日期:`2026-04-06`
|
||||
|
||||
## 1. 阶段结论
|
||||
|
||||
当前 renderer 主线已经可以阶段性收口,但 `Shader / Material / Pass` 体系还没有真正统一。
|
||||
|
||||
现在仓库里的 shader 体系处于一个过渡态:
|
||||
|
||||
- 逻辑上已经有 `Shader -> Pass -> Variant` 模型
|
||||
- authoring 外观上已经接近 Unity ShaderLab
|
||||
- 运行时已经能按 pass 和 backend variant 选择 shader
|
||||
- 三后端已经能稳定跑通 builtin shader
|
||||
|
||||
但它仍然不是 Unity 风格的正式体系,因为当前 authoring 仍然暴露了太多 backend 与 binding 细节:
|
||||
|
||||
- `.shader` 文件里仍然显式写 `#pragma backend D3D12/OpenGL/Vulkan`
|
||||
- `.shader` 文件里仍然显式写 `Resources { name(type, set, binding) }`
|
||||
- material 仍然可以显式指定 `shaderPass`
|
||||
- shader 关键字、变体、include、pass state、SubShader 选择还没有真正成体系
|
||||
|
||||
所以这一阶段的主线不是继续做新渲染效果,而是把 shader 体系升级成:
|
||||
|
||||
- **authoring 层完全按 Unity 风格书写**
|
||||
- **三后端编译路径统一收敛到 importer / compiler 层**
|
||||
- **runtime 只消费正式 shader artifact / material contract**
|
||||
|
||||
这一步不是 SRP 本身,但它是后续 SRP 能否成立的硬地基。
|
||||
|
||||
---
|
||||
|
||||
## 2. 阶段目标
|
||||
|
||||
本阶段要达成的核心目标只有一件事:
|
||||
|
||||
**把当前“伪 ShaderLab + 后端直连”的过渡体系,升级为“Unity 风格 authoring + 引擎内部统一 shader IR + 三后端编译产物”的正式体系。**
|
||||
|
||||
完成后应达到:
|
||||
|
||||
1. shader authoring 采用 Unity 风格 `.shader` 语法,不再要求作者显式写 backend variant 分发表。
|
||||
2. 新语法不再要求作者手写 `set/binding` 级资源绑定表。
|
||||
3. HLSL 成为 raster shader 的单一 authoring 语言源。
|
||||
4. D3D12 / Vulkan / OpenGL 的差异退到 importer / compiler / artifact 层。
|
||||
5. material 只管 property / keyword / texture / render state,不再负责点名 pass。
|
||||
6. renderer 按 `LightMode` / pass contract 选 pass,而不是靠 material 的临时字符串兜底。
|
||||
7. builtin shader 全部迁移到新体系并保持三后端回归稳定。
|
||||
8. 保留 legacy shader 兼容层,避免一次性炸掉现有工程内容。
|
||||
|
||||
---
|
||||
|
||||
## 3. 非目标
|
||||
|
||||
本阶段明确不做:
|
||||
|
||||
- SRP 本体
|
||||
- render graph
|
||||
- deferred / clustered
|
||||
- Shader Graph
|
||||
- Surface Shader
|
||||
- 完整 Unity ShaderLab 100% 全语法一次性覆盖
|
||||
- volume 系统
|
||||
- 更多新渲染效果
|
||||
|
||||
本阶段也不追求一口气把 Unity 的所有 authoring 特性补完,例如:
|
||||
|
||||
- `Fallback`
|
||||
- `UsePass`
|
||||
- `CustomEditor`
|
||||
- `GrabPass`
|
||||
- tessellation / geometry / ray tracing authoring
|
||||
|
||||
这些可以后续补,但不应阻塞当前阶段把“统一 shader 体系”先做正确。
|
||||
|
||||
---
|
||||
|
||||
## 4. 当前真实状态与根本问题
|
||||
|
||||
### 4.1 当前已经具备的能力
|
||||
|
||||
当前工程已经具备:
|
||||
|
||||
- `.shader` 文件解析能力
|
||||
- `Shader` 的 pass / property / resource / variant 数据模型
|
||||
- builtin shader 资产化
|
||||
- material property / texture / render state / tag 载体
|
||||
- renderer 中按 builtin pass metadata 选择可用 shader pass
|
||||
|
||||
这意味着当前不是从零开始设计。
|
||||
|
||||
### 4.2 当前最根本的问题
|
||||
|
||||
当前最大的问题不是“没有 shader 体系”,而是“authoring 层和 runtime 层的边界还没收干净”。
|
||||
|
||||
具体表现为:
|
||||
|
||||
1. **authoring 层暴露后端差异**
|
||||
- `.shader` 文件直接写 `#pragma backend D3D12/OpenGL/Vulkan`
|
||||
- shader 作者必须知道后端与源码文件映射
|
||||
|
||||
2. **authoring 层暴露 RHI binding 细节**
|
||||
- `.shader` 文件显式写 `Resources { ConstantBuffer / Texture2D / Sampler, set, binding }`
|
||||
- 这更像 Vulkan/D3D12 binding 清单,不是 Unity 风格 shader authoring
|
||||
|
||||
3. **material 还带着临时 pass 选择职责**
|
||||
- `Material::SetShaderPass()` 仍然存在
|
||||
- renderer 仍然优先吃 material 显式指定的 pass
|
||||
- 这会阻碍未来 RendererFeature / SRP 规范化
|
||||
|
||||
4. **关键字与变体体系缺失**
|
||||
- 没有正式的 `multi_compile / shader_feature`
|
||||
- 没有变体剥离与编译缓存策略
|
||||
|
||||
5. **include 与共享库体系缺失**
|
||||
- 没有正式的 shader include 搜索路径、预处理、公共库组织
|
||||
|
||||
6. **pass state 仍然不在 shader authoring 的统一语义内**
|
||||
- 诸如 `Cull / ZWrite / ZTest / Blend / ColorMask / Stencil` 还没有完整进入 shader authoring contract
|
||||
|
||||
7. **三后端仍然是物理三套源码直连**
|
||||
- 当前虽然“逻辑上一个 shader asset”
|
||||
- 但作者本质上还在维护三套 shader stage 文件
|
||||
|
||||
---
|
||||
|
||||
## 5. 核心设计结论
|
||||
|
||||
### 5.1 目标不是“看起来像 Unity”,而是“真正采用 Unity 风格 authoring 模型”
|
||||
|
||||
最终目标应当是:
|
||||
|
||||
- 一个 `.shader` 文件描述一个逻辑 shader
|
||||
- shader 内部有 `Properties / SubShader / Pass / Tags / State / Program`
|
||||
- renderer 消费的是 import 后的统一 IR / artifact
|
||||
- backend 差异不暴露给 shader 作者
|
||||
|
||||
### 5.2 HLSL 作为单一 authoring 语言源
|
||||
|
||||
本阶段必须明确:
|
||||
|
||||
- **新体系下 raster shader 统一使用 HLSL authoring**
|
||||
- D3D12 直接编 HLSL
|
||||
- Vulkan 由 HLSL 编到 SPIR-V
|
||||
- OpenGL 由 HLSL 编到 SPIR-V,再转 GLSL 430
|
||||
|
||||
原因:
|
||||
|
||||
- 如果 authoring 仍然保留 GLSL/HLSL 三套并行,永远不可能真正统一写法
|
||||
- 只有 single-source authoring,才能接近 Unity 的真实体验
|
||||
|
||||
### 5.3 backend 差异必须退到 importer / compiler 层
|
||||
|
||||
新 authoring 文件中不应再出现:
|
||||
|
||||
- `#pragma backend ...`
|
||||
- backend 专属 stage 文件路径表
|
||||
|
||||
这些内容应由 importer 根据 target backend 生成产物。
|
||||
|
||||
### 5.4 resource binding 不再由 shader 作者手写 `Resources(set,binding)`
|
||||
|
||||
Unity 风格 shader authoring 不要求作者手写 descriptor set / binding。
|
||||
|
||||
因此新体系下应改为:
|
||||
|
||||
- material 暴露属性来自 `Properties`
|
||||
- engine 内建 constant buffer / texture / sampler 来自约定与 reflection
|
||||
- importer 通过 HLSL reflection + 约定库推导 runtime resource layout
|
||||
|
||||
也就是说:
|
||||
|
||||
- authoring 层写“语义”
|
||||
- importer 层生成“绑定布局”
|
||||
- runtime 层消费“绑定布局”
|
||||
|
||||
### 5.5 pass 选择必须回归 renderer,而不是 material
|
||||
|
||||
新体系中:
|
||||
|
||||
- material 只绑定 shader 与 property / keyword / texture
|
||||
- renderer 按 `LightMode` 选 pass
|
||||
- `Material::shaderPass` 进入弃用与最终移除路径
|
||||
|
||||
这与 Unity 的 `ShaderTagId / LightMode` 思路对齐,也更利于未来 SRP。
|
||||
|
||||
### 5.6 必须保留 legacy 兼容层
|
||||
|
||||
当前仓库已经有一批 builtin shader 和测试资产。
|
||||
|
||||
因此不能激进地“一刀切重做”,而应:
|
||||
|
||||
- legacy `.shader` 继续可加载
|
||||
- 新 Unity 风格 `.shader` 进入新 importer 路径
|
||||
- builtin shader 分批迁移
|
||||
- runtime 统一落在同一套 `Shader` / artifact / variant 模型上
|
||||
|
||||
---
|
||||
|
||||
## 6. 目标架构
|
||||
|
||||
建议把 shader 体系正式分成 5 层。
|
||||
|
||||
### 6.1 Authoring 层
|
||||
|
||||
职责:
|
||||
|
||||
- 让开发者以 Unity 风格书写 shader
|
||||
|
||||
建议语法子集:
|
||||
|
||||
- `Shader`
|
||||
- `Properties`
|
||||
- `SubShader`
|
||||
- `Pass`
|
||||
- `Tags`
|
||||
- `LOD`
|
||||
- `HLSLINCLUDE`
|
||||
- `HLSLPROGRAM`
|
||||
- `ENDHLSL`
|
||||
- `#pragma vertex`
|
||||
- `#pragma fragment`
|
||||
- `#pragma target`
|
||||
- `#pragma multi_compile`
|
||||
- `#pragma shader_feature`
|
||||
- `#pragma shader_feature_local`
|
||||
- `Cull`
|
||||
- `ZWrite`
|
||||
- `ZTest`
|
||||
- `Blend`
|
||||
- `ColorMask`
|
||||
- `Stencil`
|
||||
- `Offset`
|
||||
|
||||
### 6.2 Importer / Parser 层
|
||||
|
||||
职责:
|
||||
|
||||
- 解析 Unity 风格 `.shader`
|
||||
- 生成统一的内部 `ShaderIR`
|
||||
|
||||
建议引入:
|
||||
|
||||
- `ShaderAuthoringParser`
|
||||
- `ShaderIR`
|
||||
- `ShaderSubShaderIR`
|
||||
- `ShaderPassIR`
|
||||
- `ShaderKeywordDecl`
|
||||
- `ShaderPassStateDesc`
|
||||
- `ShaderProgramIR`
|
||||
|
||||
### 6.3 Compiler / Reflection 层
|
||||
|
||||
职责:
|
||||
|
||||
- 编译 authoring 中的 HLSL
|
||||
- 为不同 backend 生成最终编译产物
|
||||
- 生成 resource layout / constant layout / keyword variant metadata
|
||||
|
||||
建议技术路径:
|
||||
|
||||
- D3D12:`DXC -> DXIL/DXBC`
|
||||
- Vulkan:`DXC -> SPIR-V`
|
||||
- OpenGL:`DXC -> SPIR-V -> SPIRV-Cross -> GLSL 430`
|
||||
|
||||
输出:
|
||||
|
||||
- 每个 pass / stage / keyword-set / backend 的编译产物
|
||||
- 反射出的 constant buffer / texture / sampler 布局
|
||||
|
||||
### 6.4 Artifact 层
|
||||
|
||||
职责:
|
||||
|
||||
- 保存运行时真正消费的 shader 产物
|
||||
|
||||
建议引入新版 artifact:
|
||||
|
||||
- `xcshader2` 或继续升级现有 `xcshader`
|
||||
|
||||
artifact 内容至少包含:
|
||||
|
||||
- shader 名称 / guid
|
||||
- properties
|
||||
- subshader / pass tags
|
||||
- pass state
|
||||
- keyword declarations
|
||||
- keyword variant table
|
||||
- backend binaries / backend source payload
|
||||
- reflected resource layout
|
||||
- include 依赖与 hash
|
||||
|
||||
### 6.5 Runtime 层
|
||||
|
||||
职责:
|
||||
|
||||
- renderer 根据 pass contract、keywords、backend 选择最终 variant
|
||||
- material 根据 property/texture 生成常量与资源绑定
|
||||
- pipeline cache 根据 shader variant + render state 建 key
|
||||
|
||||
---
|
||||
|
||||
## 7. Unity 风格 authoring 范围定义
|
||||
|
||||
### 7.1 第一阶段必须支持的语法
|
||||
|
||||
第一阶段建议正式支持:
|
||||
|
||||
```shaderlab
|
||||
Shader "XCEngine/Example/Lit"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
_BaseColor ("Base Color", Color) = (1,1,1,1)
|
||||
_BaseMap ("Base Map", 2D) = "white" {}
|
||||
_Cutoff ("Alpha Cutoff", Range(0,1)) = 0.5
|
||||
}
|
||||
|
||||
HLSLINCLUDE
|
||||
#include "ShaderLibrary/Core.hlsl"
|
||||
ENDHLSL
|
||||
|
||||
SubShader
|
||||
{
|
||||
Tags { "RenderType"="Opaque" "Queue"="Geometry" }
|
||||
LOD 200
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "ForwardLit"
|
||||
Tags { "LightMode"="ForwardLit" }
|
||||
Cull Back
|
||||
ZWrite On
|
||||
ZTest LEqual
|
||||
Blend One Zero
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma target 4.5
|
||||
#pragma vertex Vert
|
||||
#pragma fragment Frag
|
||||
#pragma multi_compile _ XC_MAIN_LIGHT_SHADOWS
|
||||
#pragma shader_feature_local _ XC_ALPHA_TEST
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 7.2 第一阶段暂不支持的语法
|
||||
|
||||
第一阶段可暂缓:
|
||||
|
||||
- `Fallback`
|
||||
- `UsePass`
|
||||
- `GrabPass`
|
||||
- `CustomEditor`
|
||||
- `Category`
|
||||
- `Dependency`
|
||||
- Surface Shader
|
||||
- CG fixed-function 时代遗留语义
|
||||
|
||||
这些需要列入兼容性说明,但不应阻塞首版落地。
|
||||
|
||||
---
|
||||
|
||||
## 8. 统一的 shader library 与 include 体系
|
||||
|
||||
这一层是“写法统一”能否成立的关键。
|
||||
|
||||
### 8.1 必须引入正式的 include 库
|
||||
|
||||
建议新增:
|
||||
|
||||
- `engine/assets/shaderlib/ShaderLibrary/Core.hlsl`
|
||||
- `engine/assets/shaderlib/ShaderLibrary/Common.hlsl`
|
||||
- `engine/assets/shaderlib/ShaderLibrary/SpaceTransforms.hlsl`
|
||||
- `engine/assets/shaderlib/ShaderLibrary/Lighting.hlsl`
|
||||
- `engine/assets/shaderlib/ShaderLibrary/MaterialInput.hlsl`
|
||||
- `engine/assets/shaderlib/ShaderLibrary/Shadow.hlsl`
|
||||
|
||||
目标:
|
||||
|
||||
- builtin shader 共用统一宏与公共函数
|
||||
- authoring 层不再重复声明一堆 per-object / lighting 结构
|
||||
|
||||
### 8.2 统一的内建常量组
|
||||
|
||||
建议统一为接近 Unity 的内建分组:
|
||||
|
||||
- `UnityPerFrame` 或 `XCPerFrame`
|
||||
- `UnityPerCamera` 或 `XCPerCamera`
|
||||
- `UnityPerDraw` 或 `XCPerDraw`
|
||||
- `UnityPerMaterial` 或 `XCPerMaterial`
|
||||
|
||||
建议引擎内部最终保留 `XC*` 前缀实现名,但 authoring 宏层提供 Unity 风格别名。
|
||||
|
||||
### 8.3 内建纹理/采样器由 include 库与 reflection 管理
|
||||
|
||||
例如:
|
||||
|
||||
- 主纹理
|
||||
- 阴影图
|
||||
- 环境图
|
||||
- sampler state
|
||||
|
||||
这些都不再由 `.shader` 手填 `Resources(set,binding)`。
|
||||
|
||||
---
|
||||
|
||||
## 9. Material 体系同步改造
|
||||
|
||||
shader 统一如果不带 material 一起改,最后会停在半路。
|
||||
|
||||
### 9.1 material 的职责边界
|
||||
|
||||
新体系里 material 负责:
|
||||
|
||||
- 选择 shader
|
||||
- 保存 property override
|
||||
- 保存 texture override
|
||||
- 保存 keyword 开关
|
||||
- 保存材质级 render queue / tag override(如保留)
|
||||
|
||||
新体系里 material 不再负责:
|
||||
|
||||
- 指定 `shaderPass`
|
||||
- 硬编码 backend 资源名
|
||||
- 猜测 shader 内的 descriptor set / binding
|
||||
|
||||
### 9.2 material constant buffer 正式化
|
||||
|
||||
必须建立:
|
||||
|
||||
- `Properties` -> `UnityPerMaterial/XCPerMaterial` 布局
|
||||
- importer 生成 property layout
|
||||
- material 按 layout 打包 GPU 常量
|
||||
- layout/hash 进入 pipeline/material cache key
|
||||
|
||||
### 9.3 keyword 体系正式化
|
||||
|
||||
建议引入:
|
||||
|
||||
- `global keywords`
|
||||
- `local keywords`
|
||||
- material keyword set
|
||||
- variant lookup key
|
||||
|
||||
material 应持有:
|
||||
|
||||
- `ShaderKeywordSet`
|
||||
|
||||
renderer 运行时根据:
|
||||
|
||||
- shader
|
||||
- pass
|
||||
- keyword set
|
||||
- backend
|
||||
|
||||
选择最终 shader variant。
|
||||
|
||||
---
|
||||
|
||||
## 10. Renderer 运行时契约调整
|
||||
|
||||
### 10.1 pass 选择规则统一为 `LightMode`
|
||||
|
||||
renderer 选 pass 时只看:
|
||||
|
||||
- 当前 pipeline 阶段需要的 `LightMode`
|
||||
- shader/subshader/pass 是否匹配
|
||||
- backend 是否有有效 variant
|
||||
|
||||
例如:
|
||||
|
||||
- 主几何:`ForwardLit` / `Unlit`
|
||||
- 阴影:`ShadowCaster`
|
||||
- 深度:`DepthOnly`
|
||||
- ObjectId:`ObjectId`
|
||||
- FinalOutput:`FinalColor`
|
||||
|
||||
### 10.2 material 显式 `shaderPass` 进入弃用路径
|
||||
|
||||
建议执行顺序:
|
||||
|
||||
1. 第一阶段保留字段,但标记为 legacy
|
||||
2. runtime 优先按 pass contract / LightMode 选 pass
|
||||
3. 只有 legacy 资产才允许 fallback 到 `shaderPass`
|
||||
4. migration 完成后移除 `shaderPass` 主路径职责
|
||||
|
||||
### 10.3 builtin pass metadata 继续保留,但收进 importer/runtime
|
||||
|
||||
当前基于 semantic 的 builtin pass binding 解析仍然有价值,但应改成:
|
||||
|
||||
- authoring/IR 层表达语义
|
||||
- compiler/reflection 层生成 binding plan
|
||||
- runtime 只消费 binding plan
|
||||
|
||||
而不是继续靠散落的名字匹配和 fallback。
|
||||
|
||||
---
|
||||
|
||||
## 11. 三后端统一策略
|
||||
|
||||
### 11.1 D3D12
|
||||
|
||||
目标:
|
||||
|
||||
- 直接消费 HLSL 编译产物
|
||||
- 反射得到 root signature / resource layout 所需元数据
|
||||
|
||||
第一阶段可继续沿用 `ps_5_0 / vs_5_0`,但建议同时规划升级:
|
||||
|
||||
- 后续逐步转 `SM 6.x`
|
||||
|
||||
### 11.2 Vulkan
|
||||
|
||||
目标:
|
||||
|
||||
- 统一吃由 HLSL 编到 SPIR-V 的产物
|
||||
- 摆脱独立 `.vk.glsl` 长期维护
|
||||
|
||||
### 11.3 OpenGL
|
||||
|
||||
目标:
|
||||
|
||||
- 不再长期维护独立 `.glsl` authoring 文件
|
||||
- importer 自动生成 OpenGL 目标 GLSL 430
|
||||
|
||||
这一步会是整个阶段最大的工程风险之一,但它是“写法统一”绕不开的核心点。
|
||||
|
||||
### 11.4 迁移期间的策略
|
||||
|
||||
在新体系落稳前,允许:
|
||||
|
||||
- legacy backend-specific variant 继续存在
|
||||
- 新 Unity 风格 shader 走统一 HLSL single-source 路径
|
||||
|
||||
两套 importer 并行一段时间,最终再逐步淘汰 legacy path。
|
||||
|
||||
---
|
||||
|
||||
## 12. 分阶段实施计划
|
||||
|
||||
### Phase A:冻结目标与建立兼容边界
|
||||
|
||||
目标:
|
||||
|
||||
- 明确“什么叫 Unity 风格 shader”
|
||||
- 明确 legacy 与新 authoring 的兼容边界
|
||||
|
||||
工作项:
|
||||
|
||||
1. 写清 Unity 风格支持子集。
|
||||
2. 明确旧 `.shader` 的 legacy 模式规则。
|
||||
3. 明确新 authoring 中禁止出现:
|
||||
- `#pragma backend`
|
||||
- `Resources(set,binding)`
|
||||
4. 明确 material 中 `shaderPass` 的弃用策略。
|
||||
|
||||
完成标准:
|
||||
|
||||
- 文档、命名、兼容边界全部写死
|
||||
|
||||
### Phase B:建立新的 Shader Authoring Parser 与 IR
|
||||
|
||||
目标:
|
||||
|
||||
- 新 `.shader` authoring 能导入到统一 `ShaderIR`
|
||||
|
||||
工作项:
|
||||
|
||||
1. 新增 parser,支持:
|
||||
- `Shader / Properties / SubShader / Pass / Tags`
|
||||
- `HLSLINCLUDE / HLSLPROGRAM`
|
||||
- `#pragma vertex / fragment / target / multi_compile / shader_feature`
|
||||
- pass state DSL
|
||||
2. 生成 `ShaderIR`
|
||||
3. 支持 include 依赖收集
|
||||
4. 保留 legacy importer
|
||||
|
||||
完成标准:
|
||||
|
||||
- authoring parser 单测齐全
|
||||
- 可以把一个 Unity 风格 shader 解析成稳定 IR
|
||||
|
||||
### Phase C:建立单一 HLSL 编译链
|
||||
|
||||
目标:
|
||||
|
||||
- 打通 `HLSL -> D3D12/Vulkan/OpenGL` 编译管线
|
||||
|
||||
工作项:
|
||||
|
||||
1. 接入 DXC 编译 HLSL。
|
||||
2. Vulkan 产出 SPIR-V。
|
||||
3. OpenGL 产出 GLSL 430。
|
||||
4. 建立 reflection 数据抽取:
|
||||
- cbuffer
|
||||
- texture
|
||||
- sampler
|
||||
- entry point
|
||||
- keywords
|
||||
5. 缓存编译产物与依赖 hash。
|
||||
|
||||
完成标准:
|
||||
|
||||
- 一份 HLSL authoring 能生成三后端产物
|
||||
- OpenGL 不再依赖手写 `.glsl` 作为新体系长期主路径
|
||||
|
||||
### Phase D:Material 与 property/keyword/runtime binding 正式化
|
||||
|
||||
目标:
|
||||
|
||||
- material 能正式驱动新 shader artifact
|
||||
|
||||
工作项:
|
||||
|
||||
1. 引入正式 property layout。
|
||||
2. 引入 material keyword set。
|
||||
3. 生成 `PerMaterial` 常量缓冲布局。
|
||||
4. texture/sampler 绑定从 reflection/约定生成。
|
||||
5. 让 material 运行时不再关心 `set/binding`。
|
||||
|
||||
完成标准:
|
||||
|
||||
- material property / texture / keyword 真正接入 GPU 绑定链
|
||||
|
||||
### Phase E:renderer pass 选择与 pipeline cache 收口
|
||||
|
||||
目标:
|
||||
|
||||
- renderer 完全按 pass contract 驱动 shader
|
||||
|
||||
工作项:
|
||||
|
||||
1. 按 `LightMode` 选 pass。
|
||||
2. `shaderPass` 降级为 legacy fallback。
|
||||
3. pipeline cache key 引入:
|
||||
- shader artifact id
|
||||
- pass id
|
||||
- keyword variant id
|
||||
- render state
|
||||
4. builtin pass 的 runtime contract 全部切到新 artifact。
|
||||
|
||||
完成标准:
|
||||
|
||||
- renderer 主路径不再依赖 material 显式 pass 指定
|
||||
|
||||
### Phase F:分批迁移 builtin shader
|
||||
|
||||
建议迁移顺序:
|
||||
|
||||
1. `unlit`
|
||||
2. `forward-lit`
|
||||
3. `depth-only`
|
||||
4. `shadow-caster`
|
||||
5. `object-id`
|
||||
6. `skybox`
|
||||
7. `color-scale-post-process`
|
||||
8. `final-color`
|
||||
|
||||
完成标准:
|
||||
|
||||
- builtin shader 全部有新 authoring 版本
|
||||
- 旧版 backend 分发文件不再是长期主定义来源
|
||||
|
||||
### Phase G:文档、测试、旧路径收口
|
||||
|
||||
目标:
|
||||
|
||||
- 让新旧体系的边界最终收口
|
||||
|
||||
工作项:
|
||||
|
||||
1. 更新 `tests/TEST_SPEC.md` 中 shader/material 测试矩阵。
|
||||
2. 增加 authoring parser / compiler / runtime 回归测试。
|
||||
3. 更新开发文档。
|
||||
4. 标记 legacy 路径弃用阶段。
|
||||
|
||||
完成标准:
|
||||
|
||||
- 新体系文档、测试、builtin 迁移都完成
|
||||
|
||||
---
|
||||
|
||||
## 13. 测试策略
|
||||
|
||||
### 13.1 Parser / Importer 单测
|
||||
|
||||
必须覆盖:
|
||||
|
||||
- Properties 解析
|
||||
- SubShader / Pass / Tags 解析
|
||||
- HLSLINCLUDE / HLSLPROGRAM 解析
|
||||
- pragma 解析
|
||||
- pass state 解析
|
||||
- include 依赖收集
|
||||
- legacy / 新 authoring 双路径兼容
|
||||
|
||||
### 13.2 Compiler 单测
|
||||
|
||||
必须覆盖:
|
||||
|
||||
- 单一 HLSL 源能生成三后端产物
|
||||
- reflection 结果稳定
|
||||
- keyword variant 正确展开
|
||||
- 编译错误日志可读、可定位到 authoring 源文件
|
||||
|
||||
### 13.3 Material 单测
|
||||
|
||||
必须覆盖:
|
||||
|
||||
- property 默认值
|
||||
- property override
|
||||
- texture binding
|
||||
- keyword set
|
||||
- 常量缓冲布局打包
|
||||
|
||||
### 13.4 Rendering 单测
|
||||
|
||||
必须覆盖:
|
||||
|
||||
- renderer 按 `LightMode` 选 pass
|
||||
- legacy `shaderPass` fallback 行为
|
||||
- keyword variant 参与 pipeline cache key
|
||||
- final color / post-process / shadow / object-id 不回退
|
||||
|
||||
### 13.5 集成测试
|
||||
|
||||
至少回归:
|
||||
|
||||
- `material_state_scene`
|
||||
- `transparent_material_scene`
|
||||
- `camera_stack_scene`
|
||||
- `directional_shadow_scene`
|
||||
- `multi_light_scene`
|
||||
- `skybox_scene`
|
||||
- `post_process_scene`
|
||||
- `final_color_scene`
|
||||
- `object_id_scene`
|
||||
|
||||
要求:
|
||||
|
||||
- 三后端全部跑通
|
||||
- GT 不回退
|
||||
|
||||
---
|
||||
|
||||
## 14. 风险与控制策略
|
||||
|
||||
### 风险 1:OpenGL 是统一写法最难的一环
|
||||
|
||||
原因:
|
||||
|
||||
- OpenGL 当前直接吃 GLSL
|
||||
- 统一 authoring 要求它改为编译链生成目标 GLSL
|
||||
|
||||
控制策略:
|
||||
|
||||
- 先把 importer/IR 做好
|
||||
- OpenGL 先走“生成 GLSL 文本产物”路径
|
||||
- legacy OpenGL GLSL 文件在迁移期保留 fallback
|
||||
|
||||
### 风险 2:一次性追 full Unity 语法会把阶段拖爆
|
||||
|
||||
控制策略:
|
||||
|
||||
- 明确 first-class 子集
|
||||
- 先做 SRP 真正依赖的 authoring 基础
|
||||
- 非关键语法延后
|
||||
|
||||
### 风险 3:material / pass 迁移会破坏当前 builtin renderer
|
||||
|
||||
控制策略:
|
||||
|
||||
- legacy runtime path 保留一段时间
|
||||
- builtin shader 分批迁移
|
||||
- 每迁移一个 shader 就跑对应 integration
|
||||
|
||||
### 风险 4:编译错误如果不可读,会极大拖慢落地
|
||||
|
||||
控制策略:
|
||||
|
||||
- 必须做 authoring 源到 backend 编译日志的映射
|
||||
- 错误日志要带 shader 名、pass 名、stage、backend、源文件行号
|
||||
|
||||
---
|
||||
|
||||
## 15. 收口判定
|
||||
|
||||
满足下面条件时,本阶段可视为完成:
|
||||
|
||||
1. 新 `.shader` authoring 采用 Unity 风格子集。
|
||||
2. 新体系 shader authoring 中不再出现 `#pragma backend`。
|
||||
3. 新体系 shader authoring 中不再出现 `Resources(set,binding)`。
|
||||
4. HLSL single-source 能生成 D3D12 / Vulkan / OpenGL 三后端产物。
|
||||
5. material 已正式接入 property / keyword / texture binding runtime。
|
||||
6. renderer 按 `LightMode` 正式选择 pass。
|
||||
7. `shaderPass` 只剩 legacy fallback,不再是主路径。
|
||||
8. builtin shader 已完成新体系迁移。
|
||||
9. 三后端关键集成测试全部通过。
|
||||
|
||||
---
|
||||
|
||||
## 16. 与后续 SRP 的承接关系
|
||||
|
||||
这一阶段完成后,才能真正自然地承接:
|
||||
|
||||
- `RenderPipelineAsset`
|
||||
- `RenderPipeline`
|
||||
- `RendererFeature`
|
||||
- `ScriptableRenderPass`
|
||||
- C# 层对 shader/material/keyword 的控制
|
||||
|
||||
承接关系应当是:
|
||||
|
||||
```text
|
||||
Unity-style Shader Authoring
|
||||
-> Shader Importer / IR / Artifact
|
||||
-> Native Material & Pass Runtime
|
||||
-> Native Renderer Pass Contract
|
||||
-> C# SRP / RendererFeature
|
||||
```
|
||||
|
||||
也就是说:
|
||||
|
||||
- 这一阶段不是 SRP
|
||||
- 但这是 SRP 成立前必须先做完的最后一层底座
|
||||
|
||||
---
|
||||
|
||||
## 17. 一句话总结
|
||||
|
||||
当前 shader 体系不是没有,而是还停在“过渡态”。
|
||||
|
||||
下一阶段的正确方向不是继续堆更多 shader 功能,而是:
|
||||
|
||||
- **把 `.shader` 的 authoring 真正统一成 Unity 风格**
|
||||
- **把 backend 差异与 binding 细节收回 importer / compiler 层**
|
||||
- **把 material / pass / variant/runtime contract 一次性做正式**
|
||||
|
||||
只有这样,后面的 SRP 才不会建立在一层伪统一的 shader 体系上。
|
||||
462
docs/used/Renderer下一阶段_方向光阴影与光照闭环计划_完成归档_2026-04-05.md
Normal file
462
docs/used/Renderer下一阶段_方向光阴影与光照闭环计划_完成归档_2026-04-05.md
Normal file
@@ -0,0 +1,462 @@
|
||||
# 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。
|
||||
应由 `SceneRenderer` 或 `CameraRenderer` 在主 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 C:SceneView / GameView runtime 接入收紧
|
||||
|
||||
### 目标
|
||||
|
||||
让 editor 的场景与游戏视图都建立在同一套 runtime renderer 能力上,而不是继续沿着临时 editor 路径分叉。
|
||||
|
||||
### 具体工作
|
||||
|
||||
#### C1. 明确 runtime pass 与 editor overlay pass 的边界
|
||||
|
||||
正式定义:
|
||||
|
||||
- runtime 正式 pass:shadow caster、depth only、forward、object-id、offscreen copy 等
|
||||
- editor 附加 pass:grid、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 风格前向运行时。**
|
||||
556
docs/used/Renderer模块设计与实现.md
Normal file
556
docs/used/Renderer模块设计与实现.md
Normal file
@@ -0,0 +1,556 @@
|
||||
# Renderer模块设计与实现
|
||||
|
||||
## 1. 背景
|
||||
|
||||
XCEngine 当前已经完成了较为可用的 RHI 抽象层,且已经具备:
|
||||
|
||||
- `Scene + GameObject + Component` 基础场景模型
|
||||
- `CameraComponent` / `LightComponent` 等基础组件
|
||||
- `Mesh` / `Material` / `Texture` / `Shader` 等资源类型
|
||||
- D3D12 / OpenGL 双后端 RHI 抽象与测试体系
|
||||
|
||||
下一阶段不应该继续封闭式打磨 RHI,而应该在 RHI 之上正式建立 **Renderer 模块**。
|
||||
|
||||
这里的 Renderer 模块不是“最终形态的 SRP”,而是:
|
||||
|
||||
- 先建立一层 **原生渲染运行时**
|
||||
- 先让场景对象能够以正式渲染链路被绘制
|
||||
- 同时在设计上预留未来 **C# Scriptable Render Pipeline(SRP)** 的接入点
|
||||
|
||||
也就是说,当前阶段的正确目标不是直接实现 Unity 的 URP/HDRP,而是先建立一套 **与 Unity 渲染架构方向一致的原生基础层**,后续让 C# SRP 驱动它。
|
||||
|
||||
---
|
||||
|
||||
## 2. 设计目标
|
||||
|
||||
Renderer 模块的目标分为两层:
|
||||
|
||||
### 2.1 当前阶段目标
|
||||
|
||||
先完成一套最小但完整的原生渲染链路:
|
||||
|
||||
- 从 `Scene` 中提取可渲染对象
|
||||
- 通过 `Camera` 构建视图与投影数据
|
||||
- 通过 `Material` / `Mesh` / `Texture` 构建 GPU 绘制数据
|
||||
- 在 RHI 之上完成正式的 frame 渲染
|
||||
- 支持 swapchain 输出与离屏输出
|
||||
- 建立独立于 editor 的渲染宿主模型
|
||||
|
||||
### 2.2 面向未来 C# SRP 的目标
|
||||
|
||||
当前阶段的实现必须为后续演进预留稳定边界:
|
||||
|
||||
- 未来允许用 C# 定义 `RenderPipelineAsset` / `RenderPipeline`
|
||||
- 未来允许用 C# 组织 render pass
|
||||
- 未来允许 editor `SceneView` / `GameView` 通过同一套 renderer 输出
|
||||
- 未来允许 C# 脚本控制 camera 渲染、pass 排序、目标输出与 command buffer
|
||||
|
||||
因此,当前阶段的原生 Renderer 不能做成一个写死的“大一统内建渲染函数”,而应该一开始就具备“可被上层 pipeline 驱动”的结构。
|
||||
|
||||
---
|
||||
|
||||
## 3. 与 Unity 渲染架构的对应关系
|
||||
|
||||
当前建议的路线与 Unity 的总体方向是对齐的,但要注意分层位置。
|
||||
|
||||
### 3.1 推荐分层
|
||||
|
||||
```text
|
||||
Scene / Components / Resources
|
||||
↓
|
||||
Renderer 模块(原生渲染运行时)
|
||||
↓
|
||||
未来 C# SRP 层(脚本化渲染管线)
|
||||
↓
|
||||
RHI 抽象层
|
||||
↓
|
||||
D3D12 / OpenGL / Vulkan 后端
|
||||
```
|
||||
|
||||
### 3.2 各层职责
|
||||
|
||||
#### Scene / Components / Resources
|
||||
|
||||
负责描述“要渲染什么”,例如:
|
||||
|
||||
- 场景对象
|
||||
- 相机
|
||||
- 灯光
|
||||
- 网格
|
||||
- 材质
|
||||
- 贴图
|
||||
|
||||
这一层不应该直接持有后端 API 对象。
|
||||
|
||||
#### Renderer 模块(本阶段核心)
|
||||
|
||||
负责描述“如何从场景变成 draw call”,例如:
|
||||
|
||||
- 渲染对象抽取
|
||||
- 可见性裁剪
|
||||
- GPU 资源缓存
|
||||
- camera frame 数据组织
|
||||
- render target / depth target 管理
|
||||
- render pass 调度
|
||||
- 内建前向管线
|
||||
|
||||
这一层是未来 C# SRP 的原生支撑层。
|
||||
|
||||
#### 未来 C# SRP 层
|
||||
|
||||
负责描述“以脚本方式控制渲染流程”,例如:
|
||||
|
||||
- `RenderPipelineAsset`
|
||||
- `RenderPipeline`
|
||||
- `ScriptableRenderContext`
|
||||
- `CommandBuffer`
|
||||
- `RenderPassEvent`
|
||||
- pass 注入与重排
|
||||
|
||||
这一层不应该直接绕过 Renderer 模块去操作后端 API。
|
||||
|
||||
#### RHI 抽象层
|
||||
|
||||
负责统一 GPU 接口与资源对象,是渲染系统的执行后端,而不是场景渲染逻辑本身。
|
||||
|
||||
### 3.3 与 Unity 的概念映射
|
||||
|
||||
| Unity 概念 | XCEngine 当前/规划对应 |
|
||||
|---|---|
|
||||
| `Camera` | `CameraComponent` |
|
||||
| `Light` | `LightComponent` |
|
||||
| `MeshFilter` | 计划新增 `MeshFilterComponent` |
|
||||
| `MeshRenderer` | 计划新增 `MeshRendererComponent` |
|
||||
| `RenderPipelineAsset` | 未来 Renderer 模块上的 pipeline asset 抽象 |
|
||||
| `RenderPipeline` | 未来 Renderer 模块上的 pipeline 实例抽象 |
|
||||
| `ScriptableRenderContext` | 未来 Renderer 模块对脚本暴露的原生 render context |
|
||||
| `CommandBuffer` | 未来 Renderer 模块对脚本暴露的命令缓冲抽象 |
|
||||
| `GraphicsDevice` / native render backend | 当前 RHI + 后端实现 |
|
||||
|
||||
结论是:
|
||||
|
||||
- **方向上符合 Unity 渲染架构**
|
||||
- **当前阶段实现的应是 Unity 渲染体系中的原生底座**
|
||||
- **而不是直接跳到最终的脚本化 SRP**
|
||||
|
||||
---
|
||||
|
||||
## 4. 核心设计原则
|
||||
|
||||
### 4.1 先建立原生渲染运行时,再开放脚本化管线
|
||||
|
||||
如果现在直接做 C# SRP,而原生 Renderer 边界还不存在,后续会出现:
|
||||
|
||||
- C# API 直接耦合 RHI
|
||||
- editor viewport 与 runtime camera 逻辑混杂
|
||||
- 资源对象与 GPU 对象生命周期混乱
|
||||
|
||||
因此必须先收敛原生 Renderer 模块。
|
||||
|
||||
### 4.2 Scene 层只描述逻辑对象,不持有后端对象
|
||||
|
||||
`GameObject`、`Component`、`Mesh`、`Material` 等对象只能描述逻辑与资源,不应该直接持有 D3D12/OpenGL 私有对象。
|
||||
|
||||
GPU 对象应由 Renderer 内部缓存层负责创建和复用。
|
||||
|
||||
### 4.3 editor 只是渲染宿主,不是渲染逻辑本体
|
||||
|
||||
`GameView` / `SceneView` 最终只是 Renderer 的输出宿主。
|
||||
|
||||
Renderer 本身必须先支持:
|
||||
|
||||
- 输出到 swapchain
|
||||
- 输出到离屏纹理
|
||||
|
||||
然后 editor 再把离屏纹理接进 ImGui 面板。
|
||||
|
||||
### 4.4 为未来 SRP 预留 pipeline 抽象
|
||||
|
||||
即使第一阶段先做内建前向渲染,也不应该把逻辑写死成单一 `SceneRenderer::DrawEverything()`。
|
||||
|
||||
应该从一开始就保留:
|
||||
|
||||
- `RenderPipeline`
|
||||
- `RenderPipelineAsset`
|
||||
- `RenderContext`
|
||||
- camera 列表驱动
|
||||
- pass 分阶段执行
|
||||
|
||||
这样未来 C# 只是在这个原生结构上做绑定,而不是重做一遍架构。
|
||||
|
||||
### 4.5 测试体系与渲染层分离
|
||||
|
||||
`tests/RHI/` 继续只验证 RHI。
|
||||
|
||||
Renderer 模块应建立自己的测试体系:
|
||||
|
||||
- `tests/Rendering/unit/`
|
||||
- `tests/Rendering/integration/`
|
||||
|
||||
这样职责边界才清晰。
|
||||
|
||||
---
|
||||
|
||||
## 5. 模块划分建议
|
||||
|
||||
建议新增 `Rendering` 模块,作为场景与 RHI 之间的正式中间层。
|
||||
|
||||
### 5.1 推荐目录结构
|
||||
|
||||
```text
|
||||
engine/
|
||||
├── include/XCEngine/Rendering/
|
||||
│ ├── RenderSurface.h
|
||||
│ ├── RenderContext.h
|
||||
│ ├── RenderPipeline.h
|
||||
│ ├── RenderPipelineAsset.h
|
||||
│ ├── SceneRenderer.h
|
||||
│ ├── RenderSceneExtractor.h
|
||||
│ ├── RenderCameraData.h
|
||||
│ ├── VisibleRenderObject.h
|
||||
│ ├── RenderResourceCache.h
|
||||
│ └── Pipelines/
|
||||
│ └── BuiltinForwardPipeline.h
|
||||
└── src/Rendering/
|
||||
├── RenderSurface.cpp
|
||||
├── SceneRenderer.cpp
|
||||
├── RenderSceneExtractor.cpp
|
||||
├── RenderResourceCache.cpp
|
||||
└── Pipelines/
|
||||
└── BuiltinForwardPipeline.cpp
|
||||
```
|
||||
|
||||
### 5.2 组件层建议
|
||||
|
||||
为了尽可能对齐 Unity,而不是做一个临时过渡方案,建议直接采用:
|
||||
|
||||
- `MeshFilterComponent`
|
||||
- `MeshRendererComponent`
|
||||
|
||||
其中:
|
||||
|
||||
#### `MeshFilterComponent`
|
||||
|
||||
负责“这个对象使用哪一个 mesh”:
|
||||
|
||||
- `ResourceHandle<Mesh>`
|
||||
|
||||
#### `MeshRendererComponent`
|
||||
|
||||
负责“这个对象如何被渲染”:
|
||||
|
||||
- 材质数组
|
||||
- cast shadow / receive shadow
|
||||
- render queue / layer / enable 状态
|
||||
- 未来可扩展 light probe / motion vector / static batching 标记
|
||||
|
||||
这样做的好处是:
|
||||
|
||||
- 更贴近 Unity 的对象模型
|
||||
- 更容易映射未来 C# API
|
||||
- 更容易在 editor Inspector 中呈现
|
||||
- 更容易为 `SkinnedMeshRenderer`、`SpriteRenderer` 等后续组件扩展留位置
|
||||
|
||||
### 5.3 Renderer 内部运行时对象
|
||||
|
||||
#### `RenderSurface`
|
||||
|
||||
统一表示渲染输出目标:
|
||||
|
||||
- 交换链输出
|
||||
- 离屏 color/depth 输出
|
||||
- editor viewport 输出
|
||||
|
||||
#### `RenderSceneExtractor`
|
||||
|
||||
负责从 `Scene` 中提取本帧可渲染对象:
|
||||
|
||||
- mesh
|
||||
- material
|
||||
- transform
|
||||
- bounds
|
||||
- render state
|
||||
|
||||
#### `RenderResourceCache`
|
||||
|
||||
负责把资源模块对象转成 GPU 可用对象:
|
||||
|
||||
- mesh -> vertex/index buffer
|
||||
- texture -> RHI texture / resource view
|
||||
- material -> descriptor set / uniform buffer / pipeline key
|
||||
- shader pass -> pipeline state
|
||||
|
||||
#### `RenderContext`
|
||||
|
||||
作为原生渲染执行上下文,未来用于承接脚本化 pipeline 的调度。
|
||||
|
||||
它应封装:
|
||||
|
||||
- 当前 frame 的 command list
|
||||
- render target 设置
|
||||
- clear / draw / submit
|
||||
- camera 相关渲染上下文
|
||||
|
||||
#### `RenderPipeline`
|
||||
|
||||
用于抽象具体渲染流程。
|
||||
|
||||
第一阶段只有一个原生内建实现:
|
||||
|
||||
- `BuiltinForwardPipeline`
|
||||
|
||||
未来再开放:
|
||||
|
||||
- native 可切换 pipeline
|
||||
- C# 绑定的 scriptable pipeline
|
||||
|
||||
---
|
||||
|
||||
## 6. 第一阶段实现边界
|
||||
|
||||
第一阶段只做最小可用链路,不做“大而全”。
|
||||
|
||||
### 6.1 第一阶段要做
|
||||
|
||||
- `Rendering` 模块骨架
|
||||
- `MeshFilterComponent` / `MeshRendererComponent`
|
||||
- `RenderSurface`
|
||||
- `RenderSceneExtractor`
|
||||
- `RenderResourceCache`
|
||||
- `SceneRenderer`
|
||||
- `BuiltinForwardPipeline`
|
||||
- 单 camera
|
||||
- 单方向的 opaque forward 渲染
|
||||
- 深度测试与深度写入
|
||||
- 交换链输出
|
||||
- 离屏输出
|
||||
|
||||
### 6.2 第一阶段先不做
|
||||
|
||||
- 阴影
|
||||
- 后处理
|
||||
- 延迟渲染
|
||||
- 完整 PBR
|
||||
- render graph
|
||||
- C# SRP 真正落地
|
||||
- editor viewport 完整交互
|
||||
- 多 camera 叠加
|
||||
|
||||
### 6.3 第一阶段材质能力建议
|
||||
|
||||
建议先支持两档:
|
||||
|
||||
1. `UnlitTexture`
|
||||
2. `SimpleLit`
|
||||
|
||||
其中:
|
||||
|
||||
- `UnlitTexture` 用于先打通最小链路
|
||||
- `SimpleLit` 用于验证灯光、法线与材质基础通路
|
||||
|
||||
---
|
||||
|
||||
## 7. 面向未来 C# SRP 的预留设计
|
||||
|
||||
虽然第一阶段先做原生内建渲染,但必须提前约束下面这些方向。
|
||||
|
||||
### 7.1 先定义 pipeline 边界,再定义内建实现
|
||||
|
||||
正确顺序应当是:
|
||||
|
||||
1. 先定义 `RenderPipeline` 抽象
|
||||
2. 再实现 `BuiltinForwardPipeline`
|
||||
3. 后续 C# SRP 只是在这个边界上做脚本绑定
|
||||
|
||||
而不是:
|
||||
|
||||
1. 先写死一个 `SceneRenderer`
|
||||
2. 以后再强行拆成 pipeline
|
||||
|
||||
第二种方式后续返工会很大。
|
||||
|
||||
### 7.2 Renderer 模块应向未来脚本层暴露的概念
|
||||
|
||||
当前阶段不一定全部实现,但结构上要留位置:
|
||||
|
||||
- `RenderPipelineAsset`
|
||||
- `RenderPipeline`
|
||||
- `RenderContext`
|
||||
- `CullingResults`
|
||||
- `DrawingSettings`
|
||||
- `FilteringSettings`
|
||||
- `ShaderTag`
|
||||
- `CommandBuffer`
|
||||
- `RendererList`
|
||||
|
||||
这些概念不一定要立刻与 Unity 一字不差,但应该在职责上能对应上。
|
||||
|
||||
### 7.3 材质与 Shader 资产模型不能停留在“单 shader 文件 + 属性包”
|
||||
|
||||
未来做 SRP 时,shader pass 选择、render queue、tag、render state 都是必要能力。
|
||||
|
||||
因此当前阶段即使先不全量实现,也不能把资产模型彻底锁死在过于简单的结构上。
|
||||
|
||||
这一点单独列为 issue。
|
||||
|
||||
---
|
||||
|
||||
## 8. 分阶段推进建议
|
||||
|
||||
### 阶段 A:Renderer v0 骨架
|
||||
|
||||
目标:
|
||||
|
||||
- 建立 `Rendering` 模块
|
||||
- 建立 `MeshFilterComponent` / `MeshRendererComponent`
|
||||
- 建立 `RenderSurface`
|
||||
- 建立 `BuiltinForwardPipeline`
|
||||
|
||||
验收:
|
||||
|
||||
- 可以通过 Renderer 正式绘制一个 textured quad 场景
|
||||
- 输出到 swapchain
|
||||
- 输出到离屏 RT
|
||||
|
||||
### 阶段 B:真实资源场景接入
|
||||
|
||||
目标:
|
||||
|
||||
- 接入 mesh / texture / material 资源模块
|
||||
- 跑通 `backpack` 这样的真实模型场景
|
||||
|
||||
验收:
|
||||
|
||||
- 真实 obj 资源经资源模块导入后可通过 Renderer 正式绘制
|
||||
- D3D12 / OpenGL 双后端结果一致
|
||||
|
||||
### 阶段 C:基础光照
|
||||
|
||||
目标:
|
||||
|
||||
- 接入 `LightComponent`
|
||||
- 跑通最基础的单方向光前向渲染
|
||||
|
||||
验收:
|
||||
|
||||
- `sphere` / `backpack` 存在正确基础明暗
|
||||
- 材质参数与法线链路可验证
|
||||
|
||||
### 阶段 D:pipeline 抽象显式化
|
||||
|
||||
目标:
|
||||
|
||||
- 把内建前向渲染切到 `RenderPipeline` 抽象之下
|
||||
- 支持 camera 列表驱动
|
||||
- 为未来 C# SRP 绑定准备原生接口
|
||||
|
||||
验收:
|
||||
|
||||
- 原生内建 pipeline 通过统一接口驱动
|
||||
- renderer 不再依赖单一路径写死执行
|
||||
|
||||
### 阶段 E:editor viewport 接入
|
||||
|
||||
目标:
|
||||
|
||||
- `SceneView` / `GameView` 使用 Renderer 的离屏输出
|
||||
|
||||
验收:
|
||||
|
||||
- editor 面板只是渲染宿主
|
||||
- 不额外复制一套渲染逻辑
|
||||
|
||||
### 阶段 F:C# SRP 桥接
|
||||
|
||||
目标:
|
||||
|
||||
- 在既有 Renderer 模块基础上绑定脚本化 pipeline
|
||||
|
||||
验收:
|
||||
|
||||
- C# 可以控制 camera 渲染流程
|
||||
- 原生 Renderer 继续负责底层资源、上下文与执行
|
||||
|
||||
---
|
||||
|
||||
## 9. 测试体系建议
|
||||
|
||||
Renderer 模块需要独立测试体系。
|
||||
|
||||
### 9.1 单元测试
|
||||
|
||||
建议放在:
|
||||
|
||||
- `tests/Rendering/unit/`
|
||||
|
||||
测试内容:
|
||||
|
||||
- render object 抽取
|
||||
- material 参数打包
|
||||
- pipeline key 构建
|
||||
- GPU cache 命中与失效
|
||||
- render surface 创建与 resize
|
||||
|
||||
### 9.2 集成测试
|
||||
|
||||
建议放在:
|
||||
|
||||
- `tests/Rendering/integration/`
|
||||
|
||||
建议场景:
|
||||
|
||||
1. `textured_quad_scene`
|
||||
2. `backpack_scene`
|
||||
3. `lit_sphere_scene`
|
||||
|
||||
仍然维持当前 RHI 抽象测试的好习惯:
|
||||
|
||||
- 一场景一张 `GT.ppm`
|
||||
- D3D12 / OpenGL 都与同一张 GT 比对
|
||||
|
||||
### 9.3 与 RHI 测试的关系
|
||||
|
||||
`tests/RHI/` 继续用于验证:
|
||||
|
||||
- API 抽象正确性
|
||||
- 后端行为一致性
|
||||
- 资源 / 命令 /格式映射等底层问题
|
||||
|
||||
`tests/Rendering/` 则验证:
|
||||
|
||||
- 场景渲染链路
|
||||
- 组件与资源到渲染结果的闭环
|
||||
|
||||
---
|
||||
|
||||
## 10. 当前已识别的不适配问题
|
||||
|
||||
以下问题不适合直接塞进本设计文档正文实现里,而应该独立跟踪:
|
||||
|
||||
1. `Scene / Components` 层还没有 `MeshFilter / MeshRenderer` 抽象
|
||||
2. `Editor` 还没有 viewport 的离屏渲染宿主接入层
|
||||
3. `Material / Shader` 资产模型还不足以支撑未来 SRP 的 pass/tag 语义
|
||||
|
||||
对应 issue:
|
||||
|
||||
- `docs/issues/Renderer模块_Scene层缺少MeshFilter与MeshRenderer抽象.md`
|
||||
- `docs/issues/Renderer模块_EditorViewport缺少RenderSurface接入层.md`
|
||||
- `docs/issues/Renderer模块_Material与Shader资产模型暂不满足SRP演进需求.md`
|
||||
|
||||
---
|
||||
|
||||
## 11. 结论
|
||||
|
||||
当前 Renderer 阶段的正确方向是:
|
||||
|
||||
- 在 RHI 之上建立 **原生渲染运行时**
|
||||
- 用它先承接基础前向渲染
|
||||
- 同时提前为未来 **C# SRP** 留出清晰接口
|
||||
|
||||
因此,下一阶段的 Renderer 规划如果按本文执行,是与 Unity 渲染架构方向相容的,而且比“先做一个临时内建 renderer,后面再拆”更稳。
|
||||
|
||||
一句话概括:
|
||||
|
||||
- **现在做的是 Unity 式渲染体系的原生底座**
|
||||
- **以后在这个底座之上接 C# SRP**
|
||||
|
||||
415
docs/used/Renderer结构收口与代码正式化计划_完成归档_2026-04-05.md
Normal file
415
docs/used/Renderer结构收口与代码正式化计划_完成归档_2026-04-05.md
Normal file
@@ -0,0 +1,415 @@
|
||||
# Renderer 结构收口与代码正式化计划
|
||||
日期:`2026-04-05`
|
||||
|
||||
## 1. 阶段定位
|
||||
|
||||
当前 Rendering 主线在功能上已经完成了相当多闭环:
|
||||
|
||||
- 三后端统一的 runtime renderer 主链已经建立
|
||||
- directional shadow、multi-light、object-id、editor overlay 等能力都已接入
|
||||
- SceneView / GameView 基本共用了同一条 runtime 渲染路径
|
||||
|
||||
但从代码结构和职责边界上看,这一阶段还没有真正收口。现在的问题已经不再是“某个功能没接上”,而是:
|
||||
|
||||
**renderer 的核心模块里仍然混有明显的阶段性写法、特殊分支、职责堆叠和 editor/runtime 边界不清的问题。**
|
||||
|
||||
如果此时直接继续往上叠 skybox、环境、后处理、更多 renderer feature,后面会越来越难拆,最终重新把已经相对稳定的 renderer 主链拖回到“能跑但很难维护”的状态。
|
||||
|
||||
因此,本阶段的唯一目标不是加新功能,而是:
|
||||
|
||||
**把当前 renderer 这一阶段真正做成可持续演进的正式结构,为后续 Skybox / Environment / PostProcess / 更正式的 SRP 承接清掉结构债。**
|
||||
|
||||
## 2. 为什么现在必须先做结构收口
|
||||
|
||||
这不是“目录看着乱一点”的表面问题,而是已经影响后续演进的实质性架构问题。
|
||||
|
||||
### 2.1 `CameraRenderer` 仍然存在特殊通道
|
||||
|
||||
当前 `CameraRenderer` 虽然已经具备请求规划与多阶段执行能力,但 `object-id` 仍然是单独的一套特殊路径,而不是正式 frame composition 里的统一 pass 节点。
|
||||
|
||||
这带来的问题:
|
||||
|
||||
- 相机级执行顺序不是单一模型,而是“主链 + 特判”
|
||||
- 后续 skybox / post-process / capture / debug target 更难正规接入
|
||||
- 单元测试里被迫维护特殊 mock pass 类型,而不是统一的 pass contract
|
||||
|
||||
关键文件:
|
||||
|
||||
- `engine/include/XCEngine/Rendering/ObjectIdPass.h`
|
||||
- `engine/include/XCEngine/Rendering/CameraRenderer.h`
|
||||
- `engine/include/XCEngine/Rendering/CameraRenderRequest.h`
|
||||
- `engine/src/Rendering/CameraRenderer.cpp`
|
||||
|
||||
### 2.2 `BuiltinForwardPipeline.cpp` 已经是典型 god file
|
||||
|
||||
这个文件里当前同时混着:
|
||||
|
||||
- pass wrapper
|
||||
- shader pass resolve
|
||||
- graphics pipeline 创建
|
||||
- descriptor set layout 规划
|
||||
- descriptor set 资源写入
|
||||
- lighting 常量打包
|
||||
- material fallback
|
||||
- draw submission
|
||||
|
||||
这已经不是“文件有点长”,而是职责拆分失败。后续任何修改都会把高层语义、资源绑定、RHI 细节、draw 级逻辑一起牵动,测试也只能做大颗粒回归,无法精准保护。
|
||||
|
||||
关键文件:
|
||||
|
||||
- `engine/src/Rendering/Pipelines/BuiltinForwardPipeline.cpp`
|
||||
|
||||
### 2.3 `RenderMaterialUtility.h` 混合了契约、兼容层和运行时解析
|
||||
|
||||
当前这个头里至少混了五类职责:
|
||||
|
||||
- builtin pass contract 定义
|
||||
- shader/property/binding 查询
|
||||
- descriptor layout 规划
|
||||
- legacy/material fallback 兼容
|
||||
- runtime material resolve 与绑定辅助
|
||||
|
||||
这会导致:
|
||||
|
||||
- “正式 contract” 与 “过渡兼容逻辑” 难以分开演进
|
||||
- 很多 renderer 代码只能依赖一个超大工具头
|
||||
- 头文件膨胀,职责不可读,接口边界不清
|
||||
|
||||
关键文件:
|
||||
|
||||
- `engine/include/XCEngine/Rendering/RenderMaterialUtility.h`
|
||||
|
||||
### 2.4 editor / debug pass 仍然混在 runtime renderer 核心层里
|
||||
|
||||
grid、outline 这些能力现在已经走到了比较正式的 runtime host path,但它们在 engine 里的组织方式仍然更接近“把 editor 需求塞进 renderer 核心”。
|
||||
|
||||
风险在于:
|
||||
|
||||
- runtime 核心会继续被 editor 语义污染
|
||||
- 后续 scene/game/editor 三条宿主路径边界会再次变模糊
|
||||
- 玩家运行时和编辑器专用渲染能力的依赖关系难以长期维护
|
||||
|
||||
关键文件:
|
||||
|
||||
- `engine/include/XCEngine/Rendering/Passes/BuiltinInfiniteGridPass.h`
|
||||
- `engine/include/XCEngine/Rendering/Passes/BuiltinObjectIdOutlinePass.h`
|
||||
|
||||
### 2.5 文件拆分层次仍然不干净
|
||||
|
||||
例如 `BuiltinDepthStylePassBase.cpp` 的底部还直接放着 `BuiltinDepthOnlyPass`、`BuiltinShadowCasterPass` 具体实现,这说明“抽象基类”和“具体 pass”仍然没有彻底分层。
|
||||
|
||||
关键文件:
|
||||
|
||||
- `engine/src/Rendering/Passes/BuiltinDepthStylePassBase.cpp`
|
||||
|
||||
### 2.6 少量稳定性问题仍然暴露出“临时写法”
|
||||
|
||||
比如 scene extractor 里 visible item 的稳定排序仍然用 raw pointer 作为 tie-breaker,而 additional light 已经升级成了稳定的 `GameObject::ID` 语义。
|
||||
|
||||
这类问题虽然不大,但非常能说明当前代码里仍混有阶段性临时写法,必须顺手清理干净。
|
||||
|
||||
关键文件:
|
||||
|
||||
- `engine/src/Rendering/RenderSceneExtractor.cpp`
|
||||
|
||||
## 3. 本阶段的核心设计原则
|
||||
|
||||
本阶段继续严格遵循当前工程既定设计理念,并与 `RHI模块总览` 中的核心原则保持一致:
|
||||
|
||||
1. `RHI` 只负责 GPU 抽象,不感知 object-id、grid、outline、skybox、post-process 等高层语义。
|
||||
2. `Renderer` 负责 scene extraction、frame composition、material/shader contract、runtime pass orchestration。
|
||||
3. `Editor` 只作为 renderer 的宿主和扩展使用方,不把 editor 语义反向污染 RHI。
|
||||
4. 兼容层和正式 contract 必须拆开,不能继续把“临时兜底”混在正式主链里。
|
||||
5. 不引入 `render graph`。本阶段先把现有 renderer 结构做正式化,不跳级优化。
|
||||
6. 不做“修修补补式”文件搬家,必须同时修职责边界、执行路径和测试结构。
|
||||
|
||||
## 4. 阶段总目标
|
||||
|
||||
本阶段收口完成后,应达到以下状态:
|
||||
|
||||
1. `CameraRenderer` 形成单一、明确、可测试的 frame composition 模型。
|
||||
2. runtime pass 与 object-id / editor-debug pass 的边界清晰,接入点正式化。
|
||||
3. `BuiltinForwardPipeline` 不再由一个 god file 承担所有责任。
|
||||
4. `RenderMaterialUtility` 被拆分为“正式 contract 层”和“兼容/运行时辅助层”。
|
||||
5. renderer 文件结构与代码结构一致,抽象基类、具体 pass、绑定辅助、compat helper 各归其位。
|
||||
6. 当前所有 rendering / editor 相关测试继续通过,不破坏已闭环功能。
|
||||
|
||||
## 5. 非目标
|
||||
|
||||
本阶段明确不做:
|
||||
|
||||
- `render graph`
|
||||
- deferred / clustered / tiled lighting
|
||||
- 新一轮 editor 视觉特效堆叠
|
||||
- 大规模 shader authoring 体系重写
|
||||
- point / spot shadow
|
||||
- 重新设计 RHI
|
||||
|
||||
## 6. 分阶段执行方案
|
||||
|
||||
## 6.1 Phase A:Camera Frame Composition 正式化
|
||||
|
||||
### 目标
|
||||
|
||||
消灭 `CameraRenderer` 里 object-id 的特殊执行通道,把相机级执行模型统一成正式 frame composition。
|
||||
|
||||
### 要解决的根因
|
||||
|
||||
- 现在相机渲染顺序不是单一 contract
|
||||
- `ObjectIdPass` 是旁路抽象,不利于后续继续扩展 composition
|
||||
- 测试里存在针对 object-id 的特殊 mock pass 体系
|
||||
|
||||
### 具体工作
|
||||
|
||||
1. 重新审视 `CameraRenderRequest` 的阶段描述,明确:
|
||||
- pre-scene
|
||||
- shadow/depth
|
||||
- scene pipeline
|
||||
- auxiliary offscreen passes
|
||||
- post-scene
|
||||
- overlay
|
||||
2. 去掉 `ObjectIdPass` 作为并行特例抽象的地位。
|
||||
3. 把 object-id 统一纳入正式 pass 执行序列,必要时通过 pass category / target intent 标识语义,而不是再保留独立虚函数族。
|
||||
4. 简化 `CameraRenderer` 执行逻辑,让失败传播、目标准备、pass 顺序只走一套主链。
|
||||
5. 同步收敛相关单元测试,让测试验证“阶段顺序”和“失败传播”,而不是验证某个特判分支。
|
||||
|
||||
### 验收标准
|
||||
|
||||
- `CameraRenderer` 不再对 object-id 走特判主逻辑
|
||||
- `test_camera_scene_renderer` 等单测仍覆盖 object-id 顺序与失败传播
|
||||
- editor viewport object-id picking 不回退
|
||||
|
||||
### 计划提交点
|
||||
|
||||
这一阶段完成后立即提交推送一次。
|
||||
|
||||
## 6.2 Phase B:BuiltinForwardPipeline 职责拆分
|
||||
|
||||
### 目标
|
||||
|
||||
把 `BuiltinForwardPipeline.cpp` 从 god file 拆成正式的职责层次,但不改变现有 forward runtime 的对外行为。
|
||||
|
||||
### 要解决的根因
|
||||
|
||||
- pipeline resolve、resource layout、descriptor write、material resolve、lighting packing、draw submission 全部耦合
|
||||
- 任何小修改都会波及整个文件
|
||||
- 难以为 skybox / post-process / future pipeline 承接建立稳定接口
|
||||
|
||||
### 具体工作
|
||||
|
||||
1. 先按职责切出独立模块,优先拆成以下几层:
|
||||
- shader/pass resolve
|
||||
- pipeline cache/build
|
||||
- resource binding layout / descriptor planning
|
||||
- frame-scoped lighting / pass constants upload
|
||||
- draw item submission
|
||||
2. 让 `BuiltinForwardPipeline` 保留 orchestration 职责,而不是继续承载全部细节。
|
||||
3. 清理与 `RenderMaterialUtility` 的交叉依赖,为下一阶段拆 contract 做准备。
|
||||
4. 保证 unlit / lit / object-id / depth-only / shadow-caster 的绑定逻辑不被混淆。
|
||||
|
||||
### 验收标准
|
||||
|
||||
- `BuiltinForwardPipeline.cpp` 明显缩小,核心职责清晰
|
||||
- 新拆出的模块命名与职责稳定,不是单纯“工具类化”
|
||||
- forward 相关单测、集成测试全部不回退
|
||||
|
||||
### 计划提交点
|
||||
|
||||
这一阶段完成后立即提交推送一次。
|
||||
|
||||
## 6.3 Phase C:RenderMaterialUtility 正式拆层
|
||||
|
||||
### 目标
|
||||
|
||||
把 shader/material/pass 的正式 contract 与 legacy/compat/runtime helper 拆开。
|
||||
|
||||
### 要解决的根因
|
||||
|
||||
- 正式接口和过渡逻辑混在一起
|
||||
- 任何依赖 `RenderMaterialUtility.h` 的代码都会被迫包含大量不相干能力
|
||||
- 后续 shader/material 演进会被兼容逻辑长期绑死
|
||||
|
||||
### 具体工作
|
||||
|
||||
1. 明确拆成三层语义:
|
||||
- `contract`:builtin pass 名称、标准 binding 名称、正式解析规则
|
||||
- `runtime resolve`:材质/着色器运行时查询、pass 选择、绑定规划
|
||||
- `compat`:legacy property 名称、历史 fallback、过渡适配
|
||||
2. 避免再把大段实现继续塞在头文件里,能下沉到 `.cpp` 的尽量下沉。
|
||||
3. 对外只暴露最小且稳定的正式接口。
|
||||
4. 给 compat 层加清晰边界,避免以后继续被当作默认主路径使用。
|
||||
|
||||
### 验收标准
|
||||
|
||||
- `RenderMaterialUtility.h` 体量显著下降,职责单一
|
||||
- renderer 主链依赖的是正式 contract / runtime resolve,而不是 compat 大杂烩
|
||||
- 现有 shader/material 行为与测试结果保持一致
|
||||
|
||||
### 计划提交点
|
||||
|
||||
这一阶段完成后立即提交推送一次。
|
||||
|
||||
## 6.4 Phase D:Runtime Pass 与 Editor/Debug Pass 边界重整
|
||||
|
||||
### 目标
|
||||
|
||||
明确 engine runtime rendering core 与 editor/debug-oriented rendering extension 的边界。
|
||||
|
||||
### 要解决的根因
|
||||
|
||||
- grid、outline 等语义虽然已经可用,但组织上仍偏临时
|
||||
- engine 核心层里混有 editor 专用概念
|
||||
- 后续 camera frame composition 扩展容易再次被 editor 需求污染
|
||||
|
||||
### 具体工作
|
||||
|
||||
1. 明确哪些是 runtime 正式能力,哪些是 editor/debug extension。
|
||||
2. 把 editor/debug pass 的注册与宿主接入方式整理成正式 extension seam。
|
||||
3. 保持 SceneView / GameView 继续复用 runtime renderer 主链,但 editor overlay / outline / grid 不侵入 runtime scene composition。
|
||||
4. 补足必要文档,说明 engine、renderer、editor 三者的责任边界。
|
||||
|
||||
### 验收标准
|
||||
|
||||
- editor/debug pass 不再作为 runtime renderer 核心概念扩散
|
||||
- SceneView / GameView 显示、grid、outline、gizmo 宿主路径不回退
|
||||
- 新增代码结构能自然承接后续 icon/light gizmo/camera gizmo 等扩展
|
||||
|
||||
### 计划提交点
|
||||
|
||||
这一阶段完成后立即提交推送一次。
|
||||
|
||||
## 6.5 Phase E:稳定性清扫、文件收口与文档归档
|
||||
|
||||
### 目标
|
||||
|
||||
清掉这一阶段剩余的临时写法,让实现、测试、文档口径再次一致。
|
||||
|
||||
### 具体工作
|
||||
|
||||
1. 修正 `RenderSceneExtractor` 里仍然使用 raw pointer 的稳定排序 tie-breaker。
|
||||
2. 把 `BuiltinDepthStylePassBase.cpp` 中具体 pass 实现拆出到独立文件。
|
||||
3. 全面复查 renderer 相关文件命名、目录结构、头源分布是否仍有明显反模式。
|
||||
4. 更新 `tests/TEST_SPEC.md` 与相关 renderer / editor guide。
|
||||
5. 阶段完成后,把已过期 plan 归档到 `docs/used`。
|
||||
|
||||
### 验收标准
|
||||
|
||||
- renderer 核心目录结构与职责边界基本一致
|
||||
- 没有明显残留的阶段性临时代码入口
|
||||
- 文档、测试矩阵、实现状态三者一致
|
||||
|
||||
### 计划提交点
|
||||
|
||||
这一阶段完成后立即提交推送一次。
|
||||
|
||||
## 7. 测试策略
|
||||
|
||||
本阶段的测试必须是“每阶段落地即验证”,不能到最后一次性回归。
|
||||
|
||||
### 7.1 Unit
|
||||
|
||||
重点保护:
|
||||
|
||||
- `CameraRenderer` 阶段顺序与失败传播
|
||||
- `RenderSceneExtractor` 的稳定输出
|
||||
- `BuiltinForwardPipeline` 的绑定与材质解析
|
||||
- material/shader contract 拆层后的接口行为
|
||||
|
||||
优先关注:
|
||||
|
||||
- `tests/Rendering/unit/test_camera_scene_renderer.cpp`
|
||||
- `tests/Rendering/unit/test_builtin_forward_pipeline.cpp`
|
||||
- 与 material utility / scene extractor 相关的 unit tests
|
||||
|
||||
### 7.2 Editor / Runtime Integration
|
||||
|
||||
重点回归:
|
||||
|
||||
- object-id picking
|
||||
- SceneView / GameView runtime 渲染链
|
||||
- overlay / outline / grid
|
||||
- backpack / shadow / multi-light / camera stack / offscreen 等现有场景
|
||||
|
||||
至少覆盖:
|
||||
|
||||
- `tests/editor/test_viewport_render_flow_utils.cpp`
|
||||
- `tests/editor/test_scene_viewport_overlay_renderer.cpp`
|
||||
- `tests/editor/test_viewport_object_id_picker.cpp`
|
||||
- 现有 rendering integration matrix 中与 lighting、object-id、camera flow 相关的场景
|
||||
|
||||
### 7.3 编译与宿主验证
|
||||
|
||||
每一阶段至少执行:
|
||||
|
||||
1. 相关 test target 编译
|
||||
2. 相关 unit / integration tests
|
||||
3. 必要时编译 `XCEditor`
|
||||
4. 对 editor 中 SceneView / GameView 做 smoke 验证
|
||||
|
||||
## 8. 风险与控制
|
||||
|
||||
### 风险 1:把“结构重构”做成单纯的文件搬家
|
||||
|
||||
后果:
|
||||
|
||||
- 文件名变了,职责没变
|
||||
- 代码仍然继续跨层互相依赖
|
||||
|
||||
控制策略:
|
||||
|
||||
- 每次拆分都要同时调整接口边界和测试保护点
|
||||
|
||||
### 风险 2:为了图省事继续保留 object-id 特判
|
||||
|
||||
后果:
|
||||
|
||||
- Camera frame composition 永远无法正式化
|
||||
- 后续 skybox / post-process 会继续引入更多特判
|
||||
|
||||
控制策略:
|
||||
|
||||
- 第一阶段必须先砍掉这类特殊旁路
|
||||
|
||||
### 风险 3:compat 逻辑继续侵入正式 contract
|
||||
|
||||
后果:
|
||||
|
||||
- shader/material 体系长期混乱
|
||||
- 之后 Unity 风格 shader authoring 很难落地
|
||||
|
||||
控制策略:
|
||||
|
||||
- compat 层必须显式命名、显式隔离、显式限定使用场景
|
||||
|
||||
### 风险 4:editor/debug pass 重整时破坏现有 editor 体验
|
||||
|
||||
后果:
|
||||
|
||||
- 影响当前 SceneView 主线
|
||||
- 把结构收口又变成功能回退
|
||||
|
||||
控制策略:
|
||||
|
||||
- 每一阶段都要做 editor smoke 和既有测试回归
|
||||
|
||||
## 9. 阶段完成判定
|
||||
|
||||
满足以下条件时,本阶段才算真正收口:
|
||||
|
||||
1. `CameraRenderer` 已统一成正式 frame composition 执行模型。
|
||||
2. `BuiltinForwardPipeline` 与 `RenderMaterialUtility` 已完成职责拆分,核心 god file 问题消除。
|
||||
3. runtime pass 与 editor/debug pass 边界清晰,不再混成一团。
|
||||
4. 现有 rendering / editor tests 继续稳定通过。
|
||||
5. `docs/plan` 与 `docs/used` 的 plan 入口重新清晰,不再保留已过期的执行入口。
|
||||
|
||||
## 10. 与当前主线的关系
|
||||
|
||||
这份计划不是替代“Skybox 环境与 Frame Composition 正式化”方向,而是它的前置收口。
|
||||
|
||||
顺序必须是:
|
||||
|
||||
1. 先做 renderer 结构收口与代码正式化
|
||||
2. 再做 skybox / environment / post-process 的正式接入
|
||||
3. 最后才考虑更高阶的 renderer feature 与未来 SRP 承接
|
||||
|
||||
否则就是在结构债未清的情况下继续加层,后面只会越收越难。
|
||||
523
docs/used/Renderer阶段收口_旧兼容路径清理与正式化计划_完成归档_2026-04-08.md
Normal file
523
docs/used/Renderer阶段收口_旧兼容路径清理与正式化计划_完成归档_2026-04-08.md
Normal file
@@ -0,0 +1,523 @@
|
||||
# Renderer阶段收口:旧兼容路径清理与正式化计划
|
||||
|
||||
日期:`2026-04-08`
|
||||
|
||||
## 1. 背景
|
||||
|
||||
当前 `Rendering` 模块的主执行架构已经基本成型:
|
||||
|
||||
- `RenderSceneExtractor`
|
||||
- `SceneRenderRequestPlanner`
|
||||
- `SceneRenderer / CameraRenderer`
|
||||
- built-in forward / shadow / object-id / outline / final-color / skybox
|
||||
|
||||
这些主链路已经能稳定支撑:
|
||||
|
||||
- runtime 场景渲染
|
||||
- editor scene/game viewport
|
||||
- 多光源、阴影、object-id、outline、skybox 等现有能力
|
||||
|
||||
因此,当前 Rendering 的主要问题已经不再是“能不能画出来”,而是:
|
||||
|
||||
- 还残留一些旧路线兼容代码
|
||||
- 一些 built-in 运行契约仍然依赖隐式推断
|
||||
- 少量路径仍然带有明显的过渡期实现痕迹
|
||||
|
||||
如果这些问题不在当前阶段彻底收口,后续继续推进:
|
||||
|
||||
- Renderer 模块扩展
|
||||
- Material / Shader editor
|
||||
- Unity 风格 SRP 底层承接
|
||||
|
||||
就会持续建立在一层“虽然能跑,但不是正式规则”的兼容逻辑之上。
|
||||
|
||||
这不符合当前阶段的目标。
|
||||
|
||||
当前阶段的正确方向不是新增更多渲染功能,而是:
|
||||
|
||||
- 清理旧兼容路径
|
||||
- 去掉运行时语义猜测
|
||||
- 把 built-in shader / material / pass contract 进一步正式化
|
||||
|
||||
---
|
||||
|
||||
## 2. 当前已确认的问题
|
||||
|
||||
基于本轮对 `engine/include/XCEngine/Rendering`、`engine/src/Rendering`、`engine/src/Resources/Shader`、`engine/src/Resources/Mesh` 的代码审查,当前确认存在以下问题。
|
||||
|
||||
### 2.1 Mesh 导入仍可生成“无 shader / 无 schema”的旧材质路线
|
||||
|
||||
当前 `MeshLoader` 导入子材质时,仍然直接写入:
|
||||
|
||||
- `baseColor`
|
||||
- `baseColorTexture`
|
||||
- `opacity`
|
||||
- `twoSided`
|
||||
|
||||
而不是直接落到正式 shader schema 对应的属性名与纹理槽位。
|
||||
|
||||
这导致 runtime 渲染阶段仍然需要兜底兼容这些旧名字。
|
||||
|
||||
典型位置:
|
||||
|
||||
- `engine/src/Resources/Mesh/MeshLoader.cpp`
|
||||
- `engine/include/XCEngine/Rendering/Materials/RenderMaterialResolve.h`
|
||||
|
||||
### 2.2 Rendering 仍通过属性别名表推断 built-in 材质语义
|
||||
|
||||
当前 `RenderMaterialResolve.h` 中,仍然保留了大量 builtin 属性/纹理别名表,例如:
|
||||
|
||||
- `baseColor`
|
||||
- `_BaseColor`
|
||||
- `color`
|
||||
- `_Color`
|
||||
- `baseColorTexture`
|
||||
- `_BaseColorTexture`
|
||||
- `_MainTex`
|
||||
- `texture`
|
||||
|
||||
这意味着 runtime 当前并不是“按 shader schema 正式解析”,而是:
|
||||
|
||||
- 优先找 semantic
|
||||
- 找不到就继续按一批旧属性名字猜
|
||||
|
||||
这属于典型过渡兼容逻辑,不应成为正式长期实现。
|
||||
|
||||
### 2.3 BuiltinForward / Depth / Shadow 仍存在 per-material fallback constant 路线
|
||||
|
||||
当前如果材质没有正式 schema constant layout,管线仍会临时构造:
|
||||
|
||||
- `FallbackPerMaterialConstants`
|
||||
|
||||
并继续提交 draw。
|
||||
|
||||
这说明 runtime 仍允许“非正式材质实例”继续进入正式绘制链路。
|
||||
|
||||
这条路径虽然提高了兼容性,但本质上绕开了已经建立的 shader/material 正式模型。
|
||||
|
||||
### 2.4 Built-in pass resource binding 仍依赖隐式硬编码
|
||||
|
||||
当前 builtin shader pass 如果未显式声明 `resources`,运行时仍会通过:
|
||||
|
||||
- `TryBuildImplicitBuiltinPassResourceBindings`
|
||||
|
||||
自动补一套绑定布局。
|
||||
|
||||
这意味着资源绑定契约并不完全存在于 shader 资产中,而是仍有一部分硬编码在 C++ 中。
|
||||
|
||||
这会带来两个问题:
|
||||
|
||||
1. shader 资产与 runtime 存在双份真相
|
||||
2. 后续继续演进 shader/material/editor 时,容易再次产生隐式规则
|
||||
|
||||
### 2.5 HLSL register 重写仍保留 legacy alias
|
||||
|
||||
当前 `ShaderVariantUtils.h` 仍保留:
|
||||
|
||||
- `ResolveLegacyHlslBindingDeclarationAlias`
|
||||
|
||||
以及基于 `gBaseColorTexture` / `gLinearSampler` 一类旧命名的重写逻辑。
|
||||
|
||||
这说明 shader runtime 编译阶段仍在兼容旧命名风格。
|
||||
|
||||
这属于典型“过渡兼容层”,应在 built-in shader 显式资源契约完成后清掉。
|
||||
|
||||
### 2.6 Built-in pass 选择仍存在隐式默认规则
|
||||
|
||||
当前如果 shader 没有显式 builtin metadata,`MatchesBuiltinPass(...)` 仍会把它默认当成:
|
||||
|
||||
- `ForwardLit`
|
||||
|
||||
这意味着 shader 即使没有明确声明自己属于哪个 built-in pass,也有可能继续进入主几何管线。
|
||||
|
||||
这不利于长期正式化。
|
||||
|
||||
### 2.7 Shader artifact 仍兼容多代旧 schema
|
||||
|
||||
当前 shader artifact loader 仍兼容:
|
||||
|
||||
- `XCSHD01`
|
||||
- `XCSHD02`
|
||||
- `XCSHD03`
|
||||
- `XCSHD04`
|
||||
- 当前 schema
|
||||
|
||||
但 shader artifact 本质上是 `Library` 中的可重建中间产物,不属于必须长期 runtime 兼容的用户资产格式。
|
||||
|
||||
如果继续保留多代 schema 分支,会让 shader 资源链路长期背着历史包袱。
|
||||
|
||||
---
|
||||
|
||||
## 3. 本阶段设计原则
|
||||
|
||||
本计划执行时,必须严格遵守以下原则。
|
||||
|
||||
### 3.1 正式路径只能有一条
|
||||
|
||||
对 built-in shader / material / pass 来说,正式路径必须是:
|
||||
|
||||
`导入/authoring -> shader schema -> material instance -> explicit pass contract -> render pipeline`
|
||||
|
||||
不能继续允许 runtime 依赖旧命名、旧别名、旧格式去自动猜测。
|
||||
|
||||
### 3.2 兼容应尽量前移到导入/重建阶段,而不是留在 runtime
|
||||
|
||||
如果确实存在历史资产问题,应优先采用:
|
||||
|
||||
- 重新导入
|
||||
- 重新生成 artifact
|
||||
- 一次性迁移
|
||||
|
||||
而不是继续在 runtime loader / renderer 中保留长期兼容分支。
|
||||
|
||||
### 3.3 Built-in shader 契约必须显式写进 shader 资产
|
||||
|
||||
以下内容必须属于 shader/pass 资产本身,而不是 runtime 猜出来:
|
||||
|
||||
- pass 类型
|
||||
- pass metadata
|
||||
- resource binding
|
||||
- property semantic
|
||||
|
||||
### 3.4 Rendering 不再为“无正式 shader/schema 的材质”兜底渲染
|
||||
|
||||
当前阶段的目标是“收口”,不是“继续最大化兼容”。
|
||||
|
||||
因此:
|
||||
|
||||
- 非正式材质应尽快在导入层修正
|
||||
- runtime 应逐步拒绝无 schema 的正式绘制路径
|
||||
|
||||
### 3.5 每一步都必须可验证
|
||||
|
||||
每个阶段完成后必须配套:
|
||||
|
||||
- unit test
|
||||
- 必要的 integration test
|
||||
- editor 编译/回归
|
||||
|
||||
不能只凭画面“看起来没问题”判断完成。
|
||||
|
||||
---
|
||||
|
||||
## 4. 本阶段目标
|
||||
|
||||
本阶段完成后,Rendering 模块应达到以下状态:
|
||||
|
||||
1. Mesh 导入出来的材质直接走正式 shader/material 体系
|
||||
2. runtime 不再依赖 `baseColor` / `_MainTex` 等别名表去维持 built-in 主链
|
||||
3. built-in pass resource binding 由 shader 资产显式声明,不再依赖隐式硬编码补全
|
||||
4. built-in pass 分类必须显式声明,不再存在“默认 ForwardLit”
|
||||
5. shader artifact runtime loader 不再长期兼容多代旧 schema
|
||||
6. 对应测试体系同步升级,保证收口后功能不回退
|
||||
|
||||
---
|
||||
|
||||
## 5. 明确不在本阶段处理的内容
|
||||
|
||||
以下内容不属于本阶段目标:
|
||||
|
||||
- render graph
|
||||
- deferred renderer
|
||||
- 新一轮后处理功能扩展
|
||||
- C# SRP 脚本侧 API
|
||||
- ShaderGraph
|
||||
- 高级材质编辑器功能扩展
|
||||
|
||||
这些方向都依赖本阶段先把底层 contract 收紧。
|
||||
|
||||
---
|
||||
|
||||
## 6. 分阶段执行计划
|
||||
|
||||
## Phase 1:建立基线与目标测试
|
||||
|
||||
### 目标
|
||||
|
||||
先把当前遗留兼容路径的行为边界用测试钉住,并同步写出“目标行为”的新测试。
|
||||
|
||||
### 任务
|
||||
|
||||
- 审查并整理当前覆盖以下行为的测试:
|
||||
- `RenderMaterialResolve`
|
||||
- builtin forward pipeline resource binding
|
||||
- mesh material import
|
||||
- shader artifact load
|
||||
- 新增/调整测试,使其明确区分:
|
||||
- 当前历史兼容行为
|
||||
- 本阶段目标正式行为
|
||||
- 对以下目标先写失败测试或待切换测试:
|
||||
- imported mesh material 必须绑定正式 builtin shader
|
||||
- imported material property 必须落到正式 schema 名称
|
||||
- builtin pass 若无显式 metadata,不得进入主 pipeline
|
||||
- builtin shader 若无显式 resources,不得依赖隐式 binding 补全
|
||||
|
||||
### 验收标准
|
||||
|
||||
- 能清楚列出哪些测试在保护旧行为,哪些测试在保护目标行为
|
||||
- 后续每个阶段都能基于这些测试判断是否真正收口
|
||||
|
||||
---
|
||||
|
||||
## Phase 2:收口 Mesh 导入材质到正式 shader/material 路径
|
||||
|
||||
### 目标
|
||||
|
||||
彻底去掉 imported mesh material 的“无 shader / 裸属性名”旧路线。
|
||||
|
||||
### 任务
|
||||
|
||||
- 调整 `MeshLoader` 导入逻辑:
|
||||
- imported material 直接绑定正式 builtin shader
|
||||
- 默认按现有主线落到 builtin lit/forward 合同
|
||||
- 导入属性与纹理时,直接写正式 property name / texture slot:
|
||||
- 例如 `_BaseColor`
|
||||
- `_MainTex`
|
||||
- `_Cutoff`
|
||||
- 其他已正式声明的 builtin 属性
|
||||
- 不再向 imported material 写入仅靠 runtime 别名识别的裸字段:
|
||||
- `baseColor`
|
||||
- `baseColorTexture`
|
||||
- `color`
|
||||
- `texture`
|
||||
- 更新 mesh import 相关测试、render extractor 测试、相关 integration 资源测试
|
||||
|
||||
### 验收标准
|
||||
|
||||
- mesh import 结果中的材质都带有正式 shader 引用
|
||||
- mesh import 结果中的属性/纹理绑定名称与 shader schema 对齐
|
||||
- 不再需要 runtime 靠旧别名才能让导入材质正常渲染
|
||||
|
||||
---
|
||||
|
||||
## Phase 3:移除 runtime builtin 材质语义别名与 fallback 常量路径
|
||||
|
||||
### 目标
|
||||
|
||||
让 built-in pipeline 只吃正式 schema 材质,不再继续兼容旧材质命名。
|
||||
|
||||
### 任务
|
||||
|
||||
- 清理 `RenderMaterialResolve.h` 中的旧别名解析表:
|
||||
- base color property alias
|
||||
- base texture alias
|
||||
- skybox texture alias
|
||||
- alpha cutoff alias
|
||||
- 保留并强化基于 `shader property semantic` 的正式解析路径
|
||||
- 移除 `FallbackPerMaterialConstants` 路线
|
||||
- 当材质未携带正式 schema constant layout 时:
|
||||
- 显式报错 / 记录诊断
|
||||
- 拒绝进入需要正式材质常量的绘制路径
|
||||
- 调整 forward / depth / shadow / skybox 相关单测
|
||||
|
||||
### 验收标准
|
||||
|
||||
- builtin pipeline 不再依赖属性别名表维持主链
|
||||
- builtin pipeline 不再手工构造 per-material fallback constant 继续绘制
|
||||
- runtime 只接受正式 shader/material 契约
|
||||
|
||||
---
|
||||
|
||||
## Phase 4:显式化 builtin pass resource binding contract
|
||||
|
||||
### 目标
|
||||
|
||||
让 builtin shader pass 的资源绑定契约完全存在于 shader 资产中,而不是藏在 runtime 硬编码里。
|
||||
|
||||
### 任务
|
||||
|
||||
- 为所有 builtin shader pass 补齐显式 `resources` 描述
|
||||
- 覆盖至少以下 shader:
|
||||
- `forward-lit.shader`
|
||||
- `depth-only.shader`
|
||||
- `shadow-caster.shader`
|
||||
- `object-id.shader`
|
||||
- `skybox.shader`
|
||||
- `final-color.shader`
|
||||
- 其他当前仍在主链中的 builtin shader
|
||||
- 清理 `TryBuildImplicitBuiltinPassResourceBindings`
|
||||
- 清理 `ShaderVariantUtils.h` 中围绕 implicit/legacy binding 的兼容逻辑:
|
||||
- legacy alias register rewrite
|
||||
- 依赖 `gXxx` 名称重写的分支
|
||||
- 调整 shader loader / rendering pipeline / builtin pass 单测
|
||||
|
||||
### 验收标准
|
||||
|
||||
- builtin shader pass 缺少显式资源绑定时,构建或运行应明确失败
|
||||
- runtime 不再替 shader 资产自动补 binding layout
|
||||
- HLSL runtime 编译不再依赖 legacy alias register 重写
|
||||
|
||||
---
|
||||
|
||||
## Phase 5:显式化 builtin pass metadata 与 pass 选择规则
|
||||
|
||||
### 目标
|
||||
|
||||
去掉“默认 ForwardLit”一类隐式 pass 归类规则。
|
||||
|
||||
### 任务
|
||||
|
||||
- 收紧 `BuiltinPassMetadataUtils`:
|
||||
- built-in pass 匹配必须依赖显式 pass name / tag
|
||||
- 删除“无 metadata 默认归 ForwardLit”的逻辑
|
||||
- 审查并统一 builtin shader 的 pass metadata:
|
||||
- `Name`
|
||||
- `LightMode`
|
||||
- 其它当前正式要求的 tag
|
||||
- 对进入 builtin 主线的 shader 建立硬约束:
|
||||
- 没有显式 builtin metadata 的 shader,不得继续被当作主几何 shader 使用
|
||||
- 更新 pass 匹配测试和 shader authoring 测试
|
||||
|
||||
### 验收标准
|
||||
|
||||
- builtin pass 选择全部基于显式 metadata
|
||||
- 不存在 runtime 默认猜一个 pass 类型的行为
|
||||
|
||||
---
|
||||
|
||||
## Phase 6:清理旧 shader artifact schema 兼容
|
||||
|
||||
### 目标
|
||||
|
||||
让 shader artifact runtime loader 与 material artifact 一样,收口到 current schema。
|
||||
|
||||
### 任务
|
||||
|
||||
- 清理 `ShaderArtifactLoader.cpp` 中对旧 schema 的分支兼容:
|
||||
- `XCSHD01`
|
||||
- `XCSHD02`
|
||||
- `XCSHD03`
|
||||
- `XCSHD04`
|
||||
- 将旧 `Library` artifact 的处理方式改为:
|
||||
- 识别为过期
|
||||
- 触发重新导入 / 重新生成
|
||||
- 或直接报错要求重建 `Library`
|
||||
- 更新 asset database / shader load 相关测试
|
||||
- 明确记录此阶段会带来的影响:
|
||||
- 旧 `Library` 无法直接沿用
|
||||
- 需要一次性刷新或重建
|
||||
|
||||
### 验收标准
|
||||
|
||||
- shader artifact loader 只接受 current schema
|
||||
- 对旧 artifact 的处理边界清晰且可测试
|
||||
|
||||
---
|
||||
|
||||
## Phase 7:全量验证与阶段收口
|
||||
|
||||
### 目标
|
||||
|
||||
确认 Rendering 在去掉旧兼容层之后没有破坏现有功能。
|
||||
|
||||
### 任务
|
||||
|
||||
- 编译并运行:
|
||||
- `material_tests`
|
||||
- `rendering_unit_tests`
|
||||
- `asset_tests`
|
||||
- `editor_tests`
|
||||
- 受影响的 mesh/shader 资源测试
|
||||
- 重新编译 `XCEditor`
|
||||
- 重点回归:
|
||||
- scene viewport
|
||||
- game viewport
|
||||
- object-id picking
|
||||
- selection outline
|
||||
- skybox
|
||||
- 阴影
|
||||
- 多光源
|
||||
- backpack / sphere / quad 等 integration scene
|
||||
- 形成阶段收口报告
|
||||
|
||||
### 验收标准
|
||||
|
||||
- 所有直接相关测试通过
|
||||
- editor 编译通过
|
||||
- 关键 integration scene 渲染行为不回退
|
||||
- 能明确宣告 runtime 旧兼容路径已移除
|
||||
|
||||
---
|
||||
|
||||
## 7. 风险与注意事项
|
||||
|
||||
### 7.1 这是一次“切正式路径”的收口,不是小修小补
|
||||
|
||||
本计划一旦执行,就会主动删除一部分兼容逻辑。
|
||||
|
||||
因此不能以“尽量少改代码”为目标,而应以:
|
||||
|
||||
- 正式路径唯一
|
||||
- contract 清晰
|
||||
- 后续 SRP 可承接
|
||||
|
||||
为目标。
|
||||
|
||||
### 7.2 `Library` 重建属于预期影响
|
||||
|
||||
一旦收掉旧 shader artifact schema 兼容,旧 `Library` 里的 shader artifact 失效是正常现象。
|
||||
|
||||
这不应被视为回归,而应被视为阶段性收口的合理代价。
|
||||
|
||||
### 7.3 必须避免引入新的“临时兼容层”
|
||||
|
||||
执行过程中需要特别警惕以下错误做法:
|
||||
|
||||
- 新加一层 alias 表,试图“先兼容一下”
|
||||
- 把 runtime fallback 换个名字继续保留
|
||||
- 在 editor 或 import 层再次引入一套过渡数据模型
|
||||
|
||||
如果遇到结构性问题,正确做法是:
|
||||
|
||||
- 直接改到正式模型
|
||||
- 同步补测试
|
||||
|
||||
而不是再加一层短期兜底。
|
||||
|
||||
---
|
||||
|
||||
## 8. 建议执行顺序
|
||||
|
||||
建议严格按以下顺序推进:
|
||||
|
||||
1. `Phase 1` 测试基线整理
|
||||
2. `Phase 2` mesh 导入材质正式化
|
||||
3. `Phase 3` runtime 材质别名与 fallback 常量清理
|
||||
4. `Phase 4` builtin pass 显式资源绑定
|
||||
5. `Phase 5` builtin pass metadata 显式化
|
||||
6. `Phase 6` shader artifact schema 收口
|
||||
7. `Phase 7` 全量验证
|
||||
|
||||
原因是:
|
||||
|
||||
- 如果不先把 imported material 拉回正式路径
|
||||
- 后面的 runtime alias / fallback 清理就一定会打断现有资源链路
|
||||
|
||||
---
|
||||
|
||||
## 9. 本阶段完成后的预期状态
|
||||
|
||||
本计划完成后,Rendering 模块应达到以下状态:
|
||||
|
||||
1. built-in shader/material/pass contract 全部走正式显式路径
|
||||
2. runtime 不再依赖旧命名猜测材质语义
|
||||
3. runtime 不再替非正式材质拼接 fallback 常量布局
|
||||
4. builtin shader 资源绑定契约完全由 shader 资产声明
|
||||
5. builtin pass 类型选择完全依赖显式 metadata
|
||||
6. shader artifact runtime loader 不再背负旧 schema 包袱
|
||||
7. 整个 Rendering 模块更适合作为后续 Unity 风格 SRP 的底层承接
|
||||
|
||||
---
|
||||
|
||||
## 10. 一句话总结
|
||||
|
||||
当前 Rendering 真正需要的不是继续加功能,而是把残留的旧兼容路径彻底拔干净。
|
||||
|
||||
这一阶段的本质,是把:
|
||||
|
||||
- imported material
|
||||
- built-in shader binding
|
||||
- pass metadata
|
||||
- shader artifact
|
||||
|
||||
全部拉回到同一套正式 contract 上,为后续 Renderer / Material / Shader / SRP 的继续推进打地基。
|
||||
71
docs/used/Renderer阶段收口补充_ObjectIdPicking正式化.md
Normal file
71
docs/used/Renderer阶段收口补充_ObjectIdPicking正式化.md
Normal file
@@ -0,0 +1,71 @@
|
||||
# Renderer 阶段收口补充:Object ID Picking 正式化
|
||||
|
||||
日期:`2026-04-02`
|
||||
|
||||
## 1. 这次补充收口解决什么
|
||||
|
||||
本次补充只收一件事:
|
||||
|
||||
- `SceneView` 选中主链路正式切到 `GPU object-id`
|
||||
|
||||
本次明确不做:
|
||||
|
||||
- render graph
|
||||
- renderer 内更完整的多 pass 调度
|
||||
- game/runtime 通用 picking 服务
|
||||
|
||||
原因很简单:这些属于下一阶段架构演进,不应该继续污染当前阶段的收口边界。
|
||||
|
||||
## 2. 本次收口后的正式行为
|
||||
|
||||
当前 `SceneView` 选中行为统一定义为:
|
||||
|
||||
1. 场景渲染时生成 `object-id` 纹理
|
||||
2. 鼠标点击时读取对应像素
|
||||
3. 颜色解码为实体 ID
|
||||
4. `0` 视为“未选中任何对象”,但这仍然是一次成功的 GPU 采样
|
||||
|
||||
关键变化:
|
||||
|
||||
- editor 不再把 `CPU ray picking` 作为 `SceneView` 点击选中的静默回退主链路
|
||||
- `CPU ray picking` 继续保留为独立几何工具能力,不再承担当前正式选中流程
|
||||
- `object-id` 读取失败会被显式标记为 readback failure,而不是与“没有有效帧”混在一起
|
||||
|
||||
## 3. 为什么这才算收口
|
||||
|
||||
之前的问题不是没有 `object-id pass`,而是“主路径”和“兜底路径”的语义不够硬:
|
||||
|
||||
- 成功采样
|
||||
- 无有效 object-id 帧
|
||||
- GPU 读回失败
|
||||
|
||||
这三种状态以前没有被清晰区分。
|
||||
|
||||
现在已经收紧为显式结果类型:
|
||||
|
||||
- `Unavailable`
|
||||
- `Success`
|
||||
- `ReadbackFailed`
|
||||
|
||||
这意味着:
|
||||
|
||||
- renderer/editor 的 `object-id` 交互已经形成可测试契约
|
||||
- `0 id` 与“采样失败”不再混淆
|
||||
- 后续若要继续升级成异步 readback、共享 picking 服务,也有稳定边界可接
|
||||
|
||||
## 4. 当前阶段完成后的边界
|
||||
|
||||
到这里,当前阶段可以正式视为完成:
|
||||
|
||||
- editor viewport 宿主链路已打通
|
||||
- renderer 的 builtin post-process 已形成稳定接口
|
||||
- `SceneView` 选中正式以 GPU object-id 为主链路
|
||||
- 回归测试已覆盖 object-id 读回状态语义
|
||||
|
||||
下一阶段真正该做的是:
|
||||
|
||||
- renderer 内正式 render graph / pass graph
|
||||
- 更完整的 renderer-owned picking 服务
|
||||
- editor / runtime shared picking contract
|
||||
|
||||
而不是继续在这个阶段里反复修补 viewport host。
|
||||
164
docs/used/Renderer阶段收口说明.md
Normal file
164
docs/used/Renderer阶段收口说明.md
Normal file
@@ -0,0 +1,164 @@
|
||||
# Renderer阶段收口说明
|
||||
|
||||
## 1. 目标
|
||||
|
||||
本文用于正式收口当前 Renderer 阶段,明确:
|
||||
|
||||
- 本阶段已经完成什么
|
||||
- 哪些能力已经进入稳定边界
|
||||
- 哪些事项明确延期到下一阶段
|
||||
- 后续开发不应再继续把新功能塞回本阶段
|
||||
|
||||
当前收口日期:`2026-04-02`
|
||||
|
||||
---
|
||||
|
||||
## 2. 本阶段已完成能力
|
||||
|
||||
### 2.1 Renderer 主体边界
|
||||
|
||||
当前已经形成稳定分层:
|
||||
|
||||
- `RHI` 负责后端抽象与资源/命令执行
|
||||
- `Rendering` 负责场景提取、camera request、pipeline、builtin pass
|
||||
- `Editor` 负责 viewport 宿主、输入、overlay、编辑态请求装配
|
||||
|
||||
关键点:
|
||||
|
||||
- `CameraRenderer` 已经承担统一 camera 渲染执行职责
|
||||
- `SceneRenderer` 已经承担 scene -> camera request 的组织职责
|
||||
- editor scene viewport 不再自己拼装 renderer 执行逻辑
|
||||
|
||||
### 2.2 内建后处理边界
|
||||
|
||||
本阶段内建编辑态后处理已经收敛为 renderer 自己的通用请求能力:
|
||||
|
||||
- `BuiltinPostProcessRequest`
|
||||
- `BuiltinPostProcessPassPlan`
|
||||
- `BuiltinPostProcessPassSequenceBuilder`
|
||||
|
||||
这意味着:
|
||||
|
||||
- renderer 公共接口不再暴露 `SceneView` 专有命名
|
||||
- grid / selection outline / debug mask 已归入 renderer 侧 builtin post-process 能力
|
||||
- editor 只负责“是否启用、传什么数据、把哪些 render target 绑定进 request”
|
||||
|
||||
### 2.3 Editor Scene Viewport 接入
|
||||
|
||||
当前 editor scene viewport 已具备:
|
||||
|
||||
- renderer 离屏输出接入
|
||||
- object-id 帧输出接入
|
||||
- CPU picking 回退链路
|
||||
- selection outline
|
||||
- infinite grid
|
||||
- built-in post-process 请求装配
|
||||
|
||||
其中:
|
||||
|
||||
- grid 和 outline 仍然服务于 editor scene viewport
|
||||
- 但执行入口已经下沉到 renderer
|
||||
- editor 只保留宿主与编辑器语义
|
||||
|
||||
### 2.4 自动化测试体系
|
||||
|
||||
当前已经具备稳定回归闸门:
|
||||
|
||||
- `tests/Rendering/unit`
|
||||
- `tests/Rendering/integration`
|
||||
- `tests/Editor`
|
||||
- `rendering_phase_regression`
|
||||
|
||||
当前阶段收口依赖的关键验证包括:
|
||||
|
||||
- renderer unit tests
|
||||
- editor tests
|
||||
- 全 rendering integration 场景
|
||||
- `XCEditor` smoke launch
|
||||
|
||||
---
|
||||
|
||||
## 3. 本阶段稳定边界
|
||||
|
||||
以下内容从现在开始视为本阶段稳定边界:
|
||||
|
||||
1. renderer 公共请求以 `CameraRenderRequest` 为核心,而不是 editor 自定义执行入口。
|
||||
2. editor scene viewport 的内建后处理数据由 editor 组装,但 pass 执行由 renderer 负责。
|
||||
3. builtin post-process 的公共语义是 renderer 语义,不是 `SceneView` 语义。
|
||||
4. rendering regression 失败时,优先视为阶段回归,而不是“可接受的小问题”。
|
||||
|
||||
---
|
||||
|
||||
## 4. 本阶段明确延期项
|
||||
|
||||
以下事项明确不再继续塞入本阶段,转入下一阶段:
|
||||
|
||||
### 4.1 真正的多 pass / render graph 框架
|
||||
|
||||
当前已有 pass sequence 与 builtin post-process,但这还不是完整的 renderer 多 pass 架构。
|
||||
|
||||
延期内容:
|
||||
|
||||
- renderer 级 render graph
|
||||
- 更正式的 pass phase / event 模型
|
||||
- 更通用的资源读写依赖管理
|
||||
|
||||
### 4.2 GPU Object ID 正式方案
|
||||
|
||||
当前 editor selection 相关链路已经能工作,但还不是最终方案。
|
||||
|
||||
延期内容:
|
||||
|
||||
- renderer 内正式 object-id pass/attachment 规范化
|
||||
- editor picking 从 CPU fallback 继续向 GPU object-id 正式方案收敛
|
||||
- editor/game shared picking contract
|
||||
|
||||
### 4.3 Gizmo 最终渲染体系
|
||||
|
||||
当前 gizmo 与 scene viewport 已经能工作,但不属于本阶段 renderer 收口范围。
|
||||
|
||||
延期内容:
|
||||
|
||||
- 更成熟的 gizmo 渲染架构
|
||||
- 更统一的 gizmo draw pass / picking / overlay 体系
|
||||
- 与后续 renderer 多 pass 的正式对接
|
||||
|
||||
### 4.4 C# SRP 对接
|
||||
|
||||
当前 renderer 的职责边界已经为 SRP 预留好了方向,但本阶段不做真正脚本化 pipeline 落地。
|
||||
|
||||
延期内容:
|
||||
|
||||
- `RenderPipelineAsset` / `RenderPipeline` 脚本绑定
|
||||
- `ScriptableRenderContext`
|
||||
- `CommandBuffer`
|
||||
- renderer 与脚本侧的正式桥接层
|
||||
|
||||
---
|
||||
|
||||
## 5. 阶段退出标准
|
||||
|
||||
当前阶段只有在以下条件全部满足时才视为完成:
|
||||
|
||||
1. renderer/editor 边界中不再存在新的 `SceneView` 语义向 renderer 公共接口泄漏。
|
||||
2. scene viewport 的 builtin post-process 组合链路具备稳定自动化回归覆盖。
|
||||
3. `rendering_phase_regression` 保持通过。
|
||||
4. 新功能开发转入下一阶段,不再回头污染本阶段边界。
|
||||
|
||||
截至本文落地时,这些退出标准已经满足。
|
||||
|
||||
---
|
||||
|
||||
## 6. 下一阶段入口
|
||||
|
||||
Renderer 下一阶段应当正式转向:
|
||||
|
||||
- renderer 内更完整的多 pass / phase 模型
|
||||
- editor/game shared render feature 契约
|
||||
- object-id 正式化
|
||||
- 为后续 C# SRP 搭建真正可扩展的 renderer 接口
|
||||
|
||||
一句话总结:
|
||||
|
||||
- 当前阶段已经把“Renderer 从 RHI 之上独立出来,并接通 editor scene viewport”这件事做完
|
||||
- 下一阶段不该继续修补这一层,而应开始建设更正式的 renderer 扩展框架
|
||||
@@ -0,0 +1,631 @@
|
||||
# Scene Viewport Overlay 与 Gizmo 正规化重构方案
|
||||
|
||||
日期:`2026-04-02`
|
||||
|
||||
## 0. 当前进度 Checkpoint
|
||||
|
||||
截至 `2026-04-02`,本方案已有以下落地结果:
|
||||
|
||||
- `Phase 1` 已完成:
|
||||
- `CameraRenderRequest` 已新增 `overlayPasses`
|
||||
- `CameraRenderer` 已在 builtin postprocess 之后执行 `overlayPasses`
|
||||
- `ViewportHostService` 已接入 editor overlay pass sequence
|
||||
- `Phase 2` 已完成首批迁移:
|
||||
- `camera frustum`
|
||||
- `directional light gizmo`
|
||||
- `camera/light scene icon`
|
||||
- 上述内容已不再走 ImGui world draw,而是走 renderer overlay pass
|
||||
- `scene icon` 的命中数据已开始收口:
|
||||
- `SceneViewPanel` 不再自己扫描 scene 构建 icon draw data
|
||||
- icon hit test 已改为消费 `SceneViewportOverlayBuilder::Build()` 产出的同类 frame data
|
||||
- `transform gizmo` 的统一命中已开始接线:
|
||||
- `SceneViewportEditorOverlayData.h` 已扩展为通用 `handleRecords`
|
||||
- `SceneViewportOverlayHandleBuilder.h` 已可把 move/rotate/scale gizmo draw data 转为 canonical handle records
|
||||
- `SceneViewPanel` 中 gizmo 的 hover / click-begin 已开始走统一 `HitTestSceneViewportOverlayHandles(...)`
|
||||
- `transform gizmo` 的绘制迁移已开始接线:
|
||||
- `SceneViewportEditorOverlayPass` 已支持 screen-space triangle primitive
|
||||
- `ViewportHostService` 已可在 host 侧根据 `SceneViewPanel` 提交的 overlay 与 gizmo handle build inputs 构建 transient transform overlay frame data
|
||||
- transform gizmo 的 handle build inputs 组装 helper 已开始从 `SceneViewPanel` 向 `SceneViewportOverlayHandleBuilder.h` 收口
|
||||
- transform gizmo 的 selection/context/refresh/cancel helper 已开始从 `SceneViewPanel` 向 `SceneViewportTransformGizmoFrameBuilder.h` 收口
|
||||
- move / rotate / scale gizmo 已不再直接依赖 `DrawSceneViewportOverlay()` 的 ImGui gizmo 绘制分支出图
|
||||
- `SceneViewportOverlayRenderer.cpp` 已收缩回 HUD/orientation 责任,不再承担 transform gizmo / scene icon / scene line 的 ImGui world draw
|
||||
- `SceneViewPanel` 内部交互前命中与交互后绘制的 gizmo 刷新链路已开始复用同一套 helper,重复的 context/update/submit 逻辑已明显收缩
|
||||
- interaction overlay frame 已改为 host 按传入的 transform gizmo inputs 现场组合,`SceneViewPanel` 不再为 hit test 预先写入 transient overlay 缓存
|
||||
- render 阶段使用的 transient transform gizmo frame data 也已改为 host 基于缓存的原始 overlay + inputs 现场构建
|
||||
|
||||
当前仍未完成的关键点:
|
||||
|
||||
- `transform gizmo` 的 drag solver / 变换求解仍然保留在各自 gizmo 类中
|
||||
- `SceneViewPanel` 里仍保留 transform gizmo 的 draw data 生成、交互仲裁与 transient overlay 提交逻辑
|
||||
- `SceneViewPanel` 仍直接控制 transform gizmo 的最终绘制 overlay 提交时机,host 尚未完全接管这一层 frame orchestration
|
||||
- `ViewportHostService` 的 canonical overlay frame data 仍未直接承载 transform gizmo,尚未收敛到单帧单份 canonical overlay 数据
|
||||
|
||||
当前阶段结论:
|
||||
|
||||
**方案方向已经验证正确,下一步不应该回头继续扩写 ImGui world overlay,而应该继续推进 canonical overlay data 与统一命中系统。**
|
||||
|
||||
## 1. 方案结论
|
||||
|
||||
当前 `Scene Viewport` 的问题,不是某一个 `Directional Light Gizmo` 画丑了,而是整条 editor overlay 链路本身没有收口:
|
||||
|
||||
- `grid` 已经是正规 renderer pass
|
||||
- `transform gizmo / camera icon / light icon / camera frustum / directional light gizmo` 仍然是 ImGui overlay
|
||||
- 输入命中和绘制几何不是同一份数据
|
||||
- `SceneViewPanel.cpp` 同时承担 panel UI、输入调度、世界转屏幕、overlay 构建、命中仲裁,职责已经失控
|
||||
|
||||
结论只有一个:
|
||||
|
||||
**不能再继续往 `SceneViewPanel.cpp` 和 ImGui world overlay 上堆功能。必须把场景中的 editor 可视化正式收口成一套 renderer 级 overlay pass 和统一 handle 数据。**
|
||||
|
||||
---
|
||||
|
||||
## 2. 当前链路梳理
|
||||
|
||||
### 2.1 正规链路:Grid
|
||||
|
||||
当前 `grid` 的路径是正规的 renderer pass:
|
||||
|
||||
`ViewportHostService -> SceneRenderer -> CameraRenderer -> BuiltinPostProcessPassSequenceBuilder -> BuiltinInfiniteGridPass`
|
||||
|
||||
关键文件:
|
||||
|
||||
- `editor/src/Viewport/ViewportHostService.h`
|
||||
- `editor/src/Viewport/ViewportHostRenderFlowUtils.h`
|
||||
- `engine/src/Rendering/CameraRenderer.cpp`
|
||||
- `engine/src/Rendering/Passes/BuiltinPostProcessPassSequenceBuilder.cpp`
|
||||
- `engine/src/Rendering/Passes/BuiltinInfiniteGridPass.cpp`
|
||||
|
||||
这条链路的特征是:
|
||||
|
||||
- 在 scene 几何渲染完成后,由 GPU pass 正式叠加
|
||||
- 有明确的 render request 输入
|
||||
- 有独立 pass 边界
|
||||
- 不依赖 ImGui draw list
|
||||
|
||||
### 2.2 非正规链路:Editor World Overlay
|
||||
|
||||
当前绝大多数 editor 可视化不是 renderer pass,而是:
|
||||
|
||||
1. `ViewportHostService` 渲出 scene viewport 纹理
|
||||
2. `RenderViewportPanelContent()` 在 ImGui 面板中显示这张纹理
|
||||
3. `SceneViewPanel.cpp` 在这张纹理之上继续用 ImGui draw list 手搓 world overlay
|
||||
|
||||
关键文件:
|
||||
|
||||
- `editor/src/panels/ViewportPanelContent.h`
|
||||
- `editor/src/panels/SceneViewPanel.cpp`
|
||||
- `editor/src/Viewport/SceneViewportOverlayRenderer.cpp`
|
||||
|
||||
当前放在这条链上的内容包括:
|
||||
|
||||
- move gizmo
|
||||
- rotate gizmo
|
||||
- scale gizmo
|
||||
- camera icon / light icon
|
||||
- camera frustum
|
||||
- directional light gizmo
|
||||
- orientation gizmo
|
||||
|
||||
其中 `orientation gizmo` 本质上是固定在右上角的 HUD,放在 ImGui 问题不大。真正失控的是那些锚定在世界空间中的 overlay。
|
||||
|
||||
---
|
||||
|
||||
## 3. 当前架构的核心问题
|
||||
|
||||
### 3.1 绘制职责放错层
|
||||
|
||||
`SceneViewPanel.cpp` 不应该知道:
|
||||
|
||||
- camera frustum 怎么构造几何
|
||||
- directional light gizmo 怎么构造几何
|
||||
- icon 如何转屏幕矩形
|
||||
- 各种 gizmo 如何排序、如何遮挡
|
||||
|
||||
这些本质上都属于 viewport overlay 系统,不属于 panel UI。
|
||||
|
||||
### 3.2 命中和绘制分裂
|
||||
|
||||
当前很多交互是:
|
||||
|
||||
- 一套代码负责画
|
||||
- 另一套代码负责 hover / click / drag
|
||||
|
||||
这会导致:
|
||||
|
||||
- 看见的和能点的不是同一个东西
|
||||
- 改样式时经常忘改命中
|
||||
- 优先级只能靠条件链硬拼
|
||||
|
||||
### 3.3 世界空间对象被当成 2D UI 处理
|
||||
|
||||
camera/light icon、frustum、light gizmo、transform gizmo 本质上都是世界空间 editor overlay。
|
||||
|
||||
但它们现在被塞进 ImGui draw list 后,就天然失去:
|
||||
|
||||
- 正规的渲染顺序语义
|
||||
- 稳定的深度/遮挡策略
|
||||
- 统一的 primitive 渲染方式
|
||||
- GPU 级别的扩展能力
|
||||
|
||||
### 3.4 `SceneViewPanel.cpp` 已经过胖
|
||||
|
||||
当前它同时负责:
|
||||
|
||||
- tools/top bar UI
|
||||
- tool mode 切换
|
||||
- gizmo context 组装
|
||||
- gizmo hover/click 仲裁
|
||||
- icon hit test
|
||||
- overlay 世界几何构建
|
||||
- scene picking
|
||||
- scene camera 输入
|
||||
|
||||
这已经不再是“面板”,而是一个巨型调度器加半个渲染系统。
|
||||
|
||||
### 3.5 视觉风格无法稳定收敛
|
||||
|
||||
Directional Light 这次暴露得最明显:
|
||||
|
||||
- 需求是“圆形底盘上的光线分布”
|
||||
- 当前实现却是在 panel 里临时拼几根线
|
||||
|
||||
这不是调几个参数能根治的问题,而是底层 primitive 表达和系统边界不对。
|
||||
|
||||
---
|
||||
|
||||
## 4. 重构目标
|
||||
|
||||
这次重构的目标不是“顺手把几个 gizmo 再修漂亮一点”,而是把 Scene Viewport overlay 彻底正规化。
|
||||
|
||||
最终目标如下:
|
||||
|
||||
### 4.1 分离两类 overlay
|
||||
|
||||
#### A. HUD 类 overlay
|
||||
|
||||
固定在面板坐标系的内容继续留在 ImGui:
|
||||
|
||||
- 顶部工具栏
|
||||
- 左侧 tools 按钮
|
||||
- 右上角 orientation gizmo
|
||||
- 状态提示文字
|
||||
|
||||
#### B. World Anchored Overlay
|
||||
|
||||
锚定在世界空间里的 editor 可视化统一进入 renderer overlay pass:
|
||||
|
||||
- move / rotate / scale gizmo
|
||||
- camera / light scene icon
|
||||
- camera frustum
|
||||
- directional light gizmo
|
||||
- 后续 collider bounds / helper shapes / volume gizmo
|
||||
|
||||
### 4.2 统一绘制数据与命中数据
|
||||
|
||||
所有可交互 gizmo handle 必须来自同一份 canonical data:
|
||||
|
||||
- 画什么
|
||||
- 颜色是什么
|
||||
- 层级优先级是什么
|
||||
- handle id 是什么
|
||||
- 哪里可以点
|
||||
|
||||
都不能再分散在不同类里各算一套。
|
||||
|
||||
### 4.3 建立 renderer 级 editor overlay pass
|
||||
|
||||
目标顺序应为:
|
||||
|
||||
`Scene Geometry -> ObjectId -> Builtin Post Process(Grid/Outline) -> Editor Overlay Pass -> ImGui HUD`
|
||||
|
||||
也就是说,editor 世界 overlay 必须成为正式 render stage,而不是纹理上的二次手绘。
|
||||
|
||||
### 4.4 让 gizmo 类回归“控制器/求解器”角色
|
||||
|
||||
`Move / Rotate / Scale Gizmo` 类应主要负责:
|
||||
|
||||
- drag 状态机
|
||||
- 轴向约束
|
||||
- plane 约束
|
||||
- 变换求解
|
||||
- 交互反馈求解
|
||||
|
||||
不再继续兼任:
|
||||
|
||||
- 实际几何绘制器
|
||||
- 实际命中主仲裁器
|
||||
|
||||
---
|
||||
|
||||
## 5. 推荐的目标架构
|
||||
|
||||
## 5.1 Render Request 层新增 `overlayPasses`
|
||||
|
||||
当前 `CameraRenderRequest` 里有:
|
||||
|
||||
- `preScenePasses`
|
||||
- `postScenePasses`
|
||||
- `builtinPostProcess`
|
||||
|
||||
但没有真正适合 editor world overlay 的最后一层。
|
||||
|
||||
建议新增:
|
||||
|
||||
- `overlayPasses`
|
||||
|
||||
执行顺序调整为:
|
||||
|
||||
1. `preScenePasses`
|
||||
2. scene geometry
|
||||
3. object id
|
||||
4. `postScenePasses`
|
||||
5. `builtinPostProcess`
|
||||
6. `overlayPasses`
|
||||
|
||||
这样 world overlay 才能稳定压在 grid 和 outline 之上,再由 ImGui 负责最后的 HUD。
|
||||
|
||||
### 5.2 新建 `SceneViewportOverlayFrameData`
|
||||
|
||||
建议新增一个独立的 frame data 结构,承载这一帧 Scene Viewport 的 editor overlay 数据。
|
||||
|
||||
建议字段:
|
||||
|
||||
- `linePrimitives`
|
||||
- `trianglePrimitives`
|
||||
- `billboardSprites`
|
||||
- `handleRecords`
|
||||
- `renderLayer`
|
||||
- `depthMode`
|
||||
- `screenSpaceThickness`
|
||||
|
||||
其中:
|
||||
|
||||
- primitive 用于绘制
|
||||
- handle record 用于命中
|
||||
- 两者共享相同的 `handleId`
|
||||
|
||||
### 5.3 新建 `SceneViewportOverlayBuilder`
|
||||
|
||||
职责:
|
||||
|
||||
- 接收 scene overlay context
|
||||
- 收集 selected objects
|
||||
- 构建 camera frustum
|
||||
- 构建 directional light 圆形底盘 gizmo
|
||||
- 构建 scene icons
|
||||
- 构建 transform gizmo handles
|
||||
- 输出统一的 `SceneViewportOverlayFrameData`
|
||||
|
||||
建议位置:
|
||||
|
||||
- `editor/src/Viewport/SceneViewportOverlayBuilder.h`
|
||||
- `editor/src/Viewport/SceneViewportOverlayBuilder.cpp`
|
||||
|
||||
### 5.4 新建 `SceneViewportOverlayHitTester`
|
||||
|
||||
职责:
|
||||
|
||||
- 基于 `SceneViewportOverlayFrameData::handleRecords` 做统一命中
|
||||
- 输出唯一的 hovered handle
|
||||
- 同一份数据同时服务 hover / click / drag begin
|
||||
|
||||
建议位置:
|
||||
|
||||
- `editor/src/Viewport/SceneViewportOverlayHitTester.h`
|
||||
- `editor/src/Viewport/SceneViewportOverlayHitTester.cpp`
|
||||
|
||||
### 5.5 新建 `SceneViewportEditorOverlayPass`
|
||||
|
||||
职责:
|
||||
|
||||
- 读取 `SceneViewportOverlayFrameData`
|
||||
- 用 GPU 绘制 line / fill / billboard
|
||||
- 负责世界空间 editor overlay 的正式渲染
|
||||
|
||||
建议位置:
|
||||
|
||||
- `editor/src/Viewport/Passes/SceneViewportEditorOverlayPass.h`
|
||||
- `editor/src/Viewport/Passes/SceneViewportEditorOverlayPass.cpp`
|
||||
|
||||
### 5.6 `SceneViewPanel` 的目标职责
|
||||
|
||||
重构后 `SceneViewPanel` 只负责:
|
||||
|
||||
- 顶部栏和 tools UI
|
||||
- tool mode / pivot / local-global 状态
|
||||
- 输入汇总
|
||||
- 与 viewport host service 交互
|
||||
- 显示固定 HUD
|
||||
|
||||
不再负责:
|
||||
|
||||
- world overlay 几何构建
|
||||
- icon 转屏幕
|
||||
- frustum / light gizmo 线框拼装
|
||||
- world overlay 主渲染
|
||||
|
||||
---
|
||||
|
||||
## 6. 模块职责重新划分
|
||||
|
||||
### 6.1 `SceneViewPanel`
|
||||
|
||||
保留:
|
||||
|
||||
- 面板 UI
|
||||
- 工具模式切换
|
||||
- 快捷键
|
||||
- 鼠标/键盘输入汇总
|
||||
- orientation gizmo
|
||||
|
||||
移出:
|
||||
|
||||
- world overlay primitive 构建
|
||||
- scene icon world/screen 几何生成
|
||||
- camera/light 线框绘制逻辑
|
||||
|
||||
### 6.2 `ViewportHostService`
|
||||
|
||||
新增职责:
|
||||
|
||||
- 组装 `SceneViewportOverlayFrameData`
|
||||
- 把 overlay pass 接到 render request
|
||||
|
||||
保留职责:
|
||||
|
||||
- scene view camera
|
||||
- viewport render target 管理
|
||||
- scene render request 提交
|
||||
- object id picking
|
||||
|
||||
### 6.3 Gizmo 求解器
|
||||
|
||||
`SceneViewportMoveGizmo / RotateGizmo / ScaleGizmo` 保留:
|
||||
|
||||
- 拖拽求解
|
||||
- 激活态
|
||||
- 交互反馈数据
|
||||
|
||||
逐步移除:
|
||||
|
||||
- 直接操作 ImGui draw data 的职责
|
||||
- 各自内部封闭的 hit test 决策权
|
||||
|
||||
### 6.4 Overlay Pass
|
||||
|
||||
只负责 GPU 绘制,不处理业务判断。
|
||||
|
||||
输入必须已经是“可直接画”的 primitive 数据,避免 pass 内部再知道 camera/light/gizmo 业务语义。
|
||||
|
||||
---
|
||||
|
||||
## 7. 推荐执行阶段
|
||||
|
||||
这次重构不能一次性大爆炸改完,但必须每一步都朝最终架构收敛,不能做过渡性屎层。
|
||||
|
||||
### Phase 0:冻结错误扩展方向
|
||||
|
||||
目标:
|
||||
|
||||
- 停止继续向 `SceneViewPanel.cpp` 添加新的 world overlay 绘制逻辑
|
||||
- 停止继续扩写 `SceneViewportOverlayRenderer.cpp` 为 ImGui world renderer
|
||||
|
||||
产出:
|
||||
|
||||
- 文档确认
|
||||
- 后续新增 world gizmo 一律走 overlay builder / pass 方向
|
||||
|
||||
### Phase 1:打通 `overlayPasses` 通道
|
||||
|
||||
目标:
|
||||
|
||||
- 给 `CameraRenderRequest` 新增 `overlayPasses`
|
||||
- 在 `CameraRenderer` 中调整执行顺序
|
||||
- 在 `ViewportHostService` 中接入 editor overlay pass sequence
|
||||
|
||||
产出:
|
||||
|
||||
- renderer 支持 scene 之后再画 editor overlay
|
||||
- 这一步允许先画空 pass,不做功能迁移
|
||||
|
||||
验收:
|
||||
|
||||
- 不影响现有 scene / grid / selection outline
|
||||
- `overlayPasses` 具备独立初始化、执行、释放边界
|
||||
|
||||
### Phase 2:迁移纯显示型 world overlay
|
||||
|
||||
优先迁移:
|
||||
|
||||
- camera frustum
|
||||
- camera/light scene icon
|
||||
- directional light gizmo
|
||||
|
||||
原因:
|
||||
|
||||
- 这些内容交互复杂度低
|
||||
- 最容易先把 `SceneViewPanel.cpp` 中世界几何拼装代码减掉
|
||||
|
||||
Directional Light 本阶段的目标形态:
|
||||
|
||||
- 圆形底盘
|
||||
- 光线分布在圆环或圆盘采样点上
|
||||
- 明确的世界朝向
|
||||
- 稳定屏幕线宽
|
||||
|
||||
验收:
|
||||
|
||||
- 这些 overlay 不再由 ImGui draw list 直接绘制
|
||||
- `SceneViewPanel.cpp` 不再负责生成对应线框
|
||||
|
||||
### Phase 3:迁移 Transform Gizmo 的绘制
|
||||
|
||||
目标:
|
||||
|
||||
- move / rotate / scale gizmo 的显示改为 overlay pass primitive
|
||||
- gizmo 类转为 handle builder + drag solver
|
||||
|
||||
当前进度:
|
||||
|
||||
- transform gizmo 已开始转成 transient overlay frame data
|
||||
- overlay pass 已可消费一批 screen-space triangle primitive 来绘制 gizmo 屏幕几何
|
||||
- 但 transient gizmo overlay 仍然由 `SceneViewPanel` 在帧末提交,尚未完全收口到 host / builder 的 canonical 路径
|
||||
|
||||
说明:
|
||||
|
||||
- 这一阶段只迁移“怎么画”
|
||||
- 可以暂时保留现有 drag 求解逻辑
|
||||
|
||||
验收:
|
||||
|
||||
- transform gizmo 已不依赖 ImGui world draw
|
||||
- gizmo 视觉反馈仍然可用
|
||||
|
||||
### Phase 4:统一命中系统
|
||||
|
||||
目标:
|
||||
|
||||
- 所有 world overlay 的 hover / click / drag begin 统一使用 `handleRecords`
|
||||
- 彻底删除 panel 里的多套 hit test 拼接逻辑
|
||||
|
||||
当前进度:
|
||||
|
||||
- `scene icon` 已完成
|
||||
- `transform gizmo` 的 hover / click-begin 已经开始接入统一 `handleRecords`
|
||||
- `drag begin` 之后的求解与 active 状态仍然保留在 gizmo 类与 `SceneViewPanel` 现有链路中
|
||||
|
||||
涵盖对象:
|
||||
|
||||
- transform gizmo
|
||||
- scene icon
|
||||
- 后续 camera/light/world helper handles
|
||||
|
||||
验收:
|
||||
|
||||
- 命中结果只由一份 canonical handle 数据决定
|
||||
- 不再依赖大量互相屏蔽的布尔条件
|
||||
|
||||
### Phase 5:删除旧世界 overlay 路径
|
||||
|
||||
目标:
|
||||
|
||||
- 删除 `SceneViewPanel.cpp` 中遗留的 world overlay 构建逻辑
|
||||
- 缩减 `SceneViewportOverlayRenderer.cpp` 到只保留 HUD 类渲染或直接拆分
|
||||
|
||||
最终保留:
|
||||
|
||||
- ImGui HUD
|
||||
- renderer world overlay
|
||||
|
||||
最终移除:
|
||||
|
||||
- ImGui world overlay
|
||||
|
||||
---
|
||||
|
||||
## 8. 第一阶段建议改动范围
|
||||
|
||||
如果按最小风险起步,第一轮只做下面这些:
|
||||
|
||||
- `engine/include/XCEngine/Rendering/CameraRenderRequest.h`
|
||||
- `engine/src/Rendering/CameraRenderer.cpp`
|
||||
- `editor/src/Viewport/ViewportHostService.h`
|
||||
- `editor/src/Viewport/ViewportHostRenderFlowUtils.h`
|
||||
- 新增 `editor/src/Viewport/Passes/SceneViewportEditorOverlayPass.*`
|
||||
|
||||
第一轮不碰:
|
||||
|
||||
- move/rotate/scale 的求解逻辑
|
||||
- Scene icon 的交互优先级逻辑
|
||||
- SceneViewPanel 的大面积交互重写
|
||||
|
||||
这样可以先把 renderer 通道立住,再分批迁移业务内容。
|
||||
|
||||
---
|
||||
|
||||
## 9. 方案边界
|
||||
|
||||
这次重构明确不做的内容:
|
||||
|
||||
- 不顺手做 local mode 新行为
|
||||
- 不顺手做 runtime 通用 debug draw 系统
|
||||
- 不顺手把所有 editor widget 一次性改成 pass
|
||||
- 不在本轮引入 render graph
|
||||
|
||||
这次只做一件事:
|
||||
|
||||
**把 Scene Viewport 中锚定世界空间的 editor overlay,从 ImGui 手搓模式收口为正式 renderer overlay 系统。**
|
||||
|
||||
---
|
||||
|
||||
## 10. 风险与控制
|
||||
|
||||
### 10.1 风险:一次性迁移过大
|
||||
|
||||
控制方式:
|
||||
|
||||
- 先打通 pass 通道
|
||||
- 再迁静态 overlay
|
||||
- 最后迁 transform gizmo 与命中
|
||||
|
||||
### 10.2 风险:命中系统重写影响交互稳定性
|
||||
|
||||
控制方式:
|
||||
|
||||
- handle record 和旧逻辑短期并存
|
||||
- 先让新系统服务 hover
|
||||
- 再切 click / drag begin
|
||||
|
||||
### 10.3 风险:D3D12-only pass 与后端扩展
|
||||
|
||||
控制方式:
|
||||
|
||||
- 第一阶段允许 editor overlay pass 先只支持 D3D12
|
||||
- 但数据结构和 pass 边界必须 backend-neutral
|
||||
|
||||
### 10.4 风险:继续出现“画的是一个,点的是另一个”
|
||||
|
||||
控制方式:
|
||||
|
||||
- 明确规定 overlay primitive 和 hit proxy 必须同源
|
||||
- 不能再允许绘制与命中分别各算一套几何
|
||||
|
||||
---
|
||||
|
||||
## 11. 最终验收标准
|
||||
|
||||
当以下条件全部满足时,说明收口完成:
|
||||
|
||||
- `SceneViewPanel.cpp` 不再承担 world overlay 几何构建职责
|
||||
- world anchored editor overlay 全部进入 renderer pass
|
||||
- transform gizmo / scene icon / camera frustum / light gizmo 使用统一 overlay frame data
|
||||
- hover / click / drag begin 使用统一 handle record
|
||||
- ImGui 只负责 HUD,不再负责世界空间 gizmo 主绘制
|
||||
- 新增一种 world gizmo 时,不需要再把世界转屏幕逻辑写回 panel
|
||||
|
||||
---
|
||||
|
||||
## 12. 对本次 Directional Light Gizmo 的直接指导
|
||||
|
||||
在该重构方案下,Directional Light Gizmo 的正确实现方式应是:
|
||||
|
||||
- 它属于 `World Anchored Overlay`
|
||||
- 它的几何由 `SceneViewportOverlayBuilder` 负责生成
|
||||
- 它的线段/圆环由 `SceneViewportEditorOverlayPass` 负责绘制
|
||||
- 它的样式使用“圆形底盘 + 圆周分布光线”,不再在 panel 中临时拼矩形列线
|
||||
|
||||
也就是说,Directional Light Gizmo 不应该被当成一个局部修补任务继续留在 `SceneViewPanel.cpp`。
|
||||
|
||||
---
|
||||
|
||||
## 13. 本文后的执行原则
|
||||
|
||||
在本方案审核通过之前:
|
||||
|
||||
- 允许修 bug
|
||||
- 不建议继续扩写新的 ImGui world overlay 逻辑
|
||||
|
||||
在本方案审核通过之后:
|
||||
|
||||
- 新增 world overlay 功能,优先接入 overlay builder / overlay pass
|
||||
- `SceneViewPanel.cpp` 只减不增
|
||||
@@ -0,0 +1,247 @@
|
||||
# Shader 与 Material 下一阶段:ShaderLab 正式化与 Builtin Shader 资产布局计划
|
||||
日期:`2026-04-07`
|
||||
|
||||
## 1. 阶段结论
|
||||
|
||||
上一阶段已经完成了最关键的主线收口:
|
||||
|
||||
- `.shader` 现在只表示 authoring shader,不再兼容 JSON manifest。
|
||||
- 旧的 manifest 主路径已经从运行时主流程移除。
|
||||
- shader / material / editor 相关测试已经回归通过。
|
||||
- 当前 shader 主线终于从“过渡态”进入了“可以继续正规化”的状态。
|
||||
|
||||
这意味着接下来不应该再围绕“兼容旧双路径”打补丁,而应该开始正式推进:
|
||||
|
||||
- `ShaderLab authoring`
|
||||
- `Material contract`
|
||||
- `builtin shader asset layout`
|
||||
- `runtime pass contract`
|
||||
|
||||
一起向 Unity 风格继续收口。
|
||||
|
||||
---
|
||||
|
||||
## 2. 当前真实状态
|
||||
|
||||
当前已经成立的事实:
|
||||
|
||||
1. `.shader` 主语义已经统一。
|
||||
2. authoring parser 已经能承载基础的 `Shader / Properties / SubShader / Pass / Tags / HLSLPROGRAM / pragma / 基础状态`。
|
||||
3. runtime 已经有 `Shader -> Pass -> Variant` 数据模型。
|
||||
4. builtin shader 已经基本都迁入 authoring 主路径。
|
||||
|
||||
但当前还没有完全完成的部分也很明确:
|
||||
|
||||
1. 语法还只是 Unity ShaderLab 的一个子集。
|
||||
2. builtin shader 资产目录结构还带有明显的过渡痕迹。
|
||||
3. material 与 shader 的契约虽然比之前干净,但还没完全达到 Unity 式心智模型。
|
||||
4. renderer 对 pass contract 的消费还可以继续正规化。
|
||||
|
||||
---
|
||||
|
||||
## 3. Builtin Shader 资产目录结论
|
||||
|
||||
这里先把结论写死:
|
||||
|
||||
- `engine/assets/builtin/shaders` 下的**主入口 shader 文件**,不需要再一 shader 一子文件夹。
|
||||
- 既然当前主入口已经都是单个 `.shader` 文件,那么更合理的结构应该是:
|
||||
|
||||
```text
|
||||
engine/assets/builtin/shaders/
|
||||
forward-lit.shader
|
||||
unlit.shader
|
||||
depth-only.shader
|
||||
shadow-caster.shader
|
||||
object-id.shader
|
||||
object-id-outline.shader
|
||||
skybox.shader
|
||||
color-scale-post-process.shader
|
||||
final-color.shader
|
||||
```
|
||||
|
||||
- 需要保留子目录的,不是 builtin shader 入口文件本身,而是**公用 include / shader library**。
|
||||
- 因此公共代码应该独立成类似:
|
||||
|
||||
```text
|
||||
engine/assets/shaderlib/
|
||||
Core.hlsl
|
||||
Common.hlsl
|
||||
Lighting.hlsl
|
||||
SpaceTransforms.hlsl
|
||||
Shadow.hlsl
|
||||
MaterialInput.hlsl
|
||||
```
|
||||
|
||||
也就是说:
|
||||
|
||||
- `builtin/shaders/`:放“逻辑 shader 资产入口”
|
||||
- `shaderlib/`:放“共享 include 库”
|
||||
|
||||
而不是继续维持“每个 shader 一个文件夹,文件名还重复一遍”的结构。
|
||||
|
||||
这更符合现在的真实资产形态,也更利于后续继续扩展 builtin shader 数量。
|
||||
|
||||
---
|
||||
|
||||
## 4. 下一阶段目标
|
||||
|
||||
下一阶段的目标不是做更多渲染效果,而是把 shader/material 底座继续正规化,达到可以稳定承接后续 SRP 的程度。
|
||||
|
||||
这一阶段的目标分成四件事:
|
||||
|
||||
1. 收口 builtin shader 资产布局。
|
||||
2. 扩展 ShaderLab authoring 子集,继续向 Unity 靠拢。
|
||||
3. 继续压缩 material 中残留的临时职责。
|
||||
4. 让 renderer 对 pass / keyword / variant 的消费边界更正式。
|
||||
|
||||
---
|
||||
|
||||
## 5. 分阶段执行
|
||||
|
||||
### Phase A:Builtin Shader 资产布局拍平
|
||||
|
||||
目标:
|
||||
|
||||
- 把 `engine/assets/builtin/shaders/*/* .shader` 收口成单层 `.shader` 文件布局。
|
||||
- 同步清理 `BuiltinResources` 中的路径映射和命名。
|
||||
|
||||
工作项:
|
||||
|
||||
1. 拍平 builtin shader 文件路径。
|
||||
2. 更新 `BuiltinResources.cpp/.h` 中的 builtin shader relative path 表。
|
||||
3. 回归所有 builtin shader loader 测试。
|
||||
4. 回归 editor / renderer 中依赖 builtin shader path 的测试。
|
||||
|
||||
完成标准:
|
||||
|
||||
- `engine/assets/builtin/shaders/` 单层化。
|
||||
- 所有 builtin shader 路径 helper 仍稳定工作。
|
||||
|
||||
### Phase B:扩展 ShaderLab authoring 子集
|
||||
|
||||
目标:
|
||||
|
||||
- 把当前 authoring 语法从“基础可用”推进到“真正像 Unity ShaderLab 的工程可用子集”。
|
||||
|
||||
优先支持:
|
||||
|
||||
- `BlendOp`
|
||||
- `Offset`
|
||||
- `Stencil`
|
||||
- `UsePass`
|
||||
- 更完整的 `Tags`
|
||||
- 更稳的 `SubShader` 级状态继承与覆盖规则
|
||||
|
||||
工作项:
|
||||
|
||||
1. 扩 parser / IR。
|
||||
2. 为新增语法补单测。
|
||||
3. 为 builtin shader 和后续材质/渲染用例补回归用例。
|
||||
|
||||
完成标准:
|
||||
|
||||
- 这些语法不再停留在计划里,而是进入实际 parser / runtime contract。
|
||||
|
||||
### Phase C:Material 契约继续收口
|
||||
|
||||
目标:
|
||||
|
||||
- 让 material 更接近 Unity 的角色定位:只管理 shader、properties、textures、keywords、必要的 render state override。
|
||||
|
||||
工作项:
|
||||
|
||||
1. 继续压缩 legacy `shaderPass` 的主路径影响范围。
|
||||
2. 梳理 property 到 constant buffer 的稳定映射。
|
||||
3. 梳理 keyword 集与 variant lookup 的契约边界。
|
||||
4. 审查 material loader 中是否还存在对旧 shader 体系的隐式兼容假设。
|
||||
|
||||
完成标准:
|
||||
|
||||
- material 不再承担本应属于 renderer 的 pass 选择职责。
|
||||
|
||||
### Phase D:Renderer 消费链继续正规化
|
||||
|
||||
目标:
|
||||
|
||||
- 让 renderer 更正式地围绕 `LightMode / pass contract / keywords / backend` 选用 pass 与 variant。
|
||||
|
||||
工作项:
|
||||
|
||||
1. 审查 builtin pipeline 中的 pass 选择逻辑。
|
||||
2. 审查 keyword 参与 variant 选择与 pipeline cache 的路径。
|
||||
3. 清理仍然依赖旧约定字符串兜底的代码。
|
||||
|
||||
完成标准:
|
||||
|
||||
- shader/material/runtime 三者的职责边界更加稳定,不再互相越界兜底。
|
||||
|
||||
---
|
||||
|
||||
## 6. 测试要求
|
||||
|
||||
这一阶段必须保持“每做一层就立刻回归”,不能再先堆实现后补测试。
|
||||
|
||||
至少要持续回归:
|
||||
|
||||
- `shader_tests`
|
||||
- `material_tests`
|
||||
- `editor_tests` 中 shader path / viewport render flow / overlay 相关用例
|
||||
- `XCEditor` 编译
|
||||
- 受影响的 rendering 单测与关键集成测试
|
||||
|
||||
如果 builtin shader 资产布局拍平,必须额外回归:
|
||||
|
||||
- builtin shader loader
|
||||
- object-id / outline / grid / final-color / skybox 相关路径与运行时消费
|
||||
|
||||
---
|
||||
|
||||
## 7. 风险与控制
|
||||
|
||||
### 风险 1:目录结构重构把路径引用打坏
|
||||
|
||||
控制策略:
|
||||
|
||||
- 先只拍平 builtin shader 主入口文件。
|
||||
- `shaderlib` 不混入 `builtin/shaders` 同层迁移,避免一次改太多。
|
||||
- 先跑 loader / editor path / renderer path 回归,再考虑下一层。
|
||||
|
||||
### 风险 2:语法扩展过快,把当前稳定 authoring 再次打回过渡态
|
||||
|
||||
控制策略:
|
||||
|
||||
- 只扩“明确服务于 Unity 风格主线”的语法。
|
||||
- 不引入新的双路径兼容层。
|
||||
- 任何新语法都必须先建测试,再接运行时。
|
||||
|
||||
### 风险 3:material 与 renderer 职责再次混淆
|
||||
|
||||
控制策略:
|
||||
|
||||
- 每做一项都用“这件事在 Unity 里是谁负责”来校验职责归属。
|
||||
|
||||
---
|
||||
|
||||
## 8. 收口判定
|
||||
|
||||
满足下面条件时,这一阶段可以认为完成:
|
||||
|
||||
1. builtin shader 资产目录已经拍平到单层主入口结构。
|
||||
2. `BuiltinResources` 与相关路径 helper 已同步完成。
|
||||
3. ShaderLab authoring 子集新增一轮关键语法支持并有测试覆盖。
|
||||
4. material 对旧路径的临时兼容进一步缩小。
|
||||
5. renderer 的 pass / variant 消费逻辑进一步正规化。
|
||||
6. shader / material / editor / XCEditor 回归全部稳定。
|
||||
|
||||
---
|
||||
|
||||
## 9. 下一步执行顺序
|
||||
|
||||
建议的实际执行顺序如下:
|
||||
|
||||
1. 先做 builtin shader 资产布局拍平。
|
||||
2. 立刻回归 shader/material/editor 路径相关测试。
|
||||
3. 再开始扩 ShaderLab 子集。
|
||||
4. 然后收 material 与 renderer 的契约边界。
|
||||
|
||||
也就是说,**下一步最应该先做的不是再加语法,而是先把 builtin shader 资产布局收干净。**
|
||||
506
docs/used/Shader与Material系统下一阶段计划_完成归档_2026-04-04.md
Normal file
506
docs/used/Shader与Material系统下一阶段计划_完成归档_2026-04-04.md
Normal file
@@ -0,0 +1,506 @@
|
||||
# Shader 与 Material 系统下一阶段计划
|
||||
|
||||
日期:`2026-04-03`
|
||||
|
||||
## 1. 阶段结论
|
||||
|
||||
当前 Renderer 这一轮主线已经完成收口,但完成的是“基础运行时闭环”,不是“最终的 Unity 风格 shader/material 体系”。
|
||||
|
||||
已经完成并应视为当前基线的内容:
|
||||
|
||||
- `Shader` 运行时契约已具备 `properties / passes / resources / backend variants`
|
||||
- builtin shader 资源已经外置,运行时不再依赖 C++ 内嵌 fallback
|
||||
- `Material` 对 builtin forward 的基础属性解析已经优先走 shader semantic
|
||||
- `BuiltinForwardPipeline` 已按 shader pass `resources` 合约生成 pipeline layout 与 descriptor binding
|
||||
- `Shader` 已接入 `AssetDatabase / Library` 流程,shader import 会生成 `main.xcshader`
|
||||
- `ShaderLoader` 已支持加载 `.xcshader` artifact
|
||||
- shader manifest 依赖与 `Material -> Shader` 依赖已进入资产追踪链
|
||||
- `rendering_unit_tests`
|
||||
- `rendering_integration_textured_quad_scene`
|
||||
- `rendering_integration_backpack_lit_scene`
|
||||
- `shader_tests`
|
||||
- `material_tests`
|
||||
|
||||
三后端验证当前是稳定的:
|
||||
|
||||
- D3D12:通过
|
||||
- OpenGL:通过
|
||||
- Vulkan:通过
|
||||
|
||||
但这仍然只是“Shader / Material Runtime 的第一层骨架”。
|
||||
|
||||
当前真正还没有完成的是:
|
||||
|
||||
- Unity 风格的 shader authoring 入口
|
||||
- 正式的 material schema / instance contract
|
||||
- 从 shader property layout 到 GPU material layout 的通用映射
|
||||
- 从 builtin forward 扩展到更通用 pass 的正式执行模型
|
||||
|
||||
## 2. 旧计划归档说明
|
||||
|
||||
以下两份计划文档已经完成历史使命,应归入 `docs/used/`:
|
||||
|
||||
- `Renderer模块设计与实现.md`
|
||||
- `Renderer下一阶段_ShaderMaterial与Pass体系设计.md`
|
||||
|
||||
原因不是它们“写错了”,而是:
|
||||
|
||||
- 第一份解决的是 Renderer 模块从无到有的问题,当前骨架已经落地
|
||||
- 第二份解决的是“为什么下一阶段先做 shader/material/pass contract,而不是 render graph”的阶段判断;这份判断已经部分兑现,整体已过期
|
||||
|
||||
本文件接手它们之后的主线,只保留对当前 checkout 仍然有效的目标。
|
||||
|
||||
## 3. 当前真实问题
|
||||
|
||||
### 3.1 Shader 运行时有了,但 authoring 还没有正式化
|
||||
|
||||
现在的运行时已经能消费:
|
||||
|
||||
- shader property
|
||||
- pass tag
|
||||
- pass resource binding
|
||||
- backend variant
|
||||
|
||||
但作者侧仍然不是最终形态。
|
||||
|
||||
当前还缺:
|
||||
|
||||
- 面向用户的 Unity 风格 `.shader` 语法入口
|
||||
- import 阶段把 authoring 语法转换为 runtime contract 的正式流程
|
||||
- shader 资产与 Library artifact 的稳定产物边界
|
||||
|
||||
### 3.2 Material 仍偏“资源容器”,还不是正式材质实例系统
|
||||
|
||||
当前 `Material` 已有:
|
||||
|
||||
- shader 引用
|
||||
- render state
|
||||
- property / texture 覆盖
|
||||
- tag / queue
|
||||
|
||||
但它还缺少真正用于 Renderer 执行的正式约束:
|
||||
|
||||
- 基于 shader property schema 的类型验证
|
||||
- property 默认值与 override 的统一解析
|
||||
- per-pass material constant layout
|
||||
- texture / sampler / buffer 到 pass resource 的正式映射
|
||||
- renderer 侧可缓存、可失效、可复用的 material binding plan
|
||||
|
||||
### 3.3 现有 pass contract 仍偏 builtin-forward 视角
|
||||
|
||||
当前 forward 主链已经能跑,但完整的 pass contract 还没有正式化为可扩展系统。
|
||||
|
||||
后续至少要能稳定承接:
|
||||
|
||||
- `ForwardLit`
|
||||
- `Unlit`
|
||||
- `DepthOnly`
|
||||
- `ShadowCaster`
|
||||
- `ObjectId`
|
||||
|
||||
否则后面一旦开始做阴影、深度预通道、更多 editor/runtime helper pass,就会重新退化回 pipeline 内部的条件分支拼装。
|
||||
|
||||
### 3.4 三后端问题的本质不是“语法不同”,而是“资产如何统一”
|
||||
|
||||
当前真正要解决的,不是简单回答“到底用 GLSL 还是 HLSL”,而是明确三层边界:
|
||||
|
||||
1. 对外 authoring 语法是什么
|
||||
2. import 后的内部运行时资产是什么
|
||||
3. 每个 backend 最终执行的 variant 是什么
|
||||
|
||||
这三层不分开,后面一定会把 authoring、runtime、backend 编译链搅在一起。
|
||||
|
||||
## 4. 下一阶段的目标
|
||||
|
||||
下一阶段只做一件事:把 `Shader` 和 `Material` 从“能支撑当前 builtin forward 的运行时拼装”升级为“能长期承接 Unity 风格渲染架构的正式系统”。
|
||||
|
||||
### 4.1 对外 authoring 语法目标:严格向 Unity 对齐
|
||||
|
||||
最终对外公开的 shader 语法目标,必须与 Unity 的使用方式保持一致。
|
||||
|
||||
目标形态应当是:
|
||||
|
||||
- 单个 `.shader` 文件作为逻辑 shader 入口
|
||||
- `Shader / Properties / SubShader / Pass` 的层级结构
|
||||
- pass 内通过 `HLSLPROGRAM ... ENDHLSL` 或等价块组织代码
|
||||
- 通过 `#pragma vertex` / `#pragma fragment` 指定 stage 入口
|
||||
|
||||
也就是说:
|
||||
|
||||
- 对外 authoring 视角应当是“Unity 风格的一体化 shader 文件”
|
||||
- 不是要求作者直接去维护一堆 runtime JSON manifest
|
||||
- 也不是让上层逻辑直接感知 D3D12/OpenGL/Vulkan 各自的底层差异
|
||||
|
||||
### 4.2 对内 runtime 资产目标:继续保留 contract 模型
|
||||
|
||||
虽然 authoring 目标要严格向 Unity 靠拢,但 runtime 不应直接拿 authoring AST 当执行数据。
|
||||
|
||||
运行时仍应落到清晰的 contract:
|
||||
|
||||
```text
|
||||
Shader Asset
|
||||
-> Properties
|
||||
-> Passes
|
||||
-> Tags
|
||||
-> Resource Bindings
|
||||
-> Backend Variants
|
||||
```
|
||||
|
||||
原因很直接:
|
||||
|
||||
- Renderer 需要稳定、扁平、可缓存的数据结构
|
||||
- 三后端最终执行的仍然是 backend variant
|
||||
- material schema 与 pass binding 都需要基于 import 结果,而不是原始文本
|
||||
|
||||
结论是:
|
||||
|
||||
- 外部写法要像 Unity
|
||||
- 内部执行模型继续使用现在这套 runtime contract,并进一步完善
|
||||
|
||||
### 4.3 Material 目标:从资源对象升级为正式材质实例
|
||||
|
||||
Material 下一阶段的核心不是“多支持几个 SetFloat”,而是建立正式实例语义。
|
||||
|
||||
Material 至少要明确:
|
||||
|
||||
- 引用哪个 shader
|
||||
- 使用哪个 pass 或 pass 策略
|
||||
- 每个 property 的默认值、覆盖值、类型与序列化规则
|
||||
- 每个 pass 对应的 material constant block 如何布局
|
||||
- 每个 texture / sampler / buffer 如何映射到 pass resource
|
||||
|
||||
Renderer 侧则必须能把这些内容稳定编译成:
|
||||
|
||||
- material binding key
|
||||
- material constant payload
|
||||
- descriptor update plan
|
||||
- pipeline compatibility key
|
||||
|
||||
## 5. 推荐架构
|
||||
|
||||
### 5.1 分成三层,不混写
|
||||
|
||||
推荐明确拆成三层:
|
||||
|
||||
```text
|
||||
Unity-like Shader Authoring (.shader)
|
||||
-> Shader Importer
|
||||
-> Runtime Shader Contract
|
||||
-> Backend Variants / Material Binding Plan
|
||||
```
|
||||
|
||||
三层职责分别是:
|
||||
|
||||
- authoring 层:给人写、给 editor 看
|
||||
- importer 层:把 authoring 语法转成稳定运行时资产
|
||||
- runtime 层:给 renderer 执行、缓存、绑定、测试
|
||||
|
||||
### 5.2 Shader 的 public contract 与 backend contract 分离
|
||||
|
||||
下一阶段不建议把“Unity 风格语法”直接等同于“单源码自动跨平台编译已完全成熟”。
|
||||
|
||||
更务实的路线是:
|
||||
|
||||
- public contract 先统一成 Unity 风格 `.shader`
|
||||
- importer 先产出统一 runtime contract
|
||||
- backend variant 暂时仍允许按 backend 持有各自的编译输入或中间产物
|
||||
|
||||
这意味着:
|
||||
|
||||
- 作者看到的是统一 shader
|
||||
- Renderer 消费的是统一 runtime contract
|
||||
- backend 最终执行的仍然可以是不同 variant
|
||||
|
||||
这个分层既不违背 Unity 风格目标,也不会过早把工程拖进复杂的全平台 shader 编译链泥潭。
|
||||
|
||||
### 5.3 Vertex / Fragment 的外部写法按 Unity 组织,内部可拆分
|
||||
|
||||
对外语义上,vertex / fragment 应当属于同一个 pass。
|
||||
|
||||
也就是说,public authoring 角度要符合 Unity:
|
||||
|
||||
- 一个 shader
|
||||
- 一个或多个 subshader
|
||||
- 一个或多个 pass
|
||||
- 每个 pass 里通过 pragma 指定 vertex / fragment
|
||||
|
||||
但内部 import/runtime 完全可以把它们拆成:
|
||||
|
||||
- pass descriptor
|
||||
- vertex stage variant
|
||||
- fragment stage variant
|
||||
|
||||
外部合一,内部拆开,这是最稳妥的做法。
|
||||
|
||||
## 6. 下一阶段实施顺序
|
||||
|
||||
### 阶段 D0:先打通 Shader Import / Artifact 基础设施(已完成)
|
||||
|
||||
这是当前 checkout 在 `2026-04-03` 已经完成的新增里程碑。
|
||||
|
||||
完成内容:
|
||||
|
||||
- `ShaderImporter` 已接管 `.shader / .hlsl / .glsl / .vert / .frag / .geom / .comp`
|
||||
- shader import 结果会写入 `Library/Artifacts/.../main.xcshader`
|
||||
- `ShaderLoader` 已支持直接读取 `.xcshader`
|
||||
- shader manifest 中声明的 stage 源文件会进入依赖追踪
|
||||
- `Material` 对引用 shader 的直接依赖也已进入依赖追踪
|
||||
- `shader_tests` 与 `material_tests` 已覆盖 shader artifact 生成、加载与重导场景
|
||||
|
||||
这一步的意义不是“最终方案已完成”,而是先把 shader 纳入和 texture/material/mesh 一致的资产闭环。
|
||||
|
||||
没有这一步,后续不管做 Unity 风格 frontend,还是做 material schema,都会一直建立在“运行时临时解析源码”的不稳定基础上。
|
||||
|
||||
### 阶段 0:当前基线确认
|
||||
|
||||
这部分已经完成,不再作为待办:
|
||||
|
||||
- runtime shader contract 已建立
|
||||
- builtin forward 已按 pass resources 驱动
|
||||
- 三后端渲染回归通过
|
||||
|
||||
### 阶段 A:建立 Unity 风格 Shader Authoring Frontend
|
||||
|
||||
目标:
|
||||
|
||||
- 新增 Unity 风格 `.shader` authoring 入口
|
||||
- importer 能解析最小闭环子集
|
||||
|
||||
第一批建议支持的子集:
|
||||
|
||||
- `Shader`
|
||||
- `Properties`
|
||||
- `SubShader`
|
||||
- `Tags`
|
||||
- `Pass`
|
||||
- `HLSLPROGRAM / ENDHLSL`
|
||||
- `#pragma vertex`
|
||||
- `#pragma fragment`
|
||||
|
||||
交付标准:
|
||||
|
||||
- builtin `forward-lit`
|
||||
- builtin `unlit`
|
||||
- builtin `object-id`
|
||||
- builtin `infinite-grid`
|
||||
|
||||
至少迁移其中一条主线并成功跑通三后端测试。
|
||||
|
||||
### 阶段 B:建立正式的 Material Schema 与 Instance Contract
|
||||
|
||||
目标:
|
||||
|
||||
- shader importer 输出可供 material 消费的 property schema
|
||||
- material 对 property override 做类型校验与默认值回退
|
||||
- 为 pass 生成 material constant layout 与 resource mapping
|
||||
|
||||
交付标准:
|
||||
|
||||
- material 不再只靠 builtin alias 名字兜底
|
||||
- shader property semantic 变成正式主路径,而不是兼容性补丁
|
||||
- renderer 能从 shader schema 生成 material binding payload
|
||||
|
||||
当前建议把这一阶段作为下一步主线。
|
||||
|
||||
原因:
|
||||
|
||||
- shader artifact 与依赖追踪已经到位,shader 现在可以作为稳定 schema 来源
|
||||
- material 仍然缺少基于 shader property 的正式类型校验、默认值回退和资源映射
|
||||
- renderer 目前虽然能消费 pass resources,但 material binding 仍偏 builtin-forward 特判
|
||||
|
||||
当前进展(`2026-04-03`):
|
||||
|
||||
- 已完成:shader schema 驱动的 property 类型校验与默认值回退
|
||||
- 已完成:source `.material` 的 `properties` authoring 入口
|
||||
- 已完成:material constant layout runtime contract
|
||||
- `Material` 现在会生成正式的 constant layout 元数据
|
||||
- layout 字段包含 `name / type / offset / size / alignedSize`
|
||||
- renderer 读取的已不再只是裸字节 payload,而是 `layout + payload` 组合
|
||||
- 已完成:builtin pass resource mapping / material binding plan runtime contract
|
||||
- `RenderMaterialUtility` 现在统一提供 `PassResourceBindingLocation / BuiltinPassResourceBindingPlan`
|
||||
- 显式 shader pass `resources` 与 legacy builtin forward fallback 已走同一套解析与校验路径
|
||||
- `BuiltinForwardPipeline` 已改为消费通用 binding plan,而不是继续内联 forward 特判绑定逻辑
|
||||
- 已验证:`rendering_unit_tests` 57/57,`material_tests` 51/51
|
||||
- 下一步:把这套 pass binding plan 继续推到 `Unlit / ObjectId` 等 pass,收敛成真正共享的 shader/material 执行边界
|
||||
|
||||
### 阶段 C:把 Pass Binding 扩展为正式材质执行链路
|
||||
|
||||
目标:
|
||||
|
||||
- 不只是 builtin forward 能吃 pass resources
|
||||
- `Unlit`、`ObjectId` 也逐步切到同一套 shader/material contract
|
||||
- pipeline state key 与 descriptor binding plan 从“按功能写逻辑”升级到“按 shader pass contract 解析”
|
||||
|
||||
交付标准:
|
||||
|
||||
- 至少 `ForwardLit + Unlit + ObjectId` 共用同一套 shader/material 执行边界
|
||||
- 新增 pass 不再默认要求先写一套新的硬编码 binding 路径
|
||||
|
||||
当前进展(`2026-04-04`):
|
||||
|
||||
- 已完成:builtin `ObjectId` pass 接入通用 pass binding plan
|
||||
- builtin object-id shader 已显式声明 `PerObject` 资源合约
|
||||
- `BuiltinObjectIdPass` 已改为消费通用 binding plan,不再硬编码 `set0/binding0` 常量布局
|
||||
- 显式 shader `resources` 与 legacy object-id fallback 现在走同一套解析与校验路径
|
||||
- 已完成:builtin `Unlit` shader / pipeline 主线接入共享执行边界
|
||||
- 新增 builtin `unlit` shader 资产与 `BuiltinResources` 入口
|
||||
- `BuiltinForwardPipeline` 现在会在 `ForwardLit + Unlit` 之间按 material/shader metadata 解析目标 pass
|
||||
- `Unlit` 与 `ForwardLit` 现在共用同一套 input layout、material schema、binding plan 与 descriptor 组装路径
|
||||
- 已完成:抽出 `ForwardLit / Unlit / ObjectId` 共用的 pass layout / descriptor set 组装骨架
|
||||
- `RenderMaterialUtility` 现在统一提供 `BuiltinPassSetLayoutMetadata` 与 `TryBuildBuiltinPassSetLayouts(...)`
|
||||
- `BuiltinForwardPipeline` 与 `BuiltinObjectIdPass` 现在都复用同一套 `binding plan -> set layout -> pipeline layout` 组装路径
|
||||
- forward 侧只保留 set0 compatibility fallback 与 draw/update 逻辑;object-id 侧只保留自身约束校验与 per-object 常量写入
|
||||
- 已完成:builtin `DepthOnly / ShadowCaster` shader 与独立 pass skeleton 落地
|
||||
- 新增 builtin `depth-only` 与 `shadow-caster` shader 资产,以及 `BuiltinResources` 对应入口
|
||||
- 新增 `BuiltinDepthOnlyPass / BuiltinShadowCasterPass`,作为独立 `RenderPass` 复用同一套 shared pass-layout skeleton
|
||||
- 两个 pass 当前先收敛到 `PerObject` 常量路径;opaque 物体走 builtin fallback,`ShadowCaster` 额外尊重 `MeshRenderer.castShadows`
|
||||
- 这一步解决的是“pass contract 与执行骨架缺失”,还没有把 shadow map / light-space request flow 一次性做完
|
||||
- 已完成:`CameraRenderRequest + CameraRenderer` 正式接入 `DepthOnly / ShadowCaster` request 流程
|
||||
- 新增 `depthOnly / shadowCaster` request,支持独立 surface、clear flags / clear color,以及可选 `RenderCameraData` override
|
||||
- `CameraRenderer` 现在按 `ShadowCaster -> DepthOnly -> Forward -> ObjectId` 的顺序执行这些请求,`BuiltinDepthStylePassBase` 也会按 request clear flags 清理目标
|
||||
- 已验证:`rendering_unit_tests` 73/73
|
||||
- 已验证:`rendering_integration_textured_quad_scene` 3/3(D3D12 / OpenGL / Vulkan)
|
||||
- 已验证:`rendering_integration_unlit_scene` 3/3(D3D12 / OpenGL / Vulkan)
|
||||
- 已验证:`rendering_integration_object_id_scene` 3/3(D3D12 / OpenGL / Vulkan)
|
||||
- 下一步:如果继续沿 renderer 主线收口,优先补 `DepthOnly / ShadowCaster` 的真实 cross-backend integration coverage,并决定是否把 shadow-map 结果继续接回 forward lighting 消费链;如果先控制范围,request 流程这一块已经收口
|
||||
|
||||
### 阶段 D:扩展 AssetDatabase / Library Artifact 能力
|
||||
|
||||
目标:
|
||||
|
||||
- 在已完成的 shader artifact 基础上,继续扩展 import 产物边界
|
||||
- backend variant 的编译输入、中间产物或缓存策略进入 `Library/Artifacts`
|
||||
- 为后续 Unity 风格 `.shader` frontend 预留稳定 importer 输出层
|
||||
|
||||
交付标准:
|
||||
|
||||
- 资源改动能够稳定触发 shader/material 重新导入
|
||||
- editor/runtime 读取的是 import 后资产,不是源码临时解析
|
||||
- shader importer 不再只服务当前 JSON manifest 兼容路径,也能承接下一步 authoring frontend
|
||||
|
||||
### 阶段 E:测试与回归收口
|
||||
|
||||
目标:
|
||||
|
||||
- 给 shader importer、material schema、binding plan 增加 unit tests
|
||||
- 对 forward/unlit/object-id 增加 integration coverage
|
||||
- 保持 D3D12 / OpenGL / Vulkan 一致回归
|
||||
|
||||
最低验证集:
|
||||
|
||||
- `shader_tests`
|
||||
- `material_tests`
|
||||
- `rendering_unit_tests`
|
||||
- `rendering_integration_textured_quad_scene`
|
||||
- `rendering_integration_backpack_lit_scene`
|
||||
|
||||
必要时新增:
|
||||
|
||||
- `rendering_integration_unlit_scene`
|
||||
- `rendering_integration_object_id_scene`
|
||||
|
||||
当前进展(`2026-04-04`):
|
||||
|
||||
- 已完成:`rendering_integration_unlit_scene`
|
||||
- 显式使用 builtin `unlit` shader + `Unlit` pass,覆盖 `BuiltinForwardPipeline` 的 `ForwardLit / Unlit` pass 选择路径
|
||||
- 复用 `textured_quad_scene` 构图做最小差异回归,验证 shader/material 新 contract 不改变既有画面输出
|
||||
- 已验证:`rendering_integration_unlit_scene`
|
||||
- D3D12:通过
|
||||
- OpenGL:通过
|
||||
- Vulkan:通过
|
||||
- 已完成:`rendering_integration_object_id_scene`
|
||||
- 新增独立的 object-id integration scene,直接验证 object-id 输出采样点,而不是再维护一张新的大尺寸 GT 图片
|
||||
- 覆盖 `CameraRenderer + BuiltinObjectIdPass` 路径,以及 `Forward -> ObjectId -> Copy/Screenshot` 的跨 pass 回归
|
||||
- 修正了 `BuiltinObjectIdPass` 在 Vulkan 下的顶点输入步长问题,并让 object-id pass 自己清理/写入 depth,避免依赖前一 pass 的 depth 复用状态
|
||||
- 已验证:`rendering_integration_object_id_scene`
|
||||
- D3D12:通过
|
||||
- OpenGL:通过
|
||||
- Vulkan:通过
|
||||
- 阶段 E 当前状态:`unlit_scene` 与 `object_id_scene` 均已完成并通过三后端验证,本阶段可以收口
|
||||
|
||||
## 7. 当前阶段明确不做
|
||||
|
||||
下一阶段不应把范围扩散到下面这些方向:
|
||||
|
||||
- render graph
|
||||
- shader graph
|
||||
- 全平台单源码自动转译一次性做完
|
||||
- 完整 SRP scripting API
|
||||
- 大规模后处理框架
|
||||
|
||||
这些都依赖 shader/material 正式体系先稳定下来。
|
||||
|
||||
## 8. 成功标准
|
||||
|
||||
这个阶段完成时,应该满足下面几个判断:
|
||||
|
||||
- 作者侧已经可以写 Unity 风格的 `.shader`
|
||||
- runtime 已不再依赖手写 JSON manifest 才能描述 pass contract
|
||||
- material 能基于 shader schema 做正式绑定,而不是 builtin 特判兜底
|
||||
- 至少 `ForwardLit / Unlit / ObjectId` 三类 pass 共用统一 shader/material 执行边界
|
||||
- 三后端回归测试仍稳定通过
|
||||
|
||||
## 9. 一句话总结
|
||||
|
||||
下一阶段不是继续给 builtin forward 打补丁,而是把 `Shader` 和 `Material` 正式提升为 Unity 风格渲染架构中的稳定中层资产与执行契约。
|
||||
|
||||
## 10. 快速收口策略(`2026-04-04`)
|
||||
|
||||
目标收窄为只处理 `shader / material` 核心主线,不继续扩散到完整阴影功能、render graph、shader graph 或 editor 外围能力。
|
||||
|
||||
按下面顺序收口:
|
||||
|
||||
1. 先完成 Unity-like `.shader` authoring MVP importer
|
||||
- 允许最小子集:`Shader / Properties / SubShader / Tags / Pass / HLSLPROGRAM / #pragma vertex / #pragma fragment`
|
||||
- importer 输出继续复用当前 runtime shader contract:`properties / passes / resources / backend variants`
|
||||
- 这一阶段不追求完整 Unity ShaderLab,只做 builtin 与主线材质系统需要的最小闭环
|
||||
|
||||
2. 再迁移 builtin shader 到新 authoring 入口
|
||||
- 优先 `ForwardLit / Unlit / ObjectId / DepthOnly / ShadowCaster`
|
||||
- 要求 importer 产出的 runtime contract 与当前 renderer 消费路径保持一致
|
||||
|
||||
3. 然后收紧 material 主路径
|
||||
- 以 imported shader schema 为主路径完成 property 类型校验、默认值回退、constant layout 与 resource mapping
|
||||
- builtin alias / canonical-name fallback 只保留兼容兜底,不再作为主执行路径
|
||||
|
||||
4. 最后做最小回归集收口
|
||||
- `shader_tests`
|
||||
- `material_tests`
|
||||
- `rendering_unit_tests`
|
||||
- 必要的 rendering integration smoke
|
||||
|
||||
当前进展(`2026-04-04`):
|
||||
|
||||
- 已完成:Step 1 `Unity-like .shader authoring MVP importer`
|
||||
- `ShaderLoader` 新增 Unity-like `.shader` authoring 识别与解析入口,但保留现有 JSON manifest `.shader` 兼容路径不动
|
||||
- importer 继续落到现有 runtime shader contract:`properties / passes / resources / backend variants`
|
||||
- `CollectSourceDependencies` 已覆盖新 authoring 路径,`AssetDatabase` 会继续追踪各 backend stage 文件依赖并参与重导入
|
||||
- 已完成:Step 2 `builtin shader 迁到新 authoring 入口`
|
||||
- `forward-lit / unlit / object-id / depth-only / shadow-caster` 五个 builtin `.shader` 入口已全部切到 Unity-like authoring
|
||||
- stage 源文件、builtin shader 路径与 renderer 消费 contract 保持不变,迁移只发生在 authoring 入口层
|
||||
- 补充 `DepthOnly / ShadowCaster` builtin shader loader 覆盖,确保五类 builtin pass 都经过新 authoring 路径验证
|
||||
- 已完成:Step 3 `material 主路径收紧到 imported shader schema`
|
||||
- `MaterialLoader` 在存在 shader schema 时,`properties / textures` 中的旧 key 会先解析到 shader property semantic,再落到 shader 正式属性名
|
||||
- 旧的 `baseColor / baseColorTexture` 等兼容 key 仍可导入,但只作为兼容输入存在,不再直接污染 material 主执行路径
|
||||
- 当 material 绑定 shader schema 后,未知 texture binding 现在会被显式拒绝,不再静默忽略
|
||||
- 已验证:`shader_tests` 中新增 authoring 直载与 artifact/reimport 覆盖
|
||||
- 已验证:`shader_tests` 31/31 通过,builtin `ForwardLit / Unlit / ObjectId / DepthOnly / ShadowCaster` 全部通过加载与 backend variant 覆盖
|
||||
- 已验证:`material_tests` 53/53 通过,schema 驱动的 property/texture 映射与未知 binding 拒绝路径都已覆盖
|
||||
- 已完成:Step 4 `最小回归集收口`
|
||||
- `rendering_unit_tests` 73/73 通过,builtin pass contract 与 renderer 侧消费路径在当前重构后保持稳定
|
||||
- 本轮最小回归集结果:`shader_tests` 31/31,`material_tests` 53/53,`rendering_unit_tests` 73/73
|
||||
- 以当前目标范围看,`shader / material` 核心主线已经可以阶段性收口
|
||||
- 补充验收(`2026-04-04`):
|
||||
- 补跑 integration smoke 时发现并修复了一处真实回归:Unity-like `.shader` authoring 将 HLSL 的 `MainVS / MainPS` 入口错误套到了 GLSL/Vulkan variant,上层表现为 Vulkan `BuiltinForwardPipeline` 建 pipeline 失败
|
||||
- 修复后补跑 `rendering_integration_textured_quad_scene` 与 `rendering_integration_unlit_scene`、`rendering_integration_object_id_scene`,三者在 `D3D12 / OpenGL / Vulkan` 下均通过
|
||||
- 额外补跑 `rendering_integration_backpack_lit_scene` 时,暴露出一条相邻但不同范围的问题:direct `MeshLoader` 导入的 mesh/material/texture 生命周期路径存在异常退出/不干净收尾,已超出本次 `shader / material contract` 收口范围
|
||||
- 因此本计划按“核心主线已收口,附带一条相邻 residual risk”归档;若后续继续补强,优先单独开一轮处理 `MeshLoader + imported subresource lifetime`
|
||||
- 下一步:从当前目标范围出发,本计划可归档;后续如继续推进,请以新计划承接 `backpack_lit_scene` 这条相邻问题
|
||||
|
||||
当前阶段明确不做:
|
||||
|
||||
- 完整阴影贴图消费链
|
||||
- render graph
|
||||
- shader graph
|
||||
- 完整 Unity ShaderLab 全语法
|
||||
- 与 shader/material 主线无关的 editor/ui 扩展
|
||||
48
docs/used/Subplan-01_XCUI-Core-Tree-State.md
Normal file
48
docs/used/Subplan-01_XCUI-Core-Tree-State.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# Subplan 01:XCUI Core Tree / State / Invalidation
|
||||
|
||||
目标:
|
||||
|
||||
- 搭出 XCUI 的 retained-mode 核心骨架。
|
||||
- 明确 `ElementTree`、`NodeId`、`View`、`ViewModel`、`dirty flag`、`rebuild`、`lifecycle` 的最小闭环。
|
||||
|
||||
负责人边界:
|
||||
|
||||
- 负责 `engine/include/XCEngine/UI/` 与 `engine/src/UI/Core/` 的核心树模型。
|
||||
- 不负责具体布局算法。
|
||||
- 不负责 ImGui 适配绘制。
|
||||
|
||||
建议目录:
|
||||
|
||||
- `engine/include/XCEngine/UI/Core/`
|
||||
- `engine/src/UI/Core/`
|
||||
- `tests` 中对应 XCUI core 测试文件
|
||||
|
||||
前置依赖:
|
||||
|
||||
- 依赖主线完成 `Phase 0` 的基础类型和 UI 生命周期边界清理。
|
||||
|
||||
现在就可以先做的内容:
|
||||
|
||||
- 设计 `UIElementId` / `UIElement` / `UIContext` / `UIBuildContext`
|
||||
- 设计 dirty 标记与增量重建规则
|
||||
- 设计 ViewModel 读写边界和 command 回调入口
|
||||
- 写最小 tree rebuild 测试
|
||||
|
||||
明确不做:
|
||||
|
||||
- 不接入 `.xcui` 文件
|
||||
- 不接入 editor 面板
|
||||
- 不写具体 widget 大库
|
||||
|
||||
交付物:
|
||||
|
||||
- XCUI core 基础类与生命周期定义
|
||||
- tree rebuild / invalidation / state propagation 单元测试
|
||||
- 一个最小 demo:代码构建 UI tree 并触发一次增量更新
|
||||
|
||||
验收标准:
|
||||
|
||||
- 可以构建一棵稳定的 UI tree
|
||||
- 局部状态变化时只标脏必要节点
|
||||
- 重建逻辑与布局/渲染解耦
|
||||
- 其他 subplan 可以基于该模块定义控件树和状态更新
|
||||
46
docs/used/Subplan-03_XCUI-Style-Theme-Token.md
Normal file
46
docs/used/Subplan-03_XCUI-Style-Theme-Token.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# Subplan 03:XCUI Style / Theme / Token
|
||||
|
||||
目标:
|
||||
|
||||
- 建立 XCUI 的样式模型、token 体系与主题覆盖规则。
|
||||
- 让控件视觉不再散落在代码硬编码常量里。
|
||||
|
||||
负责人边界:
|
||||
|
||||
- 负责 `Style` / `Theme` / `Token` 数据模型和解析规则。
|
||||
- 不负责 `.xcui` 导入器。
|
||||
- 不负责最终 renderer 具体绘制。
|
||||
|
||||
建议目录:
|
||||
|
||||
- `engine/include/XCEngine/UI/Style/`
|
||||
- `engine/src/UI/Style/`
|
||||
- `tests` 中 style/theme 测试
|
||||
|
||||
前置依赖:
|
||||
|
||||
- 依赖 `Subplan 01` 的节点属性注入点。
|
||||
|
||||
现在就可以先做的内容:
|
||||
|
||||
- 设计 style 层级:默认样式、类型样式、命名样式、局部覆盖
|
||||
- 设计 token:颜色、圆角、边距、字号、线宽
|
||||
- 设计主题切换与 token 查询接口
|
||||
- 写冲突优先级测试
|
||||
|
||||
明确不做:
|
||||
|
||||
- 不做具体面板视觉重构
|
||||
- 不做字体资源导入
|
||||
|
||||
交付物:
|
||||
|
||||
- 统一样式查询入口
|
||||
- `.xctheme` 对应的数据结构
|
||||
- 样式优先级与 token 解析测试
|
||||
|
||||
验收标准:
|
||||
|
||||
- 样式优先级可预测
|
||||
- 主题替换不需要改控件逻辑
|
||||
- 其他 subplan 能通过统一 API 获取视觉参数
|
||||
46
docs/used/Subplan-06_XCUI-Markup-Import-HotReload.md
Normal file
46
docs/used/Subplan-06_XCUI-Markup-Import-HotReload.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# Subplan 06:XCUI Markup / Import / Hot Reload
|
||||
|
||||
目标:
|
||||
|
||||
- 把 `.xcui` / `.xctheme` / `.xcschema` 拉进资源系统。
|
||||
- 建立导入、编译产物、热重载、诊断输出的第一版链路。
|
||||
|
||||
负责人边界:
|
||||
|
||||
- 负责资源类型、导入器、artifact、诊断日志。
|
||||
- 不负责 widget 运行时逻辑本身。
|
||||
|
||||
建议目录:
|
||||
|
||||
- `engine/include/XCEngine/Resources/UI/`
|
||||
- `engine/src/Resources/UI/`
|
||||
- `editor/src` 中与导入面板、诊断输出相关的接入口
|
||||
|
||||
前置依赖:
|
||||
|
||||
- 需要主计划中的资源类型命名拍板。
|
||||
- 与 `Subplan 03`、`Subplan 07` 协调格式字段。
|
||||
|
||||
现在就可以先做的内容:
|
||||
|
||||
- 定义三类资源描述结构
|
||||
- 设计导入错误诊断格式
|
||||
- 设计热重载触发和缓存失效策略
|
||||
- 先做一个最小 parser,可以把简单 `.xcui` 编成中间结构
|
||||
|
||||
明确不做:
|
||||
|
||||
- 不做完整 markup 语法大全
|
||||
- 不做 inspector 的最终渲染
|
||||
|
||||
交付物:
|
||||
|
||||
- UI 资源类型定义
|
||||
- 导入器与 artifact 结构
|
||||
- 热重载与错误输出最小闭环
|
||||
|
||||
验收标准:
|
||||
|
||||
- UI 资源可被 ResourceManager 识别
|
||||
- 导入失败时有可读诊断
|
||||
- 改动文件后可触发重新加载
|
||||
1601
docs/used/Unity式Library资产导入与缓存系统重构方案.md
Normal file
1601
docs/used/Unity式Library资产导入与缓存系统重构方案.md
Normal file
File diff suppressed because it is too large
Load Diff
1048
docs/used/Unity式SceneView_Gizmo系统完整审查与正式化重构方案_完成归档_2026-04-06.md
Normal file
1048
docs/used/Unity式SceneView_Gizmo系统完整审查与正式化重构方案_完成归档_2026-04-06.md
Normal file
File diff suppressed because it is too large
Load Diff
62
docs/used/Unity式Tick系统与PlayMode运行时方案-阶段进展.md
Normal file
62
docs/used/Unity式Tick系统与PlayMode运行时方案-阶段进展.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# Unity式 Tick 系统与 Play Mode 运行时方案阶段进展
|
||||
|
||||
日期:2026-04-02
|
||||
|
||||
## 已完成
|
||||
|
||||
### 阶段 A
|
||||
|
||||
- 已接入 `RuntimeLoop`,统一承载 `FixedUpdate / Update / LateUpdate`
|
||||
- 已接入 `PlaySessionController`
|
||||
- 已实现 `Play / Stop`
|
||||
- Play 时运行 runtime scene clone
|
||||
- Stop 时恢复 editor scene snapshot
|
||||
- `Run` 菜单与 `F5` 已可切换 `Play / Stop`
|
||||
|
||||
### 阶段 B 当前收口
|
||||
|
||||
- 明确区分“文档级编辑”和“运行态场景对象编辑”
|
||||
- `New/Open/Save Scene` 与 `New/Open/Save Project` 仍只允许在 `Edit` 下执行
|
||||
- `Play / Paused` 下允许对 runtime scene 进行对象级编辑与 `Undo / Redo`
|
||||
- runtime scene 的对象改动默认不再污染场景文档 dirty 状态
|
||||
|
||||
### 阶段 C 当前收口
|
||||
|
||||
- 已补全 `Pause / Resume / Step` 的完整请求与状态切换
|
||||
- `Run` 菜单现在区分 `Play/Stop`、`Pause/Resume`、`Step`
|
||||
- `Error Pause` 已接入正式 Pause 请求通道
|
||||
- `Paused` 下维持 runtime world,不回退到 editor scene
|
||||
- `Step` 现在只在 `Paused` 下有效,并保持 `Paused` 状态不变
|
||||
|
||||
### 阶段 D 当前收口
|
||||
|
||||
- 已在软件顶部增加独立运行栏
|
||||
- 运行栏已接入 `Play / Pause / Step` 三个图标按钮
|
||||
- 顶部按钮直接复用现有 PlayMode 请求通道,不额外分叉状态机
|
||||
- `Play` 按钮在运行中会保持高亮,再次点击即 `Stop`
|
||||
- `Pause` 在 `Play / Paused` 下可用,并沿用现有 `F6`
|
||||
- `Step` 仍只在 `Paused` 下可用
|
||||
- 顶部栏已改为参与 dockspace 布局,不再覆盖 Scene / Hierarchy / Inspector 面板标题区
|
||||
|
||||
## 本轮验证
|
||||
|
||||
- 已重新执行 `cmake -S . -B build`
|
||||
- 已通过 `cmake --build build --config Debug --target scene_tests`
|
||||
- 已通过 `cmake --build build --config Debug --target editor_tests -- /m:1 /v:minimal`
|
||||
- 已通过 `cmake --build build --config Debug --target XCEditor -- /m:1 /v:minimal`
|
||||
- 已通过聚焦测试:
|
||||
`ctest --test-dir build -C Debug --output-on-failure -j1 -R "RuntimeLoopTest|PlaySessionControllerTest|EditorActionRoutingTest.*PlayMode|EditorActionRoutingTest.*MainMenuRouterRequestsPlayPauseResumeAndStepEvents"`
|
||||
|
||||
## 当前语义
|
||||
|
||||
- `editor tick` 负责托管运行时会话
|
||||
- `engine tick` 负责推进 runtime world
|
||||
- Play 时 `Hierarchy / Inspector / SceneView / GameView` 面对的是同一份 runtime world
|
||||
- Play 中对对象的改动默认是临时运行态改动,Stop 后回滚
|
||||
- Play 中禁止的是文档切换与文档保存,不是禁止观察或编辑 runtime clone
|
||||
|
||||
## 下一阶段建议
|
||||
|
||||
- 明确 `Paused` 下的 `Undo / Redo / Gizmo / Inspector` 更细粒度交互边界
|
||||
- 将 GameView 输入正式接入 runtime input 通道
|
||||
- 继续补 `Simulate` 与更完整的 Time 语义
|
||||
1054
docs/used/Unity式Tick系统与PlayMode运行时方案.md
Normal file
1054
docs/used/Unity式Tick系统与PlayMode运行时方案.md
Normal file
File diff suppressed because it is too large
Load Diff
140
docs/used/XCUI_Input_Focus_Shortcut_Subplan_完成归档_2026-04-04.md
Normal file
140
docs/used/XCUI_Input_Focus_Shortcut_Subplan_完成归档_2026-04-04.md
Normal file
@@ -0,0 +1,140 @@
|
||||
# XCUI Input / Focus / Shortcut Subplan 完成归档
|
||||
|
||||
日期:`2026-04-04`
|
||||
|
||||
## 1. 归档结论
|
||||
|
||||
`Subplan-04` 在其原始定义边界内已经完成,可以归档。
|
||||
|
||||
这里的“完成”指的是:
|
||||
|
||||
- 已建立 XCUI 输入事件基础模型
|
||||
- 已建立焦点、激活路径、指针捕获路径三套状态管理
|
||||
- 已建立 capture / target / bubble 三阶段输入路由
|
||||
- 已建立 shortcut scope 与命令匹配机制
|
||||
- 已建立统一的 `UIInputDispatcher`
|
||||
- 已补齐最小单元测试并完成通过验证
|
||||
|
||||
这里的“完成”不包括:
|
||||
|
||||
- Win32 原生消息采集
|
||||
- ImGui / Editor 侧的输入桥接
|
||||
- 文本输入控件级别的 IME 细节
|
||||
|
||||
这些内容本来就不在 `Subplan-04` 的负责边界里,后续应由 `Subplan-05`、`Subplan-08`、`Subplan-09` 等继续接手。
|
||||
|
||||
## 2. 本次落地内容
|
||||
|
||||
### 2.1 输入事件模型
|
||||
|
||||
已扩展 `UIInputEvent`:
|
||||
|
||||
- `PointerEnter`
|
||||
- `PointerLeave`
|
||||
- `pointerId`
|
||||
- `timestampNanoseconds`
|
||||
- `repeat`
|
||||
- `synthetic`
|
||||
|
||||
相关文件:
|
||||
|
||||
- `engine/include/XCEngine/UI/Types.h`
|
||||
|
||||
### 2.2 焦点与路径模型
|
||||
|
||||
已补齐:
|
||||
|
||||
- `UIElementId`
|
||||
- `UIInputPath`
|
||||
- `UIFocusController`
|
||||
- `UIFocusChange`
|
||||
|
||||
相关文件:
|
||||
|
||||
- `engine/include/XCEngine/UI/Input/UIInputPath.h`
|
||||
- `engine/include/XCEngine/UI/Input/UIFocusController.h`
|
||||
- `engine/src/UI/Input/UIInputPath.cpp`
|
||||
- `engine/src/UI/Input/UIFocusController.cpp`
|
||||
|
||||
### 2.3 Shortcut 系统
|
||||
|
||||
已补齐:
|
||||
|
||||
- `UIShortcutScope`
|
||||
- `UIShortcutChord`
|
||||
- `UIShortcutBinding`
|
||||
- `UIShortcutRegistry`
|
||||
- shortcut scope 优先级匹配规则
|
||||
|
||||
相关文件:
|
||||
|
||||
- `engine/include/XCEngine/UI/Input/UIShortcutRegistry.h`
|
||||
- `engine/src/UI/Input/UIShortcutRegistry.cpp`
|
||||
|
||||
### 2.4 输入路由与统一分发器
|
||||
|
||||
已补齐:
|
||||
|
||||
- `UIInputRouter`
|
||||
- `UIInputRoutingPlan`
|
||||
- `UIInputRoutingStep`
|
||||
- `UIInputDispatcher`
|
||||
|
||||
相关文件:
|
||||
|
||||
- `engine/include/XCEngine/UI/Input/UIInputRouter.h`
|
||||
- `engine/include/XCEngine/UI/Input/UIInputDispatcher.h`
|
||||
- `engine/src/UI/Input/UIInputRouter.cpp`
|
||||
- `engine/src/UI/Input/UIInputDispatcher.cpp`
|
||||
|
||||
## 3. 测试与验证
|
||||
|
||||
新增测试:
|
||||
|
||||
- `tests/Input/test_xcui_input_dispatcher.cpp`
|
||||
|
||||
已完成验证:
|
||||
|
||||
- `cmake --build build --config Debug --target input_tests`
|
||||
- `ctest -C Debug -R "XCUI.*" --output-on-failure`
|
||||
|
||||
验证结果:
|
||||
|
||||
- `6 / 6` 通过
|
||||
|
||||
覆盖点包括:
|
||||
|
||||
- focus path 切换
|
||||
- capture path 优先级
|
||||
- keyboard routed path 顺序
|
||||
- shortcut scope 匹配优先级
|
||||
- pointer down / pointer up 对 active path 的影响
|
||||
- shortcut 命中后优先消费、跳过普通 routing
|
||||
|
||||
## 4. 对后续 subplan 的可复用输出
|
||||
|
||||
当前已经可以被后续直接依赖的稳定入口:
|
||||
|
||||
- `XCEngine::UI::UIInputPath`
|
||||
- `XCEngine::UI::UIFocusController`
|
||||
- `XCEngine::UI::UIShortcutRegistry`
|
||||
- `XCEngine::UI::UIInputRouter`
|
||||
- `XCEngine::UI::UIInputDispatcher`
|
||||
|
||||
后续建议对接方式:
|
||||
|
||||
- `Subplan-05`:负责把 ImGui/平台输入桥接进这套 dispatcher
|
||||
- `Subplan-08`:负责把 menu / dock / panel shell 的 shortcut scope 接进 registry
|
||||
- `Subplan-09`:负责把 viewport shell 的 pointer / focus / capture 接进 routing
|
||||
|
||||
## 5. 原 subplan 文件
|
||||
|
||||
原始 subplan 文件已从活跃 `xcui-subplans` 目录移出。
|
||||
|
||||
当前这份文件就是 `Subplan-04` 的最终归档版本。
|
||||
|
||||
其状态应视为:
|
||||
|
||||
- 已完成
|
||||
- 已归档
|
||||
- 不再作为活跃开发计划继续扩写
|
||||
93
docs/used/XCUI_Subplan-01_Core_Tree_State_完成归档_2026-04-04.md
Normal file
93
docs/used/XCUI_Subplan-01_Core_Tree_State_完成归档_2026-04-04.md
Normal file
@@ -0,0 +1,93 @@
|
||||
# XCUI Subplan 01:Core Tree / State / Invalidation
|
||||
|
||||
归档日期:
|
||||
|
||||
- `2026-04-04`
|
||||
|
||||
状态:
|
||||
|
||||
- 已完成
|
||||
|
||||
本次实际完成内容:
|
||||
|
||||
- 新增 XCUI core 基础契约:`UIElementId`、`UIDirtyFlags`、`IUIViewModel`、`RevisionedViewModelBase`
|
||||
- 新增 retained-mode build 层:`UIBuildElementDesc`、`UIBuildList`、`UIBuildContext`
|
||||
- 新增 retained-mode tree 层:`UIElementTree`、`UIElementNode`、`UIElementTreeRebuildResult`
|
||||
- 新增统一入口:`UIContext`
|
||||
- 实现最小闭环:tree rebuild、dirty flag 标记、layout dirty 向祖先传播、dirty root 收集
|
||||
- 新增并验证 UI core 测试:tree 创建、unchanged rebuild、local state invalidation、view model invalidation、structure change、未闭合 build scope 失败
|
||||
|
||||
本次涉及文件:
|
||||
|
||||
- `engine/include/XCEngine/UI/Types.h`
|
||||
- `engine/include/XCEngine/UI/Core/UIInvalidation.h`
|
||||
- `engine/include/XCEngine/UI/Core/UIViewModel.h`
|
||||
- `engine/include/XCEngine/UI/Core/UIBuildContext.h`
|
||||
- `engine/include/XCEngine/UI/Core/UIElementTree.h`
|
||||
- `engine/include/XCEngine/UI/Core/UIContext.h`
|
||||
- `engine/src/UI/Core/UIBuildContext.cpp`
|
||||
- `engine/src/UI/Core/UIElementTree.cpp`
|
||||
- `tests/core/UI/CMakeLists.txt`
|
||||
- `tests/core/UI/test_ui_core.cpp`
|
||||
|
||||
验证结果:
|
||||
|
||||
- `cmake --build . --config Debug --target core_ui_tests`
|
||||
- `ctest -C Debug --output-on-failure -R UICoreTest --test-dir .`
|
||||
- 结果:`6/6` 通过
|
||||
|
||||
当前结论:
|
||||
|
||||
- `Subplan 01` 的最小 retained-mode core 已经可用
|
||||
- 后续 `Subplan 03/05/06/07/08/09` 可以基于这套 core 继续推进
|
||||
|
||||
原始 subplan 内容归档如下:
|
||||
|
||||
# Subplan 01:XCUI Core Tree / State / Invalidation
|
||||
|
||||
目标:
|
||||
|
||||
- 搭出 XCUI 的 retained-mode 核心骨架。
|
||||
- 明确 `ElementTree`、`NodeId`、`View`、`ViewModel`、`dirty flag`、`rebuild`、`lifecycle` 的最小闭环。
|
||||
|
||||
负责人边界:
|
||||
|
||||
- 负责 `engine/include/XCEngine/UI/` 与 `engine/src/UI/Core/` 的核心树模型。
|
||||
- 不负责具体布局算法。
|
||||
- 不负责 ImGui 适配绘制。
|
||||
|
||||
建议目录:
|
||||
|
||||
- `engine/include/XCEngine/UI/Core/`
|
||||
- `engine/src/UI/Core/`
|
||||
- `tests` 中对应 XCUI core 测试文件
|
||||
|
||||
前置依赖:
|
||||
|
||||
- 依赖主线完成 `Phase 0` 的基础类型和 UI 生命周期边界清理。
|
||||
|
||||
现在就可以先做的内容:
|
||||
|
||||
- 设计 `UIElementId` / `UIElement` / `UIContext` / `UIBuildContext`
|
||||
- 设计 dirty 标记与增量重建规则
|
||||
- 设计 ViewModel 读写边界和 command 回调入口
|
||||
- 写最小 tree rebuild 测试
|
||||
|
||||
明确不做:
|
||||
|
||||
- 不接入 `.xcui` 文件
|
||||
- 不接入 editor 面板
|
||||
- 不写具体 widget 大库
|
||||
|
||||
交付物:
|
||||
|
||||
- XCUI core 基础类与生命周期定义
|
||||
- tree rebuild / invalidation / state propagation 单元测试
|
||||
- 一个最小 demo:代码构建 UI tree 并触发一次增量更新
|
||||
|
||||
验收标准:
|
||||
|
||||
- 可以构建一棵稳定的 UI tree
|
||||
- 局部状态变化时只标脏必要节点
|
||||
- 重建逻辑与布局/渲染解耦
|
||||
- 其他 subplan 可以基于该模块定义控件树和状态更新
|
||||
50
docs/used/XCUI_Subplan-02_LayoutEngine_完成归档_2026-04-04.md
Normal file
50
docs/used/XCUI_Subplan-02_LayoutEngine_完成归档_2026-04-04.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# XCUI Subplan 02:Layout Engine 完成归档
|
||||
|
||||
归档日期:
|
||||
|
||||
- `2026-04-04`
|
||||
|
||||
原始来源:
|
||||
|
||||
- [../XCUI完整架构设计与执行计划.md](../XCUI完整架构设计与执行计划.md)
|
||||
|
||||
本次完成范围:
|
||||
|
||||
- 落地 XCUI 纯算法布局基础类型:
|
||||
- `UILayoutLength`
|
||||
- `UILayoutConstraints`
|
||||
- `UILayoutThickness`
|
||||
- `UILayoutItem`
|
||||
- `UIStackLayoutOptions`
|
||||
- `UIOverlayLayoutOptions`
|
||||
- 落地 measure / arrange 双阶段布局算法
|
||||
- 实现 `Horizontal Stack` / `Vertical Stack` / `Overlay` 三类 MVP 容器
|
||||
- 支持 `px / content / stretch`
|
||||
- 支持 `padding / spacing / margin / min / max / alignment`
|
||||
- 建立独立 `ui_tests` 测试目标并通过验证
|
||||
|
||||
实际代码落点:
|
||||
|
||||
- [engine/include/XCEngine/UI/Types.h](D:/Xuanchi/Main/XCEngine/engine/include/XCEngine/UI/Types.h)
|
||||
- [engine/include/XCEngine/UI/Layout/LayoutTypes.h](D:/Xuanchi/Main/XCEngine/engine/include/XCEngine/UI/Layout/LayoutTypes.h)
|
||||
- [engine/include/XCEngine/UI/Layout/LayoutEngine.h](D:/Xuanchi/Main/XCEngine/engine/include/XCEngine/UI/Layout/LayoutEngine.h)
|
||||
- [tests/Core/Math/CMakeLists.txt](D:/Xuanchi/Main/XCEngine/tests/Core/Math/CMakeLists.txt)
|
||||
- [tests/Core/Math/test_ui_layout.cpp](D:/Xuanchi/Main/XCEngine/tests/Core/Math/test_ui_layout.cpp)
|
||||
|
||||
验证结果:
|
||||
|
||||
- `cmake --build . --config Debug --target math_tests -- /m:1`
|
||||
- `ctest -C Debug --test-dir D:\\Xuanchi\\Main\\XCEngine\\build\\tests\\Core\\Math --output-on-failure -R UI_Layout`
|
||||
- 结果:`5/5 UI_Layout tests passed`
|
||||
|
||||
与原子计划相比,当前仍未覆盖:
|
||||
|
||||
- `Scroll` 容器
|
||||
- 更复杂的主轴分布策略
|
||||
- 与 XCUI tree/state 的正式对接
|
||||
- 文本测量与真实控件树集成
|
||||
|
||||
建议后续承接:
|
||||
|
||||
- 由 `Subplan-01` 提供 tree / node / invalidation 契约后,把当前布局算法接入正式 UI tree
|
||||
- 后续再补 `Scroll`、更完整容器族、文本测量桥接
|
||||
@@ -0,0 +1,83 @@
|
||||
# XCUI Subplan 05: ImGui Transition Backend
|
||||
|
||||
归档日期:
|
||||
- `2026-04-04`
|
||||
|
||||
状态:
|
||||
|
||||
- 已完成
|
||||
|
||||
本次实际完成内容:
|
||||
- 新增 XCUI 绘制数据契约:`UIColor`、`UIDrawCommandType`、`UIDrawCommand`、`UIDrawList`、`UIDrawData`
|
||||
- 新增 `ImGuiTransitionBackend` 过渡后端,支持 `FilledRect`、`RectOutline`、`Text`、`Image`、`PushClipRect`、`PopClipRect`
|
||||
- 新增最小 editor 接入样例 `XCUIDemoPanel`,用于在现有编辑器壳层中演示 XCUI draw data 到 ImGui draw call 的过渡链路
|
||||
- 将 demo panel 接入 editor workspace,并补齐 editor/tests 构建入口
|
||||
- 新增 Subplan-05 配套测试,覆盖 draw data 聚合与 backend flush 行为
|
||||
|
||||
本次涉及文件:
|
||||
- `editor/CMakeLists.txt`
|
||||
- `editor/src/Core/EditorWorkspace.h`
|
||||
- `editor/src/XCUIBackend/ImGuiTransitionBackend.h`
|
||||
- `editor/src/panels/XCUIDemoPanel.cpp`
|
||||
- `editor/src/panels/XCUIDemoPanel.h`
|
||||
- `engine/include/XCEngine/UI/DrawData.h`
|
||||
- `tests/editor/CMakeLists.txt`
|
||||
- `tests/editor/test_xcui_draw_data.cpp`
|
||||
- `tests/editor/test_xcui_imgui_transition_backend.cpp`
|
||||
|
||||
验证结果:
|
||||
- `cmake --build . --config Debug --target editor_tests -- /m:1 /p:CL_MPCount=1`
|
||||
- `ctest -C Debug -R "XCUIDrawDataTest|XCUIImGuiTransitionBackendTest" --output-on-failure`
|
||||
- 结果:`4/4` 通过
|
||||
- `cmake --build . --config Debug --target XCEditor -- /m:1 /p:UseMultiToolTask=false /p:CL_MPCount=1`
|
||||
- 结果:通过
|
||||
|
||||
提交记录:
|
||||
- `75ded6f` `Add XCUI ImGui transition backend MVP`
|
||||
|
||||
当前结论:
|
||||
- `Subplan-05` 的最小过渡后端已经可用,可以作为 XCUI 在 editor 中落地的第一层渲染适配桥
|
||||
- XCUI 逻辑层仍然不直接依赖 ImGui API,ImGui 仅存在于过渡 backend 和 editor 接入层
|
||||
- 后续 `Subplan-08`、`Subplan-09` 可以直接基于这套 draw data 和 transition backend 继续推进
|
||||
|
||||
原始 subplan 内容归档如下:
|
||||
|
||||
# Subplan 05:XCUI ImGui Transition Backend
|
||||
|
||||
目标:
|
||||
- 在过渡阶段,让 ImGui 只承担宿主窗口和 draw submission 容器的职责
|
||||
- 由 XCUI 自己生成 draw list,再交给 ImGui backend 落屏
|
||||
|
||||
负责人边界:
|
||||
- 负责 `editor/src/XCUIBackend/` 或等价新目录
|
||||
- 负责 XCUI draw primitive 到 ImGui draw call 的映射
|
||||
- 不负责 XCUI tree、布局、样式的内部规则
|
||||
|
||||
建议目录:
|
||||
- `editor/src/XCUIBackend/`
|
||||
- `editor/src/UI/` 中与 XCUI backend 直接相关的桥接代码
|
||||
- `tests/Editor` 中 backend 相关测试
|
||||
|
||||
前置依赖:
|
||||
- 需要 `Subplan-01` 给出稳定 draw data 和 frame submission 契约
|
||||
- 需要 `Subplan-03` 提供样式查询结果
|
||||
|
||||
现在就可以先做的内容:
|
||||
- 定义 `UIDrawList` / `UIDrawCommand` / `UIDrawText` / `UIDrawImage` / `UIDrawClip`
|
||||
- 先做矩形、边框、文字、图片四类 primitive
|
||||
- 设计 frame begin / submit / end 的 adapter 流程
|
||||
- 写一个最小 demo panel,用 XCUI draw list 通过 ImGui 显示
|
||||
|
||||
明确不做:
|
||||
- 不做 RHI native backend
|
||||
- 不做 docking 逻辑
|
||||
|
||||
交付物:
|
||||
- XCUI 到 ImGui 的过渡 backend
|
||||
- primitive 转换测试或快照测试
|
||||
- 最小 editor 接入样例
|
||||
|
||||
验收标准:
|
||||
- XCUI 逻辑层不直接依赖 ImGui API
|
||||
- ImGui 只出现在 backend 适配层
|
||||
- 可以渲染基础控件和文本
|
||||
Reference in New Issue
Block a user