# 3DGS-D3D12 最小可行系统计划 日期:2026-04-12 ## 1. 文档定位 这份计划用于指导 `D:\Xuanchi\Main\XCEngine\mvs\3DGS-D3D12` 的最小可行系统落地。 当前任务边界已经明确: 1. 只允许在 `mvs/3DGS-D3D12` 目录内开发与新增文件。 2. `engine` 代码只能引用,禁止修改。 3. 图形抽象层只能使用现有 `engine` 提供的 `RHI` 接口。 4. 本轮目标是先把 3DGS 的最小可行系统跑通,而不是把它正式并入引擎主线。 5. 本轮明确不引入 `chunk` 机制。 因此,这份计划不是“继续修补引擎内已有的 GaussianSplat 路径”,而是“在 MVS 目录内重新搭一条干净的、可验证的、无 chunk 的 3DGS-D3D12 最小链路”。 ## 2. 参考实现与职责拆分 本轮只参考两条现有实现,各自承担不同职责: ### 2.1 `mvs/3DGS Unity Renderer` 用途: 1. 参考 `.ply` 的读取方式。 2. 参考如何从 PLY 属性中提取 3DGS 所需原始数据。 3. 参考资源准备阶段的数据布局与字段含义。 注意: 1. 这里只借鉴导入与数据准备思路。 2. 不照搬 Unity Editor 资产工作流。 3. 不引入 chunk。 ### 2.2 `mvs/3DGS-Unity` 用途: 1. 参考“干净的无 chunk 渲染路径”。 2. 参考 `prepare -> sort -> draw -> composite` 的最小闭环。 3. 参考 3DGS 在屏幕空间椭圆展开、混合与合成时的核心着色器语义。 注意: 1. 这里重点参考渲染过程,而不是 Unity 的宿主框架。 2. 不把 Unity 的 `ScriptableRenderPass`、资产导入器、Inspector 等编辑器逻辑带入本轮实现。 ## 3. 首轮目标 首轮只完成以下闭环: 1. 在 `mvs/3DGS-D3D12` 内部加载 `room.ply`。 2. 将 PLY 中的高斯数据转换为无 chunk 的运行时缓冲。 3. 通过现有 `RHI` 完成 D3D12 路径下的最小渲染。 4. 输出一张稳定可观察的结果图,证明房间场景已经被正确绘制。 首轮验收标准: 1. 程序能独立编译与运行。 2. 不依赖修改 `engine` 才能成立。 3. 渲染结果不再是纯黑、纯白或明显错误的撕裂图。 4. 渲染链路中不存在任何 chunk 数据结构、chunk 缓冲或 chunk 可见性阶段。 ## 4. 非目标 本轮明确不做: 1. 不并入 editor。 2. 不接入引擎现有 Renderer 主线。 3. 不做 OpenGL / Vulkan 多后端对齐。 4. 不做正式资源缓存格式。 5. 不做 chunk、cluster、LOD、streaming 等优化层。 6. 不做 compute 之外的额外架构扩展。 7. 不为迎合当前 MVS 去修改 `engine` 的 `RHI`、Renderer、Resources。 ## 5. 约束与执行原则 ### 5.1 目录约束 本轮新增内容应尽量收敛在 `mvs/3DGS-D3D12` 内,例如: 1. `src/`:程序入口、渲染器、相机、数据上传。 2. `include/`:本地头文件。 3. `shaders/`:本地 HLSL 或中间 shader 资源。 4. `assets/`:本地测试资源或生成物描述。 5. `third_party/`:仅当 MVS 自己确实需要额外小型依赖时使用。 ### 5.2 RHI 使用原则 1. 只调用现有 `engine` 的 `RHI` 公共接口。 2. 如果发现最小系统缺失某项能力,优先在 MVS 内通过更简单的组织方式规避。 3. 若确实被 `RHI` 能力边界阻塞,先记录问题并汇报,不允许直接改 `engine`。 ### 5.3 数据路径原则 1. 整个系统只保留 positions、other、color、SH 等无 chunk 基础数据。 2. 不生成 chunk header。 3. 不上传 chunk buffer。 4. 不做 visible chunk 标记。 5. 不保留任何为了兼容旧 chunk 方案而加的临时分支。 ## 6. 技术路线 ### Phase 1:梳理 3DGS-D3D12 的骨架与构建入口 目标: 1. 确认 `mvs/3DGS-D3D12` 当前是否只有 `room.ply`。 2. 建立最小的可执行工程骨架。 3. 打通对 `engine` 中 `RHI` 的引用与链接。 任务: 1. 规划 `CMakeLists.txt` 与目录结构。 2. 建立窗口、设备、交换链、命令提交、离屏或在屏渲染的最小入口。 3. 跑通一个“清屏可显示”的基础版本。 验收: 1. `3DGS-D3D12` 可独立编译。 2. 程序能启动并输出基础画面。 ### Phase 2:实现无 chunk 的 PLY 读取与运行时数据打包 目标: 1. 参考 `mvs/3DGS Unity Renderer`,在 MVS 内部完成 PLY 读取。 2. 输出适合渲染阶段直接上传的高斯原始数组。 任务: 1. 解析 PLY header 与顶点属性。 2. 提取 position、rotation、scale、opacity、color/SH 等字段。 3. 明确字段的排列顺序、类型与归一化方式。 4. 生成 MVS 本地 `GaussianSplatSceneData`。 验收: 1. `room.ply` 可被成功读取。 2. 点数量、字段长度、边界盒等基础统计合理。 3. 整条导入链中完全没有 chunk 概念。 ### Phase 3:对齐无 chunk 的 GPU 数据布局与上传 目标: 1. 把导入结果上传到 GPU。 2. 数据布局尽量贴近 `mvs/3DGS-Unity` 的渲染输入。 任务: 1. 设计 positions / other / color / SH 的 GPU buffer。 2. 建立与着色器绑定一致的 SRV/UAV 视图。 3. 为排序与绘制准备 index、distance、view-data 等工作缓冲。 验收: 1. GPU 侧所有关键缓冲都能正确创建。 2. 每个绑定槽位与 shader 语义一一对应。 3. 不包含 chunk buffer / visible chunk buffer。 ### Phase 4:先打通 prepare 与 sort 目标: 1. 先验证“高斯数据被相机看到并被正确排序”。 2. 在 draw 之前把中间结果可视化或可检查化。 任务: 1. 参考 `mvs/3DGS-Unity` 的 prepare 语义,计算每个 splat 的 view-space 信息。 2. 生成排序距离。 3. 跑通最小排序路径。 4. 必要时增加调试输出,用于检查 order / distance / 计数是否异常。 验收: 1. prepare 结果不是全零或明显错误。 2. sort 输出索引顺序稳定。 ### Phase 5:对齐 draw 与 composite 目标: 1. 参考 `mvs/3DGS-Unity` 的“干净无 chunk 渲染路径”把核心画面先画出来。 任务: 1. 对齐 Gaussian splat draw shader 的主要输入输出语义。 2. 对齐椭圆展开、覆盖范围与透明混合约定。 3. 建立 accumulation target。 4. 建立 composite pass,把 accumulation 结果合回最终颜色。 验收: 1. 输出图中能看出 `room.ply` 对应的房间结构。 2. 不出现整屏纯黑、纯白、随机撕裂。 ### Phase 6:收口与验证 目标: 1. 固化最小系统结果,形成稳定基线。 任务: 1. 规范运行命令与资源路径。 2. 输出一张固定命名的结果图作为检查基线。 3. 清理调试残留与临时分支。 4. 补一份 MVS 内局部说明文档。 验收: 1. 代码、资源、着色器都收敛在 `mvs/3DGS-D3D12`。 2. 运行方式清晰。 3. 基线截图稳定。 ## 7. 关键风险 ### 7.1 PLY 属性语义与当前样例不一致 如果 `room.ply` 的字段命名、顺序或编码方式与参考加载器假设不一致,最先要修的是导入器映射,不是渲染器。 ### 7.2 RHI 能力与参考实现存在接口差 如果 Unity 参考依赖的某些资源绑定或 compute 流程不能直接一比一照搬,本轮优先在 `mvs/3DGS-D3D12` 内部重排执行方式,而不是去动 `engine`。 ### 7.3 排序与混合契约不一致 3DGS 最容易出错的不是“有没有画出来”,而是排序方向、alpha 累积与 composite 契约是否一致。本轮必须把这三者当成同一个问题处理,禁止分开打补丁。 ## 8. 本轮完成后的下一步 当 `mvs/3DGS-D3D12` 的无 chunk 最小系统跑通后,下一步才有意义讨论: 1. 是否把这条路径收编进引擎正式 Renderer。 2. 是否把 PLY 导入升级成正式资源导入器。 3. 是否在引擎层补 structured buffer / compute / renderer pass 抽象。 4. 是否接入 editor 与资产缓存。 在这之前,所有工作都应服务于一个目标: 先在 `mvs/3DGS-D3D12` 内证明“无 chunk 的 3DGS-D3D12 + 现有 RHI”这条路是通的。