十一、物理:高级应用

11.1 角色控制器

角色控制器是 Kinematic Actor,是反物理的

11.1.1 在物理系统中创建一个Controller

两个胶囊体:

  1. 内部的胶囊体:用于与其他物体进行碰撞
  2. 外部的胶囊体:防止高速移动时卡到其他物体里面、防止角色离墙太近导致相机出现bug

image-20230728144547779

11.1.2 与环境的碰撞

  1. 撞墙时不是直接停住,而是会沿墙滑动

image-20230728144822521

11.1.3 自动的stepping

有小台阶时,角色要能够迈上去

  1. 每一帧会尝试将controller往高抬一点,往前走
  2. 问题:如果屋顶不是很高,这样做会导致角色卡到屋顶里面

image-20230728144939164

11.1.4 最大斜坡角度

当斜坡的角度过大时,角色虽然能上去,但是会滑下来

image-20230728145229999

11.1.5 体积更新

当角色的姿态变换时,controller的形状要发生变化

image-20230728145432971

11.1.6 Controller推动物体

当controller撞击到物体上时,会触发物理引擎的回调函数,根据controller的质量&速度,输出一个冲量

image-20230728145621939

11.1.7 站在平台上

会通过ray cast,判断controller是站在哪个物体上的。在没有新的输入之前,会将controller与物体绑死

image-20230728145901094

11.2 布娃娃系统

11.2.1 将骨骼与刚体绑定

用几个刚体包裹住角色的大骨骼,所有刚体加起来将整个骨骼包裹住

image-20230728150433669

11.2.2 骨骼的约束

通常在引擎中,会开放每个刚体之间的六个自由度的约束

image-20230728150835128

11.2.3 用Ragdoll驱动骨骼运动

类似于动画重定向

  1. Active joint:Ragdoll绑定的骨骼,直接由Ragdoll控制
  2. Leaf joint:在Ragdoll之外的骨骼,通常不会改变姿态
  3. Intermediate joint:在Ragdoll绑定的骨骼之间的骨骼,会通过相邻两个Active joint进行插值计算

image-20230728151119627

11.2.4 将动画与Ragdoll混合

  1. 前一部分由动画驱动,后一部分逐步交给Ragdoll驱动

image-20230728151418052

image-20230728151408758

11.2.5 Powered Ragdoll

将动画作为输入,动画中会包含速度与旋转,然后由物理系统产生新的动量&角动量,混合起来

image-20230728151630922

11.3 衣料模拟

11.3.1 基于动画的衣料模拟

用骨骼驱动衣物

优点:性能高、可控

缺点:不真实、不能与环境交互、衣物的设计很受限

image-20230728160942706

11.3.2 基于刚体的衣料模拟

用ragdoll技术驱动衣物

image-20230728161116126

11.3.3 基于Mesh的衣料模拟

11.3.3.1 前期工作

将render mesh转化为physical mesh,大幅减少面数

image-20230728161306494

设置每个顶点的约束,越靠近固定点的顶点,约束越大,可变性越小,骨骼权重越小

image-20230728161842890

11.3.3.2 衣料结算–质点弹簧系统

image-20230728162458501

image-20230728162523506

image-20230728163035195

11.3.3.3 Verlet积分

通过相邻两帧的计算公式的合并,下一帧的位置只与当前帧位置、上一帧位置、当前帧加速度有关

  1. 模拟中,位移是最真实的
  2. 这样计算可以减小误差

image-20230728163235979

11.3.5 基于位置的动力学模拟 PBD

用拉格朗日约束求解位置,不需要通过力&速度

  1. 更加快、更加稳定、精度敏感时表现更好

image-20230728163548025

11.3.6 自穿插

image-20230728163830417

  1. 加厚布料
  2. 增加布料的物理仿真步伐
  3. 设置最大的速度,保证每一步不会穿得过深,还可以弹回来
  4. 在布料的里面添加一个负向力场,将顶点弹回来

image-20230728164003716

image-20230728164019251

