想象你在拍一部动画电影:一个皮球砸向地面,弹起来,滚进一滩水里,水面泛起涟漪。如果皮球穿过地面消失了,或者水花溅得像碎玻璃,你会立刻觉得“太假了”。AI 生成视频时面临同样的问题——它需要“懂物理”,才能让画面里的物体遵循现实世界的规则。怎么让 AI 懂物理?答案是给它的“脑海”装一个物理模拟器,就像给一个孩子装上“重力感”和“碰撞感”。刚体仿真管的是“硬东西怎么撞”(皮球、积木、汽车),流体仿真管的是“软东西怎么流”(水、烟、岩浆)。这篇文章就用“拍电影”这个比喻,带你走进世界模型中物理仿真的内核。

岗位关联

对 AI 从业者来说,理解物理仿真 = 理解视频生成模型“不穿帮”的底层逻辑。无论你是在做世界模型、视频生成还是具身智能,物理仿真都是让 AI 从“画得好看”进阶到“物理正确的视频”的必修课。

目录
  1. 可视化演示
  2. 刚体仿真的核心
  3. 碰撞响应与惩罚
  4. 流体仿真的方法
  5. 数值积分的稳定性
  6. 物理引擎的选型
  7. 世界模型中的落地
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

动态演示世界模型中的刚体与流体物理仿的核心机制,通过基础/核心/应用/扩展四种模式展示关键概念与交互流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

世界模型中的刚体与流体物理仿:世界模型 世界模型中物理仿真的必要性与挑 刚体碰撞响应与接触力学建模 核心机制可视化 世界模型中的刚体与流体物理仿整体架构与关键组件

刚体仿真的核心

拍电影时,副导演需要精确记录每个演员的位置、速度,确保走位不穿帮。刚体仿真做的正是这件事——把场景里的“硬东西”视为一个个刚体,追踪它们的位移、旋转、速度和角速度。你可以把每个刚体想象成一辆遥控车:你给它一个初始位置和朝向,然后通过“位置 = 初始位置 + 速度 × 时间”来更新它。这就是刚体仿真的第一步:建立状态变量,然后用数值方法推进时间。

刚体仿真的核心状态由线速度 v 和角速度 ω 共同决定。线速度让物体平移,角速度让物体绕质心旋转。想让刚体动起来,还需要受力分析:重力、碰撞力、摩擦力、约束力(比如铰链)。在 AI 视频生成的场景里,我们通常只关心物体怎么运动,而不关心它内部会不会变形——因为桌椅板凳、汽车皮球这些“硬家伙”在碰撞时几乎不变形。

回到拍电影的比喻:副导演不关心演员肌肉怎么发力,只关心“每秒走几步、面朝哪个方向”。刚体仿真同理——它只追踪宏观状态,把形状简化为碰撞盒或三角网格,用碰撞检测来判断“谁和谁碰到了”。这种简化让世界模型能在毫秒级完成物理推理,为视频生成提供实时约束。

x(t+Δt)=x(t)+v(t)×Δt,v(t+Δt)=v(t)+a(t)×Δt\displaystyle \mathbf{x}(t + \Delta t) = \mathbf{x}(t) + \mathbf{v}(t) \times \Delta t, \quad \mathbf{v}(t + \Delta t) = \mathbf{v}(t) + \mathbf{a}(t) \times \Delta t
位置 = 原来位置 + 速度 × 时间步长;速度 = 原来速度 + 加速度 × 时间步长。就像开车导航:每 0.1 秒根据当前车速推算下个位置。
  1. 位置更新新位置等于旧位置加上速度在时间步长内的位移,这是最基本的运动学方程。
    x(t+Δt)=x(t)+v(t)×Δt\displaystyle \mathbf{x}(t + \Delta t) = \mathbf{x}(t) + \mathbf{v}(t) \times \Delta t
  2. 速度更新新速度等于旧速度加上加速度(来自合力)在时间步长内的增量。
    v(t+Δt)=v(t)+a(t)×Δt\displaystyle \mathbf{v}(t + \Delta t) = \mathbf{v}(t) + \mathbf{a}(t) \times \Delta t
  3. 角速度旋转刚体的朝向用旋转矩阵或四元数表示,角速度驱动旋转更新。
    q(t+Δt)=q(t)+12ω(t)q(t)×Δt\displaystyle \mathbf{q}(t + \Delta t) = \mathbf{q}(t) + \frac{1}{2} \boldsymbol{\omega}(t) \mathbf{q}(t) \times \Delta t

