🧿

Physical Simulation 物理模拟

Newton’s Law

最简单的物理,就是牛顿的运动定律。
应用在一个物体的一个质量、一个质点上的一个力 F 会获得一个加速度。它们的关系就是 ,有了加速度就能算速度,有了速度就能算位置。也就是说只要我们知道了物体上的力,以及一些初始条件,比如位置在哪,最初的速度是多少,那么我们就能动态地更新下一个位置。
notion image
💡
模拟和仿真就是不断地推导和实现各种不同的物理公式,用作模拟,来计算出物体应该有的形状的变化或位置的改变。

Physically Based Animation

Generate motion of objects using numerical simulation
notion image
例如我们扔一个小球,我们知道会由重力的作用下形成一个抛物线,有重力就有加速度的影响,就会影响速度,从而影响位置。
对衣服来说,衣服由不同的网格来形成,我们知道在某一个顶点上会受到重力,由于顶点和其他顶点相连,肯定也会受到各种各样的作用力。虽然复杂,涉及到大量的碰撞检测,但把所有力都考虑在一块,算出受力模型,我们就能算出加速度,从而算出位置。

Example: Cloth Simulation

模拟得好的话,就肯定不会出现反物理的现象,例如衣服进到人的身体里面。
notion image

Example: Fluids

流体是在仿真领域研究非常多的话题,特别是对于水。
  1. 先模拟水是怎么运动的,水滴和各种地方是怎么形成的。
  1. 模拟了水的位置形状之后,还要去渲染。
正常来说这两步是割裂开的,正常来说我们不会去关心渲染是怎么做的,而是会去关心水花四溅是怎么做的。
Macklin and Müller, Position Based Fluids
Macklin and Müller, Position Based Fluids

Mass Spring System: Example of Modeling a Dynamic System

我们只要正确地建立物体的相互作用力,把作用力解释明白,自然就能模拟正确的效果。
这里介绍一个非常简单、实用的系统——质点弹簧系统(Mass Spring System)。

Example: Mass Spring Rope

把绳子模拟成很多个小弹簧连接在一块,我们可以让弹簧在重力的作用下来回打。
Video preview

Example: Hair

这里关心的不是头发怎么样渲染得真实,而是在各种作用力下,头发会有怎样的变化。
例如下图中头发会受风力、重力,头发和头发之间也有摩擦力,当我们把各种力结合起来就有非常准确的效果。
nvida 实时
nvida 实时

Example: Mass Spring Mesh

质点弹簧系统还可以作为一块布,布既然是网格描述的,很自然地就能用质点弹簧系统来描述。如下图,我们还能在上面拽。
notion image
 
对一块布,只要我们建模得足够好,模拟的仿真是可以达到以假乱真的效果的。
下图中,左边是照片,右边是渲染仿真的效果,可以看到仿真的结果几乎是一致的。当然也会有区别,有区别也是肯定的,因为在真实世界中很多东西不是那么容易就能表示出来的。
Huamin Wang, Ravi Ramamoorthi, and James F. O'Brien. "Data-Driven Elastic Models for Cloth: Modeling and Measurement". ACM Transactions on Graphics, 30(4):71:1–11, July 2011. Proceedings of ACM SIGGRAPH 2011, Vancouver, BC Canada.
Huamin Wang, Ravi Ramamoorthi, and James F. O'Brien. "Data-Driven Elastic Models for Cloth: Modeling and Measurement". ACM Transactions on Graphics, 30(4):71:1–11, July 2011. Proceedings of ACM SIGGRAPH 2011, Vancouver, BC Canada.

A Simple Spring

💡
质点弹簧系统是什么? 是一系列相互的点和弹簧。
💡
质点弹簧系统最基础的单元是什么? 是一个弹簧左右连接的两个质点。
假设一个理想化的弹簧,没有长度,被拉开多长就会产生多大的力。
notion image
就是弹簧应用在 a 上,使得 a 往 b 方向去的作用力。这个作用力取决于 a 到 b 有多远,和定点 a 有关。同时还取决于这个作用力的方向,把弹簧从没有长度到拉长之后,就能看到式子中的 ,是 a 指向 b 的向量,向量本身和长度有关系,b-a 越长,力越大。这样就可以精确写出 a 点收到的往 b 方向去的力。是劲度系数。a 受到向右的力,那 b 受到的就是向左的力,两个力互为相反,这个就是胡克定律(Hooke’s Law)。
⚠️
但是,没有弹簧是零长度的。

Non-Zero Length Spring

Spring with non-zero rest length
弹簧正常情况下都有一个长度,这个长度叫 Rest length,就是式子中的
归一化表示的是受力的方向,绝对值减 就是拉伸的长度。
在分析的时候,我们只需要考虑拉伸。
⚠️
但是这样的话,弹簧会永远地震动下去,因为能量守恒,动能和势能一直在转换。如果用我们这个模型,只要我们拉开弹簧松手,弹簧就永远不会停。

Dot Notation for Derivatives

那我们就加入一个摩擦力,让它能停下来。
我们加入一个在物理仿真中常用的记号。平常我们会用 来表示位置, 表示速度(位置的一阶导数)。但在模拟仿真中会用点来表示, 表示速度, 表示加速度(位置的二阶导数,也就是速度的导数)。

Introducing Energy Loss

我们要加一个摩擦力让弹簧停下来,这个力就是 damping force。
想让一个物体停下来,那么力就要和运动的方向相反。因此 的方向和 速度相反。
 
notion image
  • Behaves like viscous drag on motion
  • Slows down motion in the direction of velocity
  • is a damping coefficient
