本节摘要:约束是动力学的关系数据库:每条约束记录两个物体的连接方式( glue 粘合、soft 软连、pin 钉住)与失效条件(受力阈值、时间、动画)。程序化破坏的全部控制感来自对约束网络的操作——在哪个属性上断、按什么顺序断。本节完成主线塌方实验。
取第 4 章高度场转出的网格,圈出一段陡坡(用 slope 掩码选面),流程五步:
// 约束强度按埋深衰减:深处牢固、表层酥脆 int p1 = prim(0, 'pt1', @primnum); vector pos1 = point(1, 'P', p1); // 输入1=碎片点云 float depth = length2(pos1 - chv('slide_origin')); f@strength = fit(depth, 0, 30, 1e6, 1e3); // 近坡脚处几乎一碰就断
整个过程没有任何关键帧。你设定的是"山有多脆"的空间分布,物理负责演。

上图标红的要点展开一句:约束网络在 Houdini 里就是一份普通几何(线段+属性)。这意味着你可以用 VEX 改 strength、用噪声挑出"先断的缝"、用距离场控制断裂传播方向。破坏的编排不是调物理参数,是编辑这份关系数据——这是程序化动力学区别于"按播放看运气"的分水岭。
⚠️ 常见坑:拿 fracture 自动生成的默认约束直接解算——强度全场常数,碎裂形态完全由随机种子决定,等于放弃导演权。先写 strength 场,再看模拟。
💡 关键直觉:约束回答"什么连着什么",失效规则回答"何时不再连"。破坏艺术的全部戏剧性都住在第二个问题里。
如果物理引擎里没有你想要的规律呢?下一节自己写一个:Solver。
约束是 DOP 的韧带,解剖一次它的数据结构就不再神秘。RBD 解算中约束是独立的几何网络(Constraint Network 节点),每条折线两个端点用 @soppath/@ptnum 绑定刚体,primitive 上携带类型与参数:
[约束折线的属性字典] @constraint_name — 匹配 Relationship 引用名(如 Glue) @constraint_type — glue/soft/hard 三类语义 f@strength — 断裂阈值(超过即解除) f@restlength — soft/hard 的目标距离 s@group_a/@group_b — 也可按组绑定而非逐点 调试: DOP 网络里 Constraint Visualization 打开, 逐帧看哪些约束活着(绿)/断了(红) —— 约束即图的边
手工修改约束是在解算中途接管物理的标准手段:按 @strength 的分位数批量弱化某区域,再敲一下就按剧本塌——可控破坏的艺术本质是"给物理写剧本"。
// Solver (Run Over: Points): 距离约束的逐帧松弛(布料雏形) int nbs[] = nearpoints(0, @P, ch("link_dist")); foreach (int nb; nbs) { vector d = point(0, "P", nb) - v@P; v@P += normalize(d) * (length(d) - f@rest) * 0.5 * ch("stiff"); } v@P.y -= 9.8 * @TimeInc * ch("gravity_scale"); // 重力积分 // 阻尼收敛: 每帧多次内迭代(iterations>10)可显著稳定
五十行以内的求解器足以理解所有商业布料的内核:预测(重力)+修正(约束投影)循环;参数 stiff/iterations 就是布料的"硬度"旋钮。
再补一条约束排错的经验法则:约九成的"约束不生效"问题出在绑定属性而非约束参数本身——@name 不匹配(刚体与约束折线两端的名字对不上)、@soppath 指向了错误几何、或约束几何没有正确进入 Relationship 的第二输入。排错顺序永远是先验证绑定(用 Visualization 染色确认每条约束找到了两具刚体),再调 strength 与 restlength。跳过绑定验证直接调参数的排错,就像不看接线就拧旋钮——动力学问题的诊断,同样遵循全书"先取证再动手"的纪律。
最后提一条约束与第六章的伏笔连接:批量化解算(一百次塌落扫描以挑选最佳镜头)时,约束网络的种子与断裂阈值应纳入 Wedge 参数矩阵——约束不只是物理构件,也是可扫描的艺术变量。把 @strength 的分布参数化(分位点、方差)后,同一套资产能产出一整族"从局部酥裂到整体崩塌"的连续谱系,供导演挑选;这正是"给物理写剧本"在规模化语境下的自然延伸。