碰撞响应与惩罚

两个演员在片场撞到一起,导演会怎么处理?要么让他们立刻分开(冲量法),要么在他们之间垫一个“气垫”慢慢推开(惩罚力法)。刚体仿真的碰撞响应正是这两条路。冲量法直接修改碰撞瞬间的速度——想象两个台球对撞,撞击前一瞬间速度突然反转,这就是冲量在起作用。惩罚力法则在检测到穿透时施加一个弹性力,像弹簧一样把物体推开。

冲量法的精髓在于动量守恒。两个刚体碰撞时,系统总动量不变,但各自的动量会重新分配。恢复系数 e 描述了反弹的程度:e=1 是完美弹性碰撞(皮球永远弹跳),e=0 是完全非弹性碰撞(泥巴落地粘住)。现实中大多数物体介于两者之间。

惩罚力法的公式更简单:碰撞穿透越深,施加的力越大,像压缩弹簧产生的弹力。它不需要精确求解动量方程,计算快但容易“弹跳抖动”。在实际物理引擎中,两者常结合使用:先用惩罚力防止深度穿透,再用冲量法修正速度——相当于先用气垫缓冲,再轻轻一推让人站稳。

j=−(1+e) vrel⋅n1m1+1m2+(r1×n)TI1−1(r1×n)+(r2×n)TI2−1(r2×n) n\displaystyle \mathbf{j} = \frac{-(1 + e) \, \mathbf{v}_{\text{rel}} \cdot \mathbf{n}}{\frac{1}{m_1} + \frac{1}{m_2} + (\mathbf{r}_1 \times \mathbf{n})^T \mathbf{I}_1^{-1} (\mathbf{r}_1 \times \mathbf{n}) + (\mathbf{r}_2 \times \mathbf{n})^T \mathbf{I}_2^{-1} (\mathbf{r}_2 \times \mathbf{n})} \, \mathbf{n}
冲量 j 的大小与相对速度、恢复系数成正比,与质量、转动惯量有关。碰撞越猛、恢复系数越高,冲量越大——就像你用力拍墙反弹力更大。
  1. 相对速度投影计算两碰撞点沿法线方向的相对速度,决定冲量方向。
    vrel=(v1−v2)⋅n\displaystyle v_{\text{rel}} = (\mathbf{v}_1 - \mathbf{v}_2) \cdot \mathbf{n}
  2. 恢复系数修正乘以 -(1+e) 让碰撞后相对速度反向并衰减。
    −(1+e) vrel⋅n\displaystyle -(1 + e) \, \mathbf{v}_{\text{rel}} \cdot \mathbf{n}
  3. 质量惯性归一化分母合并两刚体的质量倒数与转动惯量贡献,保证动量守恒。
    1m1+1m2+(r1×n)TI1−1(r1×n)\displaystyle \frac{1}{m_1} + \frac{1}{m_2} + (\mathbf{r}_1 \times \mathbf{n})^T \mathbf{I}_1^{-1} (\mathbf{r}_1 \times \mathbf{n})

流体仿真的方法

刚体是“演员”,那流体就是“群演”——水、烟、火,成千上万个粒子或网格单元,每一个都随波逐流。想象你在拍一场暴雨戏:水从天空倾泻,汇成洪流。你可以用两种方式拍:一种是给每个雨滴装上追踪器,跟着它飞(拉格朗日法);另一种是在空间画好网格,记录每个格子里的水量变化(欧拉法)。这两种思路对应了流体仿真的两大流派。