Problem: slows down all motion
  • Want a rusty spring’s oscillations to slow down, but should it also fall to the ground more slowly?
但是这样又有问题:它会让所有运动都停下来。加入我们有弹簧 ab,ab 同步向右走。这样会出现 ab 之间没有相对的运动,也就是说弹簧一直没有拉伸,整个不会震动,但最后还是会被这个力停下来。也就是说这个摩擦力只能描述外部的力,不能描述弹簧之间内部的力。
另外,如果我们竖着拿着 ab 弹簧系统,一松手弹簧往地上掉,作为一个整体来说,下落的速度是定的,如果我们对 ab 都应用这个摩擦力,那么下落的就会越来越慢。
💡
这个摩擦力描述不了弹簧内部的损耗。

Internal Damping for Spring

Damp only the internal, spring-driven motion
内部的摩擦力应该跟相对之间的运动有关系。
首先我们要知道摩擦力要做什么事,这个力希望弹簧恢复到正常长度。也就是说只要 a 和 b 被拉开了,a 就会想办法往 b 方向去靠。
假设我们拉开弹簧,那么就应该有个力应用在 b 方向上向左,那么可以下式中 描述的方向就是对的。那么这个力有多大?这肯定跟 a 和 b 的相对速度有关系, 中, 是a 指向 b 的单位向量, 是相对速度向量,向量点乘单位向量的结果,其实就是往一个方向上做投影,就可以得到投影的长度,也就是相对速度投影在 ab 方向的速度是多少。
为什么要做投影?因为相对速度本身还解决不了问题,有一些速度并不能让弹簧引起改变,例如按住 a,然后让 b 做圆周运动,b 的速度是垂直于方向 a 到 b 的,这时绝对不应该有弹簧内部摩擦力的损耗,从而让它停在它的自然长度上。
因此我们要把相对速度分解到沿着 ab 方向,这个相对速度才会对整个质点弹簧系统造成衰减。
notion image
  • Viscous drag only on change in spring length
    • Won’t slow group motion for the spring system (e.g. global translation or rotation of the group)
  • Note: This is only one specific type of damping
⚠️
之前拽弹簧的力跟长度有关系,但这个摩擦力跟长度没关系。

Structures from Springs

上面说的只是一种摩擦力,其实还有各种不同的摩擦力,但只要我们分析明白,能写出物理公式就没问题,剩下如何模拟的步骤相对简单。
💡
我们这里的物理原理,都是对真实物理中存在的现象进行的一种抽象或简化。
notion image
如果现在用不同的弹簧想模拟一块布,就可以想下图这么连接。下图无限大,哪里都有连接。
但这个结构有问题。切边(shearing)会影响,也就是往对角一拽,形状就会改变。也就是说应用这种力,它就会发生这种形变,但真实的布不会这样。也就是说对于这种简单的结构来说,用来模拟布是不合理的。因为布可以抵抗切边这种力,不会影响形状。
如果有一种力可以让这个形状变得不是一个平面,这种我们叫 out-of-plane bending,就是让一个平面发生弯曲。一块布很难像纸一样对折,例如沿着对角线,两三角形对折到一块,折成一张纸。布本身有对抗这种折法,但目前这个结构是可以对折的。
notion image
首先来解决切变的问题,现在这个形状中加入斜的对角线,如果我们沿对角线拉的话,我们新加的蓝色的质点弹簧系统会压缩往里挤,整个形状会变瘦,弹簧会往外抵抗它,这算是解决了问题。但是这个结构不对称,对于一块布,我们从各个方向拉它,行为都应该是一致的。
虽然这个蓝色的线也能抵抗沿着下图线的对折,但是另外一个方向是不行的。
notion image
我们可以在另外一个方向再加线,但这样仍然不能抵抗非平面的弯曲。
如果我们沿着顶点竖着作折痕来对折,还是不会引起其他的变化,因此无法解决非平面弯曲的问题。
 
notion image
 
这里我们对任何一个点都跟隔了一个的点连线。加了之后,不管我们怎么弯曲平面,都会引起弹簧的长度发生变化。
红线的连接其实是非常弱的,本身不折也可以弯下来,例如布放在桌边也能自然垂下来。
也就是说红线不是说多强,而是强在布本身(蓝线)非常强,红线只是加了一点点来抵抗非平面弯折的事情。
notion image
这样,再加上各种摩擦力、本身的模型等,对于一块布,拿到空中放下落到地上,这部分的模拟是绝对够用了。

Example: Mass Spring Dress + Character

notion image
但这样还不足够精确,前面提到过布料的渲染:Cloth,有三个层级结构的缠绕,纤维缠绕形成 Ply,Ply 再经过缠绕形成 Yarn 线,线再通过不同的针织方法来编织形成不同真实的布料,其中还有旋转的东西。
💡
物理模拟是对真实世界的一种表示方法,但通常都是简化的表示方法。
💡
有没有除了质点弹簧系统其他的系统?有,比如有限元方法(Finite Element Method)。

Aside: FEM (Finite Element Method) Instead of Springs

有限元方法(Finite Element Method)被广泛地应用于车的碰撞,比如汽车厂商在发布新车之前会做一些模拟,撞向一些墙。接触墙的地方会受力,但为什么车到车尾巴都会被撞坏?因为力有传导的作用,这就好像热之间也有传导的作用。传导的过程,也就是扩散的过程,叫 defusing,很适合拿有限元方法来做。
有限元方法非常不好做,写起来头疼,但也是另一种对世界建模的方式,它讲的是一个力从一个地方扩散到另一个地方应该怎么样。
notion image