Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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