XPBD布料模拟Demo
这是一个扩展位置基动力学(XPBD)算法,基于CUDA加速的布料模拟的演示项目。支持拉伸、弯曲、固定与长距离约束,并提供粒子自碰撞与SDF碰撞处理。通过OpenGL实时渲染可视化调试。通过 GPU 并行友好的约束求解、稳定的时间步进策略、高效的空间哈希碰撞检测,以及针对原子操作和内存访问的多层优化,实现了高性能、稳定的实时布料模拟。
开发工具和库
Visual Studio 2022 + C++(20) + CUDA 12.4。推荐库使用vcpkg进行管理。
glfw3: 窗口管理库 glad: OpenGL的资源加载 fmt: 格式化输出 glm: 3D数学库 assimp: 模型加载 ImGui: 图形界面
主循环
采用常用的XPBD模拟的流程,先生成预测位置,处理碰撞,然后求解约束,最后更新位置。
CollideSDF(); // 与 SDF 碰撞(预稳定处理)
for (int substep = 0; substep < numSubsteps; substep++)
{
PredictPositions(); // 预测粒子位置
FindNeighborsBySpatialHash(); // 空间哈希查找邻居
// 处理碰撞
CollideParticles(); // 粒子间碰撞
CollideSDF(); // 与 SDF 碰撞
// 求解约束
for (int iteration = 0; iteration < numIterations; iteration++)
{
SolveStretch(); // 拉伸约束
SolveAttachment(); // 固定约束
SolveBending(); // 弯曲约束
Integration(); // 应用累积位置偏移
}
Finalize(); // 更新速度与位置
}
ComputeNormals(); // 计算法线用于渲染
约束种类和求解
- 拉伸约束(Stretch Constraint),约束相邻粒子之间的距离,用于模拟布料的经纬线结构。
- 弯曲约束(Bending Constraint),约束相邻三角形之间的夹角,控制布料的柔软程度和抗折叠能力。
- 固定约束(Attachment Constraint),将粒子绑定到世界空间中的点,用于悬挂、固定布料。
- 长距离固定约束(Long Range Attachment, LRA),从全局尺度限制粒子到锚点的最大距离,用于抑制 GPU Jacobi 迭代下的整体拉伸问题。
碰撞检测
-
布料自碰撞,把布料上的顶点当成球体。这些球体之间的碰撞,通过Space Hash方法进行检测,即对空间进行格子分类,仅对相邻格子内的球体进行碰撞检测。
-
布料和物体碰撞,通过SDF(Signed Distance Field)方法进行碰撞检测。SDF函数是一个标量场,空间中每个点对应SDF值,通过正负号,区分在物体内外。布料的顶点,仍使用球来描述,碰撞的物体,使用SDF来进行描述。布料的顶点,去查询碰撞物体的SDF值,得到距离和法线方向,如果布料穿透物体表面,沿法线把粒子推回表面。
项目优化
1.并行计算与 GPU 友好优化
核心目标: 让布料模拟适合 GPU 大规模并行执行。
-
Jacobi 迭代替代 Gauss-Seidel 所有约束并行求解,避免线程间依赖,提升 GPU 利用率。
-
位置增量累积(ApplyDeltas) 将多个约束产生的位移先累积,再统一应用,减少并行更新导致的抖动。
-
原子操作重排(Atomic Reorder) 对向量分量的 atomicAdd 顺序进行打散,降低线程写冲突,提高吞吐率。
2.时间步进与数值稳定性优化
核心目标: 在保持实时性能的同时避免数值爆炸和振动。
-
子步(Substep)时间积分 将一帧拆分为多个小步,提高高速运动下的稳定性。
-
SDF 预稳定碰撞处理 在约束迭代前先修正穿透,只改位置不改速度,抑制能量爆炸。
-
长距离附着(Long Range Attachment, LRA) 在 GPU 并行条件下减少布料整体拉伸,提高不可伸展性。
3.碰撞检测与过滤优化
核心目标: 降低碰撞复杂度,避免无效或错误的碰撞响应。
-
空间哈希(Spatial Hashing) 将粒子分桶,只检测邻近网格内的粒子,避免 碰撞。
-
邻居缓存(Neighbor Caching) 多个子步复用邻居结果,减少重复构建空间结构的开销。
-
初始距离过滤(Collision Filtering) 利用初始粒子距离忽略本来就相邻的粒子,防止自碰撞伪影。
4. 约束系统与物理模型优化
核心目标: 在有限迭代次数下保持物理合理性。
-
多类型约束并行求解 拉伸、弯曲、附着约束统一在 GPU 上迭代处理。
-
XPBD 形式的约束稳定性 引入顺应性(Compliance),使约束在大时间步下仍然稳定。
-
约束分层执行顺序 合理安排约束顺序,减少误差累积。
5.数据结构与内存访问优化
核心目标: 提高显存访问效率,减少带宽浪费。
-
结构化邻居数组布局 使用利于合并访问(Coalesced Access)的邻居存储方式。
-
减少随机内存访问 尽量使用连续缓冲区和顺序访问模式。
-
初始状态缓存(initialPositions) 通过缓存初始几何关系,避免复杂拓扑查询。
6.渲染与调试性能优化
核心目标: 在不影响模拟性能的情况下实现可视化。
-
屏幕空间粒子渲染 用屏幕空间 billboard 代替真实几何,显著降低渲染开销。
-
GPU Instancing(调试模式) 在粒子数较少时方便调试结构和行为。
-
延迟法线与深度计算 以近似方式获得视觉效果,换取性能。
参考文章
[1] Müller et al., Position Based Dynamics, 2007
[2] Macklin et al., Unified Particle Physics for Real-Time Applications, 2014
[3] Macklin et al., XPBD: Position-Based Simulation of Compliant Constrained Dynamics, 2016
[4] Müller et al., Long Range Attachments, 2012