本节摘要:布料是二维网格上的距离约束加弯曲约束,绳索是一维粒子链上的距离约束,松弛时 slack、绷紧时只拉不推。自碰撞和与刚体碰撞决定会不会穿身、穿墙。拉伸刚度要高、弯曲刚度要低,才像布而不是铁皮。先挂一面旗,再做能缠绕的绳。
阅读完本节,你应当能够:
结构边连接相邻顶点,管拉伸。剪切边连接对角,管切变,减少平行四边形滑。弯曲用隔一顶点的边或二面角约束,让布能折但抵抗对折成硬板。只加结构边,布会沿对角塌。三种边的 compliance 不同:拉伸很小(几乎不可伸),弯曲大(易折)。这是布和铁皮的差别,不是渲染。
固定旗杆:那些顶点 w=0,或每帧写死位置。风:在顶点上加力,力在预测阶段进入 Verlet。风太大加拉伸不够,旗会无限拉长——说明拉伸约束迭代或柔度不够,不是风模型高级。
对每条结构边: projectDistance(..., complianceStretch) 对每条剪切边: projectDistance(..., complianceShear) 对每条弯曲约束: projectBending(..., complianceBend) 对每个顶点: 与碰撞体投影
迭代 4–10 次常见。顶点多时弯曲约束数量仍线性。不要对布料上刚体 FEM。
| 问题外观 | 可能原因 | 先试 |
|---|---|---|
| 旗像铁皮 | 弯曲太硬或迭代把弯曲也投死 | 增大弯曲柔度 |
| 旗像口香糖拉丝 | 拉伸太软 | 减小拉伸柔度或加迭代 |
| 穿旗杆 | 碰撞半径小于网格间距 | 加大厚度或加密网格 |
| 抖动闪烁 | 自碰撞与拉伸互殴 | 降自碰撞刚度,加子步 |
| 整体飞走 | 锚点 w 不是 0 | 检查固定顶点 |
绳索:粒子间距 rest,只拉:若 len < rest 不投影(松弛),len > rest 当距离约束。链条用刚体加铰链更有质量感,但条数一多不如粒子绳。锚到动态刚体时,投影位移要还冲量给刚体,同 5.1,否则角色甩绳绳动人不动,或人被瞬移。
布料自碰撞:顶点对三角形,或边对边。网格间距小,邻接三角形要排除,否则结构边被当成碰撞拉开。宽相用网格。角色穿衣:布料对胶囊/凸包,单向或双向。裙子用单向(布料让角色,角色不让布料)更稳,物理不正确但游戏常用。
高速挥舞的布需要 CCD 或更细子步,否则一帧穿过手臂。子步对布料比对刚体更常见。
💡 关键直觉:布料的“材料”主要是三种 compliance 的比例,不是贴图。贴图再软,拉伸约束太硬仍是铁皮。
绳索绕柱:只靠距离约束会穿柱。要对每段做胶囊对场景碰撞,或用位置投影把段推出表面。缠绕模拟要段足够密。游戏钩索常常用射线检测缩短长度,而不是真缠绕物理——又是专用近似,5.4 同类思想。
物理网格可以比渲染粗。渲染用细分或蒙皮跟着物理顶点。不要让美术的两万三角全进 XPBD。撕裂:拉伸超过阈值删边并复制顶点,拓扑变了约束列表要重建。第一版可以不撕裂。
⚠️ 常见坑:弯曲约束用世界坐标存静止二面角,布料整体旋转后弯曲发力把旗拧成麻花。静止角应在局部或用无向边长约束近似弯曲。
空气阻尼和结构阻尼分开。旗在无风时应尽快停,但扔出的桌布应能飞一段。同 5.1,别用全局乘速度系数。
测试:旗杆上的旗无风时应垂下并静止;侧面来风应鼓起,松手风停应回垂。绳吊着箱子,箱子质量变大绳应更垂,不应无限伸(拉伸只拉有上限伸长由柔度决定)。绕过一个钉子的绳应被钉子挡住而不是穿过。
性能:布料约束高度可并行,注意颜色分组。移动平台上的旗,锚点每帧跟刚体变换走,不要积分锚点。
2D 绳先写:十个点吊一个球,只拉,球应摆起来。再加碰撞。3D 布料在 2D 绳稳了之后再上,否则分不清是投影写错还是网格拓扑错。
长绳稳定性:段数多,误差累积,末端会晃。增加迭代或用长程约束(隔 2、4 个点再加边)加速拉伸信息传播。这是 PBD 布料的经典技巧:结构边只传邻点,应变要很多轮才传到另一角,长程边当高速公路。
贴身衣服用布料对胶囊单向碰撞,角色不让布,布让角色。双向会把角色挤出胶囊控制器,KCC 与布料互殴。裙子、斗篷同理。只有独立桌布、旗帜才双向。把这当成产品规则写进注释。
钩索:射线打中点,生成距离约束或直接改角色速度把人拉过去。真缠绕绕柱要密段加碰撞,预算高。玩法是“钩到就拉”,用射线。物理绳留给吊桥、起重机。不要用吊桥的绳去做钩索,手感会黏。
风场采样:按顶点位置读向量场,力乘面积近似(用邻边叉积)。旗应鼓向顺风。风场若按渲染帧变,布料会抖,风也要固定步采样。
长程边:网格 20x20,除了邻点边,加隔 2、隔 4 的边,拉伸传播快,末端少橡皮。弯曲不要加长程,否则变铁皮。只拉伸长程。
沿对角滑成平行四边形。缺弯曲则过软对折无抵抗,或你把弯曲做太硬变成铁皮。比例靠柔度,不靠贴图。
结构边会被当成碰撞拉开,网格炸。拓扑邻居不是碰撞对。实现漏了会表现为布料自己把自己撕开。
玩法是钩到就拉,真缠绕贵。吊桥才用物理绳。用错手感会黏。
弯曲长程会变铁皮。只给拉伸当高速公路,让应变传到另一角。末端橡皮明显时再加隔 2、隔 4。
布料抖。风场也固定步采样。和物理同一时钟。
对角塌。剪切和弯曲要有。
变铁皮。长程只给拉伸。
自己撕自己。排除拓扑邻居。
手感黏。钩索射线。
旗抖。风也固定步。
先粗网格蒙皮。
整体一转拧麻花。
松弛消失或永远绷。只拉不推。
固定时间步是「03-织物与绳索」所有数值实验的尺子。尺子在抖,你无法比较积分器,无法调 beta,无法谈确定性。谁把渲染帧时间直接喂进物理,谁就在用弹性的尺子量钢梁。 本条对应「03-织物与绳索」第 1 号备忘,和相邻条目不要合并成一句空话,分开验收。
「03-织物与绳索」里出现 NaN 要在源头断言:未归一化法向、零长度边当轴、除以过小的有效质量、四元数没归一。把 NaN 传到求解器再查,整场速度都会脏,回溯成本高一个数量级。 本条对应「03-织物与绳索」第 2 号备忘,和相邻条目不要合并成一句空话,分开验收。
和美术、策划交接「03-织物与绳索」参数时,用测试盒而不是形容词。说清楚二十厘米台阶能上、八十厘米不能,比说手感更跟手有用。测试盒还能在引擎升级后当合同跑一遍。 本条对应「03-织物与绳索」第 3 号备忘,和相邻条目不要合并成一句空话,分开验收。
「03-织物与绳索」若跨模块耦合,先单向再双向。布料先撞静地,流体先撞静箱,关节先吊静锚。双向一步到位时,你分不清是 A 推 B 写错还是 B 还力写错。控制变量不是学术,是省生命。 本条对应「03-织物与绳索」第 4 号备忘,和相邻条目不要合并成一句空话,分开验收。
睡眠和唤醒属于「03-织物与绳索」正确性,不只是性能。该醒不醒会穿模,不该醒全醒会卡顿。爆炸查询、关节边、运动学平台都是唤醒图的边。漏一条边,现场像鬼。 本条对应「03-织物与绳索」第 5 号备忘,和相邻条目不要合并成一句空话,分开验收。
「03-织物与绳索」的默认值要进协议版本。改默认迭代次数、默认 dt、默认皮肤半径,旧回放会分叉。版本头拒绝错版本,比静默错乱重放更负责任。 本条对应「03-织物与绳索」第 6 号备忘,和相邻条目不要合并成一句空话,分开验收。
先写 2D 再写 3D 适用于「03-织物与绳索」里所有几何麻烦事。二维金字塔、二维绳、二维铰链能看见点的增减。三维裁剪 bug 极难看,会让你怀疑人生。二维过了再加一根轴。 本条对应「03-织物与绳索」第 7 号备忘,和相邻条目不要合并成一句空话,分开验收。
「03-织物与绳索」不要在热路径调用脚本。求解器迭代十次回调十次,缓存和确定性一起死。标记事件,步末再发。这是布局问题也是架构问题。 本条对应「03-织物与绳索」第 8 号备忘,和相邻条目不要合并成一句空话,分开验收。
对账数字比观感先行。静止支撑冲量是否接近质量乘重力乘 dt,自由落体一秒是否接近四点九米,两球对心是否交换速度。「03-织物与绳索」相关实现先过对账,再谈好看。 本条对应「03-织物与绳索」第 9 号备忘,和相邻条目不要合并成一句空话,分开验收。
「03-织物与绳索」出抖动时按清单:时间步是否固定、流形点是否闪、法向是否跳、恢复系数是否在静止时仍生效、bias 是否过大、迭代是否其实在清零热启动。不要先把摩擦系数调到十。 本条对应「03-织物与绳索」第 10 号备忘,和相邻条目不要合并成一句空话,分开验收。
空间结构必须在世界系。把「03-织物与绳索」绑到摄像机或屏幕格子,逻辑和确定性都会在转视角时崩。渲染剔除不能代替宽相,看不见的物体仍能被撞到。 本条对应「03-织物与绳索」第 11 号备忘,和相邻条目不要合并成一句空话,分开验收。
下一节进入游戏里最常用的两种“假物理”:轮子不一定是真圆柱,走路的人不是布娃娃。