拉格朗日粒子法把流体离散成大量粒子,每个粒子携带质量、速度、位置。粒子之间通过相互作用力(压力、粘性力)推动。最经典的算法是 SPH(Smoothed Particle Hydrodynamics,平滑粒子流体力学):每个粒子就像一滴小水珠,通过影响半径内的“邻居”来计算受力。欧拉网格法则把空间划分为网格单元,每个格子存储速度场、压力场、密度场,通过求解偏微分方程(N-S 方程)得到每格流体的演化。

回到拍电影:拉格朗日法像给上千群演每人发一台 GPS,精确但计算量大;欧拉法像在片场铺好方格地砖,记录每格的水深,够用但细节粗糙。现代流体现效结合两者——离镜头近的地方用粒子法,远处用网格法,既保真又省算力。

fi=∑j≠imj(piρi2+pjρj2)∇W(ri−rj,h)\displaystyle \mathbf{f}_i = \sum_{j \neq i} m_j \left( \frac{p_i}{\rho_i^2} + \frac{p_j}{\rho_j^2} \right) \nabla W(\mathbf{r}_i - \mathbf{r}_j, h)
这是 SPH 中粒子 i 受到的压力合力:每个邻居粒子 j 贡献一份“推开”的力,大小由压力 p 和光滑核函数 W 决定。就像一群人挤在电梯里,每个人都被周围人推挤,压强越大推挤越强。
  1. 邻居粒子遍历对每个粒子 i,找出影响半径内所有邻居粒子 j。
    ∑j≠imj\displaystyle \sum_{j \neq i} m_j
  2. 压力梯度项压力差驱动流体运动,从高压区流向低压区。
    (piρi2+pjρj2)\displaystyle \left( \frac{p_i}{\rho_i^2} + \frac{p_j}{\rho_j^2} \right)
  3. 核函数加权$\nabla W$ 是光滑核函数的梯度,距离越近影响越大。
    ∇W(ri−rj,h)\displaystyle \nabla W(\mathbf{r}_i - \mathbf{r}_j, h)

数值积分的稳定性

物理仿真的本质是解微分方程——但计算机只能离散地一步步推进。就像拍电影不能连续记录每帧,只能每秒拍 24 帧,中间的时间用“积分”推算。数值积分方法决定了推算的准确性和稳定性。如果推算偏差过大,物体可能越飞越高最终爆炸——这就是“数值发散”。

最简单的显式欧拉法:直接用当前时刻的速度和位置,一步算出新位置。它像开夜车只看眼前 5 米,转弯大了容易翻车,当时间步长过大时系统就会发散。隐式欧拉法则用“未来”的值来推算,像在结冰的路面上起步,每一步都试探性踩油门,稳定但计算量翻倍。半隐式欧拉法折中:先用新速度更新位置,再算新加速度——这是很多物理引擎和游戏引擎的默认选择。

为什么步长选择如此关键?想象拍 24 帧视频,每帧之间的时间 Δt=1/24 秒。如果 Δt 太大,物体可能在 1 帧内穿透一堵墙;如果 Δt 太小,计算量剧增。对世界模型来说,需要在精度和速度间找平衡——通常用自适应步长:物体运动快、碰撞多时自动加密时间步。

vn+1=vn+a(xn)×Δt,xn+1=xn+vn+1×Δt\displaystyle \mathbf{v}_{n+1} = \mathbf{v}_n + \mathbf{a}(\mathbf{x}_n) \times \Delta t, \quad \mathbf{x}_{n+1} = \mathbf{x}_n + \mathbf{v}_{n+1} \times \Delta t
半隐式欧拉:先用旧位置算加速度更新速度,再用新速度更新位置。就像一个谨慎的司机:先踩油门,再根据新速度预判下个位置。
  1. 加速度计算用当前位置 x_n 计算加速度(由合力决定)。
    a(xn)\displaystyle \mathbf{a}(\mathbf{x}_n)
  2. 速度更新新速度 = 旧速度 + 加速度 × 时间步长。
    vn+1=vn+a(xn)×Δt\displaystyle \mathbf{v}_{n+1} = \mathbf{v}_n + \mathbf{a}(\mathbf{x}_n) \times \Delta t
  3. 位置更新新位置 = 旧位置 + 新速度 × 时间步长——这就是“半隐式”的关键。
    xn+1=xn+vn+1×Δt\displaystyle \mathbf{x}_{n+1} = \mathbf{x}_n + \mathbf{v}_{n+1} \times \Delta t

