3. 物理引擎调优:理解PhysX核心参数,平衡精度与性能

物理引擎是仿真世界的「重力法则」。你场景里每一个物体的下落、碰撞、堆叠,都靠它算。但算得越精细,CPU就越累。我见过不少团队,场景里就几百个箱子,仿真却卡得像幻灯片——问题往往出在PhysX参数上。

今天我们就来拆解几个核心参数。搞懂了它们,你就能在精度和性能之间找到那个「甜点」。

3.1 子步数(Substep Count)——时间切得越细,碰撞越准

先问个问题:为什么高速运动的物体会「穿模」?

因为物理引擎不是连续计算时间的。它把1秒切成若干帧,每帧只算一次。如果一个薄板在1帧内从球左边穿到了右边,引擎根本不知道它们曾经重叠过——这就是「隧道效应」。

子步数就是解决这个问题的。它把每一帧再切成更小的步长,在每个子步里都做一次碰撞检测。

子步数 每帧计算次数 碰撞精度 CPU开销
1(默认) 1次 低,易穿模 最低
2 2次 中等 约2倍
4 4次 高 约4倍
8 8次 极高 约8倍
我的经验:对于大多数工业仿真场景(机器人抓取、物体搬运),子步数设为2就够用了。只有当你仿真高速碰撞(比如乒乓球、子弹)时,才需要提到4或8。别一上来就设8,CPU会哭的。

3.2 碰撞检测模式——选对了,省一半算力

PhysX提供了几种碰撞检测模式。说白了,就是「用什么形状去算碰撞」。

  • Primitive(基本体):用球体、立方体、胶囊体代替复杂模型。最快,但精度最低。
  • Convex Hull(凸包):用物体外轮廓的凸包。精度中等,性能也不错。
  • Triangle Mesh(三角网格):直接用模型的三角面。最精确,但最慢。
  • Height Field(高度场):专门用于地形。效率高,适合地面。

我建议你遵循一个原则:能用基本体就别用凸包,能用凸包就别用三角网格。

避坑指南:我曾经接手一个项目,场景里所有物体都用了三角网格碰撞。结果仿真帧率只有5 FPS。后来我把静态物体(墙壁、地面)换成基本体,动态物体(箱子、零件)换成凸包,帧率直接飙到30 FPS。精度损失?肉眼几乎看不出来。

3.3 刚体睡眠阈值——让不动的物体「睡过去」

场景里总有些物体是静止的——比如地上的箱子、桌上的零件。如果引擎每帧都去算它们的碰撞,那就是白费力气。

刚体睡眠机制就是干这个的。当一个物体的速度和角速度低于某个阈值,且持续一段时间,PhysX就会把它标记为「睡眠」状态,不再参与物理计算。

两个关键参数:

  • Linear Sleep Threshold:线速度阈值,默认0.001 m/s
  • Angular Sleep Threshold:角速度阈值,默认0.001 rad/s

你可以适当调高这两个值。比如在物流仿真场景里,我习惯设到0.01。这样箱子一停下来就立刻「睡着」,CPU负担明显下降。

注意:阈值别设太高。否则物体还没完全静止就被强制睡眠,看起来会像「粘在地上」一样,很不自然。

3.4 求解器迭代次数——收敛速度的开关

当多个物体堆叠在一起时(比如一摞箱子),PhysX需要反复计算它们之间的接触力,直到所有力达到平衡。这个计算过程叫「求解」。

求解器迭代次数决定了每次求解时,引擎最多算多少轮。迭代越多,堆叠越稳定,但CPU开销也越大。

迭代次数 堆叠稳定性 性能影响
4(默认) 一般,小堆叠还行 低
8 良好,适合中等堆叠 中等
16 优秀,适合高堆叠 高
32 极高,几乎不抖动 极高

我个人习惯:如果场景里堆叠不超过5层,用4次就够了。超过10层,我会提到8次。再往上?说实话,16次和32次的差别,肉眼很难分辨,但CPU已经快冒烟了。

3.5 核心参数调优流程图

下面这张图总结了调优的核心逻辑。你可以把它贴在工位上。

PhysX 核心参数调优流程 开始调优 场景有高速碰撞吗? 是 子步数设为4 否 堆叠层数超过5层? 是 迭代次数设为8 否 需要高碰撞精度? 是 用凸包碰撞 否 用基本体碰撞 测试并微调 提示 每次只改一个参数 观察FPS和碰撞效果

3.6 实战:一个典型的调优案例

假设你要仿真一个仓库场景:AGV小车搬运箱子,箱子堆叠6层,AGV速度2m/s。

我的调优步骤:

  1. 子步数:AGV速度不算快,2m/s。子步数设为2,防止偶尔穿模。
  2. 碰撞模式:箱子用凸包,地面和墙壁用基本体。
  3. 迭代次数:堆叠6层,超过5层了。设到8。
  4. 睡眠阈值:设到0.005,让静止的箱子尽快睡眠。

跑一轮测试。如果FPS低于30,我会先降迭代次数到4,看看堆叠是否稳定。如果还卡,再降子步数到1——但这时候要留意AGV会不会穿模。

核心原则:精度够用就行,别追求完美。仿真不是电影特效,工业场景里,95%的精度 + 30 FPS,远比99%的精度 + 5 FPS更有价值。

3.7 常见误区总结

  • 误区一:所有物体都用三角网格碰撞。→ 其实90%的场景用凸包就够了。
  • 误区二:子步数越高越好。→ 子步数翻倍,CPU开销也翻倍。够用就行。
  • 误区三:迭代次数设到32,堆叠纹丝不动。→ 但你的仿真已经卡成PPT了。先试试8。
  • 误区四:睡眠阈值设到0.1,所有物体秒睡。→ 然后你发现箱子还在半空中就睡着了,直接悬停。

嗯,调优这件事,说白了就是「试错」。我每次调完参数,都会跑一个5分钟的测试场景,盯着FPS和碰撞效果看。别指望一次调对——物理引擎的参数之间会互相影响,慢慢来,找到那个平衡点。