Unity Shader 系列(三十四):Compute Shader 物理模拟——布料与粒子群
为什么用 Compute Shader 做物理?
Unity 自带的 PhysX 是 CPU 物理引擎,适合刚体碰撞检测,但处理万级以上粒子或布料节点时性能急剧下降。Compute Shader 让物理计算搬到 GPU 上并行执行:
- 1024 个线程组 × 64 线程/组 = 65536 个粒子同时并行更新
- 数据常驻 GPU,无需 CPU→GPU 数据传输(除非需要读回)
- 与渲染 Shader 共享
GraphicsBuffer,无需格式转换
本篇实现两个完整示例:GPU 布料模拟(弹簧质点系统)和 N-body 粒子群(引力模拟),均包含 Compute Shader + 渲染 Shader + C# 控制脚本。
Compute Shader 工作流基础
创建 Compute Shader
Project 窗口右键 → Create → Shader → Compute Shader,得到 .compute 文件。
1 | |
C# 调用流程
1 | |
ComputeBuffer vs GraphicsBuffer
| 类型 | 用途 | 推荐场景 |
|---|---|---|
ComputeBuffer |
Compute Shader 数据 | 旧版 API,Unity 2020 以前 |
GraphicsBuffer |
同时用于 Compute + 渲染 | Unity 2021+,推荐 |
RWTexture2D |
图像输出(写纹理) | 流体模拟、高度图生成 |
Unity 2021+ 推荐统一使用 GraphicsBuffer,它既可以作为 Compute Shader 的 RWStructuredBuffer,也可以直接作为渲染 Shader 的顶点/索引缓冲(Graphics.DrawMeshInstancedIndirect)。
实战示例一:GPU 布料模拟
数据结构设计
布料是一个 M×N 的质点网格,相邻质点之间用弹簧连接:
- 结构弹簧(Structural):连接上下左右邻居,防止拉伸
- 剪切弹簧(Shear):连接对角线邻居,防止剪切形变
- 弯曲弹簧(Bend):连接间隔 2 的邻居,防止折叠
1 | |
Compute Shader:弹簧质点布料
1 | |
C# 控制脚本
1 | |
布料渲染 Shader
1 | |
实战示例二:N-body 引力粒子群
适合制作星系、粒子群、魔法能量汇聚等效果。
1 | |
Burst ECS vs GPU Compute 的边界
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| < 1000 粒子,需要精确碰撞 | Burst + ECS | CPU 逻辑控制更灵活 |
| 1000~100000 粒子,视觉效果为主 | Compute Shader | GPU 并行效率高 |
| > 100000 粒子 | Compute + Indirect Rendering | 完全 GPU 化 |
| 布料(需要与角色骨骼互动) | 混合:CPU 骨骼 + GPU 布料 | 数据同步在关键帧 |
| 流体模拟 | Compute + RWTexture2D | 纹理读写更适合流场 |
Graphics.DrawMeshInstancedIndirect 渲染大量粒子
对于超大量粒子(>100k),使用 Indirect Rendering 完全避免 CPU 逐粒子 DrawCall:
1 | |
性能考量
- 线程组大小:布料用
[numthreads(8,8,1)](适合 2D 网格),粒子用[numthreads(64,1,1)](适合 1D 数组)。线程数应是 32 或 64 的倍数以对齐 Warp/Wavefront - Bank Conflict:避免多个线程同时访问同一内存 Bank。使用
SV_GroupIndex而非全局 ID 做共享内存寻址时要注意偏移 - 子步骤:布料等刚性弹簧系统每帧需要 4-8 个子步骤以保证稳定,时间步长
dt = Time.deltaTime / substeps - Mobile 限制:
ComputeShader需要 OpenGL ES 3.1+ 或 Vulkan/Metal,iOS 需要 Metal(A7 芯片以上支持)。发布移动端前务必通过SystemInfo.supportsComputeShaders检查
Compute Shader 是 Unity 游戏特效中最强大也最复杂的工具,掌握它之后,你可以在 GPU 上运行完整的物理世界,而 CPU 只需在每帧发出一个 Dispatch 命令。
Unity Shader 系列(三十四):Compute Shader 物理模拟——布料与粒子群
https://alex-rachel.github.io/2026/04/01/34-simulation-physics/