物理引擎的选型

拍电影要选摄影器材,物理仿真要选引擎。市面上主流开源方案各有所长。PhysX 是 NVIDIA 的物理引擎,GPU 加速强、刚体流体全家桶,适合视频生成场景的深度学习框架集成;Bullet 老牌开源引擎,支持刚体、软体、流体,在机器人仿真和游戏领域广泛使用;MuJoCo 则专注于接触力学的精确建模,是强化学习和具身智能的首选——它的信噪比高,对真实世界的模拟精度领先。Taichi(太极)是新兴的 GPU 并行编程语言,用 Python 就能写出高效的 SPH 流体仿真。

选型时要权衡三个维度:精度(物理世界的还原度)、速度(每秒能模拟多少帧)、易用性(与深度学习框架的集成难度)。对世界模型来说,引擎要能嵌入神经网络训练流程,最好支持“可微分物理”——让梯度能流经碰撞和流体计算,这样才能让 AI 从物理引擎中学习规则。

回到影片:你是导演,选器材要看拍摄题材。拍洪水灾难片,SPH 粒子法 + GPU 加速的引擎是首选;拍机器人抓取积木,接触精度高的 MuJoCo 更合适。没有“最好的引擎”,只有“最适合当前任务的引擎”。

评分=w1×精度+w2×速度+w3×集成度,w1+w2+w3=1\displaystyle \text{评分} = w_1 \times \text{精度} + w_2 \times \text{速度} + w_3 \times \text{集成度}, \quad w_1 + w_2 + w_3 = 1
引擎选型是一个加权打分问题:不同场景给精度、速度、集成度不同权重。做视频生成,可能更看重 GPU 加速和可微性;做机器人仿真,更看重接触精度。
  1. 权重分配三个权重 w1、w2、w3 之和为 1,表示不同场景下的优先级。
    w1+w2+w3=1\displaystyle w_1 + w_2 + w_3 = 1
  2. 加权求和每个维度打分后按权重加权,总分越高越适合当前场景。
    评分=w1×精度+w2×速度+w3×集成度\displaystyle \text{评分} = w_1 \times \text{精度} + w_2 \times \text{速度} + w_3 \times \text{集成度}
  3. 动态调整训练阶段和推理阶段可以切换不同引擎——训练求稳(隐式),推理求快(显式)。
    Enginetrain=Enginestable,Engineinfer=Enginefast\displaystyle \text{Engine}_{\text{train}} = \text{Engine}_{\text{stable}}, \quad \text{Engine}_{\text{infer}} = \text{Engine}_{\text{fast}}

世界模型中的落地

最后,物理仿真如何进入世界模型?世界模型要生成“物理正确”的视频,不能靠事后检查,而要在生成过程中就遵循物理规律。目前有三条主流路径。路径一:物理约束生成——在视频生成模型的推理过程中,每生成一帧就调用物理引擎做约束,让生成结果符合物理定律。路径二:神经模拟器蒸馏——用物理引擎生成海量“物理正确的视频”作为训练数据,让扩散模型“学会”物理规则,推理时不再调用物理引擎。

路径三:混合神经物理场——把物理引擎的偏微分方程求解器嵌入神经网络的隐藏层,让模型既保留神经网络的表达力,又满足物理方程的约束。你可以把这三条路径想象成教演员演戏:物理约束生成是“导演在旁边盯着,错了就喊卡”;神经模拟器蒸馏是“提前排练了无数遍,肌肉记忆已经形成”;混合神经物理场是“把导演的指导写在剧本里,演员照着剧本演就不会错”。

这正是世界模型和视频生成 Model(如 Sora 和 World Model 类架构)最前沿的融合方向:物理引擎提供先验知识,神经网络提供表达自由,两者结合让 AI 既能理解物理规则,又能创造丰富多彩的视觉内容。

