Unity Virtual Mesh 解读
Unity Virtual Mesh 解读 它是什么 Unity Virtual Mesh 是 Unity Technologies 发布的实验性参考实现仓库,用来验证一种基于 triangle cluster / meshlet、memory page 流送和 GPU driven culling / LOD 的虚拟几何方案,而不是面向生产环境的成熟通用包。 关键依据: 仓库描述明确写明这是 “…
Unity Virtual Mesh 解读
它是什么
Unity Virtual Mesh 是 Unity Technologies 发布的实验性参考实现仓库,用来验证一种基于 triangle cluster / meshlet、memory page 流送和 GPU-driven culling / LOD 的虚拟几何方案,而不是面向生产环境的成熟通用包。
关键依据:
- 仓库描述明确写明这是 “a GPU-driven pipeline that supports triangle cluster LODs and two-pass occlusion culling at a triangle level” https://github.com/Unity-Technologies/com.unity.virtualmesh
- Runtime 的核心入口是
Runtime/VirtualMeshManager.cs,文档直接说明它负责 Unity game loop 中 virtual mesh system 的处理与 runtime buffer 持有。Documentation~/implementation.md:7 - 渲染功能入口是
Runtime/RenderFeatures/VirtualMeshRenderFeature.cs,文档说明它负责插入 rendering pipeline 的自定义 pass,并构成 GPU-driven pipeline。Documentation~/implementation.md:9-11
核心结论
1. 它不是“整物体 LOD 包”,而是 cluster / group / page 驱动的几何系统
术语文档直接定义:
- Cluster / meshlet:最大 64 triangles 的固定几何块。
Documentation~/glossary.md:13-15 - Cluster group:一组带父子层级关系的 clusters,共享包围盒,用于 occlusion culling。
Documentation~/glossary.md:17-19 - Memory page:若干 cluster groups 的磁盘序列化单元,按屏幕投影大小决定流送优先级。
Documentation~/glossary.md:21-23 - Upload buffer:页面数据从磁盘到 GPU 的中转缓冲,最终再写入 page slot。
Documentation~/glossary.md:29-31
2. 它的核心思想是“离线重构 + 运行时按需驻留”
编辑期不是直接使用原始 mesh,而是先:
- spatial sort triangles
Documentation~/implementation.md:69-73 - build meshlets
Documentation~/implementation.md:71-73 - partition meshlets 形成 leaf cluster groups
Documentation~/implementation.md:73-75 - 递归 simplify + re-cluster 生成 cluster hierarchy
Documentation~/implementation.md:75-77 - 将 group 装入 memory pages 并序列化为流送文件
Documentation~/implementation.md:77-81
源码对应实现:
- meshlet 最大三角数和 page 常量定义在
Editor/VirtualMeshBakerAPI.cs:46-49 - 实际 meshlet 构建在
Editor/VirtualMeshBakerAPI.cs:476-482 - 分区在
Editor/VirtualMeshBakerAPI.cs:484-499
3. 运行时调度主线是“GPU 请求页面,CPU 负责流送,GPU 完成驻留后再剔除与绘制”
实现文档说明:
- GPU 先做 culling / LOD 并决定需要哪些 pages。
Documentation~/implementation.md:29-33 - CPU 通过
RequestAsyncReadback读取反馈,派发 jobs 做文件 I/O 和 streaming。Documentation~/implementation.md:31-35 - 完成后通过 compute shader 把 upload buffer 拷贝到 runtime buffers。
Documentation~/implementation.md:33
源码直接证据:
- GPU 反馈回读入口:
Runtime/VirtualMeshManager.cs:495(FeedbackReadbackCallback) - Streaming loop 调度:
Runtime/VirtualMeshManager.cs:612-613 - header load job:
Runtime/VirtualMeshManager.cs:195-197 - page data load job:
Runtime/VirtualMeshManager.cs:231-233
4. 这是明确的 GPU-driven 渲染,而不是 CPU 逐对象提交
源码注释明确说明 render feature 负责 “GPU-driven culling and LOD processing”。Runtime/RenderFeatures/VirtualMeshRenderFeature.cs:8-10
进一步证据:
- first pass / second pass 的 two-pass occlusion culling 在 render feature 中有明确注释。
Runtime/RenderFeatures/VirtualMeshRenderFeature.cs:229,Runtime/RenderFeatures/VirtualMeshRenderFeature.cs:571 - 绘制采用
DrawProceduralIndirect。Runtime/RenderFeatures/VirtualMeshRenderFeature.cs:161,Runtime/RenderFeatures/VirtualMeshRenderFeature.cs:296,Runtime/RenderFeatures/VirtualMeshRenderFeature.cs:348,Runtime/RenderFeatures/VirtualMeshRenderFeature.cs:612 - CPU 侧说明 draw 基于 post-culling compacted index buffer。
Runtime/VirtualMeshManager.cs:618-620
5. “从对象驱动转向屏幕贡献驱动”在这个仓库里是有明确源码落点的
不是抽象理念,而是具体落在:
- page priority 由页面包围盒投影大小和距离决定。
Documentation~/implementation.md:40-50 - LOD layer 选择基于 simplification error,并转为 screen-space error。
Documentation~/implementation.md:83-87 - GPU shader 中存在 page / cluster / triangle 三层 pass:
PageOcclusionPassRuntime/Shaders/DXCVisibilityPasses.compute:58ClusterOcclusionPassRuntime/Shaders/DXCVisibilityPasses.compute:102TriangleOcclusionPassRuntime/Shaders/DXCVisibilityPasses.compute:203
关键数据结构
- Cluster triangle 上限:64。
Editor/VirtualMeshBakerAPI.cs:46,Runtime/VirtualMeshManager.cs:108 - Memory page 最大数量:256。
Editor/VirtualMeshBakerAPI.cs:49,Runtime/VirtualMeshManager.cs:109 - 单 page 最大 instance 数:1600。
Editor/VirtualMeshBakerAPI.cs:48,Runtime/VirtualMeshManager.cs:111 - PageData / VertexPosition / VertexAttribute / Index / GroupData / InstanceData / FeedbackBuffer 等 runtime buffer 都集中由
VirtualMeshManager持有。Runtime/VirtualMeshManager.cs:364-426
快速上手(源码阅读顺序)
- 看总实现说明:
Documentation~/implementation.mdDocumentation~/glossary.md
- 看编辑期几何烘焙:
Editor/VirtualMeshBakerAPI.csEditor/MeshOperations.cs
- 看运行时管理器:
Runtime/VirtualMeshManager.cs
- 看渲染管线整合:
Runtime/RenderFeatures/VirtualMeshRenderFeature.cs
- 看 GPU pass:
Runtime/Shaders/DXCVisibilityPasses.computeRuntime/Shaders/DepthPyramidPass.computeRuntime/Shaders/CopyPasses.compute
适用场景
从当前实现可推断它适合:
- 大量静态几何
- 需要细粒度 LOD 与按需流送的场景
- 希望把可见性决策更多下放给 GPU 的实验型渲染方案
依据:cluster/page 设计、GPU-driven pass、two-pass occlusion、AsyncGPUReadback 流送闭环。Documentation~/implementation.md:29-50, Runtime/RenderFeatures/VirtualMeshRenderFeature.cs:229-229, Runtime/RenderFeatures/VirtualMeshRenderFeature.cs:571-571
限制与定位
当前证据更支持把它定义为“实验性/参考实现”,而不是生产就绪方案:
- 仓库位于 Unity-Technologies 官方公开仓库,但文档集中讨论的是实现路径与技术原理,没有给出生产稳定性承诺;现有公开定位更接近 implementation reference。主要依据是文档文件名和内容都在解释系统如何实现,而不是提供成熟产品使用手册:
Documentation~/implementation.md,Documentation~/glossary.md - 多个关键常量是硬编码上限,例如 page 数 256、page instance 上限 1600、cluster triangle 上限 64。
Editor/VirtualMeshBakerAPI.cs:46-49,Runtime/VirtualMeshManager.cs:108-111 - LOD 投影误差依赖 baking 时相机 FOV,文档明确说 changing camera FOV requires a rebake。
Documentation~/implementation.md:85-87
待确认问题
- page feedback buffer 的完整位编码格式,本轮未完全展开;已确认 CPU 读回并驱动状态机,但若要写精确 bitfield 规范,仍需继续逐行追踪
FeedbackReadbackCallback与 shader 写入逻辑。 - 当前结论基于官方仓库源码与文档在线读取,未在本地 Unity 环境实际编译运行。
相关链接
- 仓库主页:https://github.com/Unity-Technologies/com.unity.virtualmesh
- 实现说明:https://raw.githubusercontent.com/Unity-Technologies/com.unity.virtualmesh/main/Documentation~/implementation.md
- 术语表:https://raw.githubusercontent.com/Unity-Technologies/com.unity.virtualmesh/main/Documentation~/glossary.md
一句话总结
Unity Virtual Mesh 的关键价值不只是“把模型切成 meshlet”,而是把几何数据重组织成 cluster group + memory page,并用 GPU-driven 的 page / cluster / triangle 多级剔除与按需流送,验证一种更接近“几何虚拟化”的渲染路线。