vampire-like/docs/CodeX-TODO.md

145 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# CodeX TODO
## GPU Instancing 改造路线
### 目标定义
- `SimulationWorld` 继续作为敌人 `position / rotation / state` 的唯一真相源。
- 新增 `InstanceRendererComponent` 作为 Presentation 侧批量渲染组件,不把批次构建和 GPU Buffer 管理塞回 `SimulationWorld`
- 先做 `Graphics.DrawMeshInstanced` 低风险版,确认链路跑通后,再决定是否升级到 `DrawMeshInstancedIndirect`
- P3 首阶段只处理“敌人批量渲染”,不同时扩大到投射物、掉落物和所有特效。
### 架构边界
- `SimulationWorld`
- 只负责逻辑 Tick、生命周期同步、状态容器与碰撞结算。
- 不负责 `Mesh / Material / MaterialPropertyBlock / ComputeBuffer`
- `InstanceRendererComponent`
- 只负责收集可渲染实例、按 `Mesh + Material + Shadow + Layer + RenderState` 分组、构建 batch、发起 draw call。
- 只消费 `SimulationWorld` 输出,不反写 sim 状态。
- `TransformSync`
- P3 第一阶段继续保留,用于 HPBar、受击特效、挂点和现有表现依赖。
- 不要求一开始就把所有敌人 `Transform` 写回移除,否则风险过高。
- 敌人 GameObject
- 第一阶段继续保留,用于碰撞、生命周期、事件桥和表现挂点。
- 仅逐步移除“每敌人独立 MeshRenderer”这条渲染路径。
### 组件规划
1. 新增批量渲染组件骨架
- 建议文件:
- `Assets/GameMain/Scripts/CustomComponent/InstanceRendering/InstanceRendererComponent.cs`
- `Assets/GameMain/Scripts/CustomComponent/InstanceRendering/EnemyInstanceRegistry.cs`
- `Assets/GameMain/Scripts/CustomComponent/InstanceRendering/EnemyInstanceBatch.cs`
- 建议职责:
- `InstanceRendererComponent`:帧级调度、统一提交 draw call。
- `EnemyInstanceRegistry`:维护 `EntityId -> RenderBinding`,缓存 mesh/material/archetype。
- `EnemyInstanceBatch`:缓存每组矩阵、颜色、闪白参数和批次拆分结果。
2. 接入 `GameEntry`
- 文件:`Assets/GameMain/Scripts/Base/GameEntry.Custom.cs`
- 处理:
- 增加 `GameEntry.InstanceRenderer`
-`SimulationWorld` 一样在启动时自动获取或挂载组件
### 第一阶段:低风险版 `DrawMeshInstanced`
1. 建立渲染注册表
- 注册时机:敌人 show 时缓存渲染资源引用hide 时释放注册。
- 注册内容:
- `EntityId`
- `Mesh`
- `Material`
- 阴影/Layer/子类型信息
- 受击闪白、稀有度色等实例化属性默认值
- 约束:
- 注册表只缓存渲染资源和 archetype不缓存位置真相数据。
2.`SimulationWorld` 读取实例数据
- 读取来源:`_enemies` 或对外只读查询接口。
- 每帧收集:
- `Matrix4x4`
- 朝向/缩放
- `flashAmount`
- `baseColor`
- 其他实例化参数
- 约束:
- 由 sim 输出生成当前帧渲染数据,不从敌人 `Transform` 反推逻辑状态。
3. 按批次分组并提交
- 分组键至少包含:
- `Mesh`
- `Material`
- `ShadowCastingMode`
- `ReceiveShadows`
- `Layer`
- 需要的渲染状态位
- 提交方式:
- 每批最多 `1023` 实例
- 使用 `Graphics.DrawMeshInstanced`
- 通过 `MaterialPropertyBlock` 下发实例颜色和闪白参数
4. 接入现有 Instanced Shader
- 文件:`Assets/GameMain/Materials/Shaders/SimpleInstancedFlash.shader`
- 处理:
- 复用现有 `_BaseColor / _FlashColor / _FlashAmount` 实例化属性
- 确认敌人材质启用 instancing
- 不在第一阶段同时改复杂动画或多 Pass 材质
5. 替换敌人独立 Renderer 路径
- 第一阶段做法:
- 保留敌人实体和挂点
- 禁用敌人身上的 `MeshRenderer/SkinnedMeshRenderer`
- 改由 `InstanceRendererComponent` 统一绘制
- 约束:
- 碰撞、伤害、掉落、状态切换仍完全走现有逻辑链路
### 第二阶段:高上限版 `DrawMeshInstancedIndirect`
1. 升级批次数据结构
-`Matrix4x4[]` 和实例属性数组迁移到 `ComputeBuffer` / `GraphicsBuffer`
- 建立按 archetype 持久复用的 buffer避免每帧重建
2. 升级提交方式
- 使用 `Graphics.DrawMeshInstancedIndirect`
- 为实例数量、剔除结果和参数下发建立独立 buffer
3. 逐步加入可选优化
- 视锥剔除
- 距离分层
- LOD
- 大规模敌人下的批次复用和 buffer 容量管理
4. 进入该阶段的前提
- `DrawMeshInstanced` 版本已验证视觉正确
- `5k` 规模下 draw call 或主线程提交成本仍是瓶颈
- 否则不要过早把复杂度拉到 `Indirect`
### 风险控制
- 不要把 GPU batch 容器放进 `SimulationWorld` 主状态里。
- 不要让碰撞、索引或目标选择依赖 `InstanceRendererComponent`
- 不要一上来就移除 `TransformSync`,先保住现有 HPBar/特效/挂点行为。
- 不要在第一阶段同时处理敌人、投射物、掉落物三类 instancing。
### 验证口径
1. 功能回归
- 敌人朝向、受击闪白、死亡隐藏、精英/普通配色与当前一致
- `Battle -> LevelUp -> Shop -> Battle` 循环不丢渲染实例
2. Profiling 指标
- `0.5k / 1k / 1.5k / 2k / 5k` 敌人
- `Draw Calls`
- `SetPass Calls`
- `Main Thread`
- Render Thread / GPU 时间
3. 阶段验收
- 第一阶段验收:
- 先证明 `DrawMeshInstanced` 跑通且视觉一致
- Draw Calls 相比当前路径明显下降
- 第二阶段验收:
- `5k` 敌人规模下主线程提交和渲染耗时继续下降
- buffer 生命周期稳定,无泄漏、无错绘、无实例残留