Ltotal=L视频重建+λ物理∥xt+1−P(xt)∥2\displaystyle \mathcal{L}_{\text{total}} = \mathcal{L}_{\text{视频重建}} + \lambda_{\text{物理}} \left\| \mathbf{x}_{t+1} - \mathcal{P}(\mathbf{x}_t) \right\|^2
最终损失 = 视频重建误差 + 物理约束误差。物理项像“导演的叮嘱”:生成结果与物理引擎预测的下一帧偏差越小,奖励越高。
  1. 重建损失衡量生成视频帧与真实视频的像素差异,是第一目标。
    L视频重建\displaystyle \mathcal{L}_{\text{视频重建}}
  2. 物理正则项用物理引擎预测的下一状态与实际生成状态的均方误差作为约束。
    ∥xt+1−P(xt)∥2\displaystyle \left\| \mathbf{x}_{t+1} - \mathcal{P}(\mathbf{x}_t) \right\|^2
  3. 权重系数λ_物理控制物理约束的强度——太小则物理穿帮,太大则画面僵硬。
    λ物理\displaystyle \lambda_{\text{物理}}

AI 应用场景

场景一:影视级视频生成中的物理约束

阶段:世界模型训练与推理

解决的问题:传统视频生成模型经常出现“水从杯子里流出却往天上飞”、“球穿过桌面”的物理穿帮。引入物理引擎做约束后,生成的视频每一帧都经过刚体碰撞和流体动力学校验,从根本上杜绝穿帮。

具体案例:某影视特效公司用世界模型生成“城市洪水”镜头。传统的做法是先用 SPH 流体仿真模拟水流,再人工调节粒子材质参数,耗时数周。现在用混合神经物理场——把 SPH 仿真嵌入视频生成模型,输入一段暴雨视频,模型自动生成物理正确的洪水蔓延动画,耗时从两周缩短到三天。

场景二:具身智能的机器人仿真训练

阶段:强化学习环境构建

解决的问题:机器人要在真实世界抓取物体,但真实训练成本高、风险大。用 MuJoCo 引擎构建物理正确的仿真环境,让机器人在仿真中学习抓取、推搡、堆叠刚体的技能,再迁移到真实世界。

具体案例:研究团队用 MuJoCo 模拟“机器人叠杯子”任务。每个杯子是刚体,水是流体(用粒子法模拟),机器人需要先学会抓住杯子不洒水,再学会叠放。仿真环境下训练 100 万步后,迁移到真实机器人的成功率从 20% 提升到 85%。

场景三:游戏引擎中的实时物理世界

阶段:实时推理与渲染

解决的问题:游戏中的 NPC 需要感知物理世界——扔出去的石头会弹开,雨水会在地面积聚。用物理引擎做实时仿真,为游戏世界模型提供物理一致的交互反馈。

具体案例:某开放世界游戏用 Bullet 引擎做刚体仿真(碎石、木箱),用 Taichi 写 SPH 做水交互(玩家踩水会溅起水花)。玩家看到的每帧画面都经过物理引擎的实时计算,即使是 AI 生成的 NPC 行为也符合物理直觉。

Python 演示