11.4 破坏模拟

11.4.1 层级碎片

  1. 将整个表面按照层级分为多个碎片,形成一个树状结构

    image-20230728164503118

  2. 连接相邻碎片,得到连接图

    image-20230728164616789

  3. 设置连接权重,表示该连接的硬度

    image-20230728164713239

  4. 当施加的冲量大于硬度时,该连接就会断裂,造成实际的伤害

    image-20230728164915647

  5. 当打中一个点时,会将damage以同心圆的方式传播出去

    image-20230728165027145

11.4.2 与游戏世界连接

image-20230728165236281

11.4.3 自动生成碎片:Voronoi算法

在空间中洒下一些种子,从种子开始,自动划分该空间

image-20230728165445311

image-20230728165511861

image-20230728165526214

生成断裂处的纹理:

  1. 使用3D Texture表示物体的纹理,碎裂时直接在3D Texture中采样即可
  2. 提前离线渲染好断裂处的纹理,碎裂时切换到断裂处的纹理

通常不会让碎裂后的物体参与游戏逻辑的计算

image-20230728165614394

11.4.4 物理系统中的Destruction

image-20230728170049396

11.4.5 破坏后的回调函数

在破坏后,要提供一些回调函数,供上层开发者选择是否播放特效、音效或者其他效果

image-20230728170236962

11.4.6 Destruction产生的问题

一个物体碎成很多个碎片后,会产生大量的独立物体,它们之间会产生大量碰撞

image-20230728170458842

11.5 载具模拟

11.5.1 载具结构建模

  1. 通过rigid body模拟车身
  2. 轮子是弹簧,但是也会与地面产生碰撞

image-20230728170843037

11.5.2 驱动力

  1. 由引擎engine产生扭矩torque
  2. 经过变速箱gear和差分器differential,将扭矩差分到各个轮子上,转化为轮子真实的扭矩drive torque
  3. 轮子的扭矩与地面作用,产生向前的驱动力(静摩擦力)

image-20230728171110327

11.5.3 悬挂力

image-20230728171942668

11.5.4 轮胎力

image-20230728172101716

11.5.5 重心

image-20230728172246993

重心会对汽车在空中的稳定性产生影响:

  1. 重心靠前,容易翻滚
  2. 重心靠后,更加稳定

image-20230728172332009

重心会对转向的驱动力产生影响

  1. 重心靠前:转向力更低
  2. 重心靠后:更容易转向

image-20230728172342905

11.5.6 重心的变化

image-20230728172602276

11.5.7 转向角

image-20230728172721719

image-20230728172820162

11.5.8 Advanced Wheel Contact

image-20230728172913874

11.6 PBD/XPBD

拉格朗日力学:用约束反向推导运动

11.6.1 约束示例

圆周运动约束:始终绕着原点,半径一定的运动

image-20230728173629506

弹簧约束

image-20230728173738433

11.6.2 PBD

雅可比矩阵的作用:计算从某个状态转移到另一个状态时,每个变量的变化趋势

PBD:将任务表达为一系列关于位置的约束,通过雅可比矩阵,计算在当前位置应该向哪个方向扰动,每次只扰动一点点

image-20230728174607551

image-20230728174701030

每一步里面:

  1. 首先把所有v放进去,计算半隐式积分
  2. 判断是否由碰撞,如果有碰撞,相当于添加了一个约束
  3. 用刚才的方法,每一次按照λ步长进行迭代,直到误差较小
  4. 从而得到当前帧每个顶点的位置、速度
  5. 为速度添加一个damping,让PBD的计算更加稳定

image-20230728174754116

优点:稳定、收敛快

image-20230728175255932

11.6.3 XPBD

  1. 给约束添加stiffness,表示约束的权重
  2. 将约束矩阵\(C(X)\)变为了服从度矩阵\(U(X)\)
    1. 类似于弹簧的势能,要求总体的势能最小
    2. 可以对不同约束设计不同的stiffness,在一个方程中求解

image-20230728175316018