python120 行
import numpy as npimport matplotlib.pyplot as plt class RigidBody:    def __init__(self, x, v, mass=1.0, restitution=0.7):        # 初始化刚体状态:位置、速度、质量、恢复系数        self.x = x        self.v = v        self.mass = mass        self.e = restitution     def apply_force(self, f, dt):        # 牛顿第二定律: 加速度 = 合力 / 质量        self.v += f * dt / self.mass     def update(self, dt):        # 半隐式欧拉积分: 先更新速度, 再更新位置        self.v += self.g * dt        self.x += self.v * dt     def collide_ground(self, ground_y):        # 地面碰撞响应: 位置反弹, 速度乘以恢复系数并反号        if self.x < ground_y:            self.x = ground_y            self.v = -self.e * self.v     def kinetic_energy(self):        # 动能 = 0.5 * m * v^2        return 0.5 * self.mass * self.v**2  class SPHSimulation:    def __init__(self, x, v, mass=1.0, h=0.5, rho0=1000.0):        # 初始化 SPH 粒子系统: 所有粒子的位置、速度、质量        self.x = np.array(x, dtype=float)        self.v = np.array(v, dtype=float)        self.mass = mass        self.h = h        self.rho0 = rho0        self.gc_count = 0  # 计数: 避免与方法同名     def smooth_kernel(self, r):        # 光滑核函数: 距离越近影响越大, 超过 h 则无影响        q = np.linalg.norm(r) / self.h        if q < 1.0:            return (2.0 / 3.0) * (1.0 - 1.5 * q + 0.75 * q**3)        return 0.0     def compute_density(self, i):        # 计算粒子 i 的密度: 所有邻居粒子的质量加权        rho = self.mass * self.smooth_kernel(np.zeros(2))        for j in range(len(self.x)):            if j != i:                rho += self.mass * self.smooth_kernel(self.x[i] - self.x[j])        return rho     def pressure_force(self, i):        # 压力梯度力: 从高压区指向低压区        force = np.zeros(2)        rho_i = self.compute_density(i)        for j in range(len(self.x)):            if j != i:                rho_j = self.compute_density(j)                grad_w = self.smooth_kernel_grad(self.x[i] - self.x[j])                force += -self.mass * (self.v[i] - self.v[j]) * grad_w        return force     def smooth_kernel_grad(self, r):        # 核函数梯度: 决定力的大小和方向        # 简化实现: 使用线性近似        n = np.linalg.norm(r)        if n < 1e-6:            return np.zeros(2)        return -self.h * r / n**2     def update(self, dt):        # 更新所有粒子: 施加压力梯度力和重力        for i in range(len(self.x)):            f = self.pressure_force(i)            self.v[i] += (f / self.rho0 + np.array([0.0, -9.8])) * dt            self.x[i] += self.v[i] * dt            self.gc_count += 1     def simulate(self, steps, dt=0.01):        # 主循环: 推进仿真        for _ in range(steps):            self.update(dt)        return self.x, self.v  def main():    # 创建小球: 从 1米 高度自由落体    ball = RigidBody(x=1.0, v=0.0, mass=2.0, restitution=0.7)    ball.g = -9.8     # 模拟 2 秒: 观察能量变化    energies = []    times = np.arange(0, 2, 0.01)    for dt in np.diff(np.append(0, times)):        ball.apply_force(0, dt)        ball.update(dt)        ball.collide_ground(ground_y=0)        energies.append(ball.kinetic_energy())     # 创建 SPH 粒子系统    x = np.array([[0.0, 0.0], [0.5, 0.0], [1.0, 0.0], [1.5, 0.0], [2.0, 0.0]])    v = np.zeros((5, 2))    sph = SPHSimulation(x, v)    final_x, final_v = sph.simulate(steps=10)     plt.plot(times[:-1], energies)    plt.xlabel("时间 (s)")    plt.ylabel("动能 (J)")    plt.title("刚体碰撞能量变化")    plt.show()    print("仿真完成, 最终粒子位置:", final_x)  if __name__ == "__main__":    main()
目的:演示刚体碰撞(地面反弹 + 能量衰减)和 SPH 流体的核心逻辑——压力梯度力驱动粒子运动。
  1. self.v += f * dt / self.mass牛顿第二定律的离散形式:合力除以质量得加速度,乘以时间步长得速度增量
  2. self.x += self.v * dt半隐式欧拉积分:用更新后的速度更新位置,保证数值稳定
  3. self.v = -self.e * self.v地面碰撞响应:速度反向并乘以恢复系数(0.7 表示弹跳后保留 70% 速度)
  4. smooth_kernel(self, r)SPH 核心:核函数决定粒子间影响随距离衰减的规律
  5. compute_density(self, i)密度估计:每个粒子的密度是邻居粒子质量的加权和,类比“人群密度”
  6. pressure_force(self, i)压力梯度力:高密度区域向低密度区域推动,让流体“摊开”
  7. ball.g = -9.8重力加速度赋值,是刚体自由落体的驱动力

常见误区

误区显式欧拉法实现简单、计算快,直接用它跑物理仿真不就行了?时间步长调大一点,一秒钟能算上千帧,效率岂不更高?

正解显式欧拉法的稳定性极差。就像开车只看眼前 5 米,速度一快就翻车——时间步长稍大,能量会越算越多,系统“爆炸”。半隐式欧拉法虽然是隐式欧拉的近似,但稳定性和精度都远优于显式,是现代物理引擎的“默认选项”。天下没有免费的午餐,追求速度必须以稳定为底线。

为何常见:初学者学数值积分时,先接触的是欧拉法最直观的显式形式,公式简单、代码好写,自然觉得“快就是好”。

误区流体仿真嘛,粒子数量翻倍,视觉效果一定更细腻,质量也更高。把粒子数从 1000 加到 100 万,效果拉满。

正解粒子多确实提升分辨率,但边际收益快速递减。SPH 的计算复杂度是 O(n²)(每个粒子要遍历所有邻居),粒子翻 10 倍,计算量翻 100 倍。更关键的是,粒子太多时核函数选择的误差影响更大,甚至会引入数值噪声。专业做法是“自适应性”——近处加密、远处稀疏,用 GPU 加速邻居搜索。

为何常见:人容易把“数量”等同于“质量”,但物理仿真是计算资源预算的艺术,不是堆量的游戏。

误区物理引擎是现成的库,直接调 API 就行,不用理解内部原理,就像用计算器不用懂加法器原理。

正解物理引擎的每个参数(恢复系数、时间步长、碰撞容差)都可能决定仿真是“稳定收敛”还是“爆炸发散”。做视频生成场景,你还需要把物理引擎接入神经网络——如果引擎不可微,梯度无法回流,训练就断了。理解刚体碰撞和 SPH 的原理,才能正确地设置参数、诊断“物体乱飞”“水花穿帮”等典型故障。

为何常见:现代物理引擎封装得太好,API 调用极其简单,让人误以为“调参即懂”。

误区刚体和流体是完全不同的世界,刚体仿真只能处理硬碰硬的碰撞,跟水、火、烟这些流体不搭界。

正解刚体仿真的碰撞检测其实可以服务于流体——比如 SPH 的边界处理,把容器和障碍物视为刚体,流体粒子撞击刚体表面时按碰撞响应反弹。反过来,流体对刚体也有浮力和冲击力,所以现代引擎(PhysX、Bullet)都在刚体核心之上扩展了流体耦合模块。它们不是两套孤立的系统,而是一个统一物理世界的正反两面。

为何常见:多数教材把刚体动力学和流体力学分开讲,“力”的视角分割了知识框架,让人误以为它们是并列独立的领域。

面试题

Q1. 刚体仿真中最核心的“追踪目标”是什么?

单选题 · easy

  • A.物体内部的应力分布
  • B.物体的位置、速度与朝向← 正确答案
  • C.物体表面纹理的细节
  • D.物体材质的化学成分

答案:B。刚体仿真的核心是宏观运动状态——位置、速度、角速度、朝向,而非内部应力或材质成分。就像拍电影只关心演员走到哪、面朝哪,不关心演员肌肉怎么收缩。A 是有限元分析的目标,C 属于渲染范畴,D 毫无关系。

Q2. 半隐式欧拉法与显式欧拉法的关键区别是什么?

单选题 · easy

  • A.半隐式用旧速度更新位置
  • B.半隐式用新速度更新位置← 正确答案
  • C.半隐式不更新速度
  • D.半隐式不更新位置

答案:B。半隐式欧拉法先用旧位置算加速度更新速度,再用新速度更新位置。显式欧拉则用旧速度更新位置,像“先看后走”,而半隐式是“先走再看”,数值稳定性大幅提升。

Q3. 恢复系数 e=0 表示什么物理含义?

单选题 · mid

  • A.完全弹性碰撞
  • B.完全非弹性碰撞← 正确答案
  • C.碰撞后速度加倍
  • D.碰撞后物体消失

答案:B。恢复系数描述碰撞后相对速度的恢复比例。e=1 是完美弹性(皮球永远弹),e=0 是完全非弹性(泥巴落地粘住,动能全部耗散为变形和热量)。

Q4. SPH 算法中“光滑核函数”的作用是什么?

单选题 · mid

  • A.将粒子位置映射到像素
  • B.决定粒子间影响随距离的衰减← 正确答案
  • C.计算粒子的颜色值
  • D.加速粒子碰撞检测

答案:B。SPH 的核函数 W 定义了粒子影响半径内的权重分布——距离越近贡献越大,超过影响半径 h 则贡献为 0。就像人群密度:离你越近的人对你的“拥挤感”贡献越大。

Q5. 下列哪些属于世界模型中融入物理仿真的典型路径?

多选题 · mid

  • A.物理约束生成← 正确答案
  • B.随机噪声注入
  • C.神经模拟器蒸馏← 正确答案
  • D.混合神经物理场← 正确答案

答案:ACD。三条路径分别是:推理时用物理引擎约束生成(A)、用物理引擎数据蒸馏训练神经网络(C)、把物理方程嵌入网络结构(D)。B 随机噪声是扩散模型的加噪手段,与物理约束无关。

Q6. 惩罚力法处理碰撞时,为什么可能出现“抖动”现象?

单选题 · mid

  • A.惩罚力与穿透深度成反比
  • B.惩罚力与穿透深度成正比且弹簧刚度太大← 正确答案
  • C.惩罚力与速度无关
  • D.惩罚力会让物体加速

答案:B。惩罚力 = 刚度系数 × 穿透深度。刚度太大时,物体刚穿透就被大力弹回,下一帧又穿入,形成弹簧式的振荡。就像弹簧床垫过硬,人躺上去会不停抖动。

Q7. 刚体碰撞冲量公式中,分母的物理含义是什么?

单选题 · hard

  • A.两刚体的总质量
  • B.碰撞点沿法线方向的“有效质量”倒数之和← 正确答案
  • C.碰撞点的位置
  • D.摩擦系数之和

答案:B。分母包含质量倒数与转动惯量贡献(r×n)^T I^-1 (r×n),它衡量“在碰撞点沿法线方向推一推,物体能有多大的运动响应”——有效质量越小,响应越灵敏,冲量越大。类比:推门把手(远离铰链)比推门轴(靠近铰链)更容易推动。

Q8. 关于数值积分的时间步长选择,下列说法正确的是?

多选题 · hard

  • A.步长越小精度越高但计算越慢← 正确答案
  • B.步长过大可能导致显式方法发散← 正确答案
  • C.自适应步长根据速度动态调整← 正确答案
  • D.隐式方法对步长极其敏感

答案:ABC。A、B 是数值积分的常识。C 是现代物理引擎的常用优化——物体碰撞剧烈时自动加密步长。D 错误:隐式方法恰恰以“大步长稳定”著称,它牺牲精度换取稳定性。

Q9. 物理引擎选型的主要权衡维度有哪些?

多选题 · mid

  • A.物理精度← 正确答案
  • B.计算速度← 正确答案
  • C.与深度学习框架的集成度← 正确答案
  • D.安装包大小

答案:ABC。精度(还原真实物理)、速度(实时渲染/训练吞吐)、集成度(能否支持自动微分、与 PyTorch 等框架对接)是三大核心维度。安装包大小是工程便利性但不是核心决策因素。

Q10. 在物理约束的视频生成中,损失函数中的物理项的“约束”手段是什么?

单选题 · easy

  • A.将物理引擎预测状态与生成状态之间的均方误差加入总损失← 正确答案
  • B.直接修改生成视频的像素值
  • C.用物理引擎替代扩散模型
  • D.禁止视频中出现物体碰撞

答案:A。物理项用 ‖x_{t+1} - P(x_t)‖² 衡量“生成画面的下一帧”与“物理引擎预测的下一帧”的偏差,将其作为正则项加入总损失。它不直接改像素、不替代模型,而是让模型学会不偏离物理规律——就像导演在片场盯着演员,动作不对就喊卡。