【深入淺出 Nvidia FleX】(1) Position Based Dynamics
一、 Nvidia FleX簡介
FleX 是一款完全基於GPU的物理引擎,其中所有動態物體都是由粒子構成,可以很容易實現不同物體(剛體,軟體,流體,布料等)之間的互動效果。如下圖:


在傳統的物理引擎中,基本上都是針對每一種動態物體,會有一個獨立的解算器(Solver),各種Solver按照一定順序進行計算,從而得到模擬結果,這樣會帶來大量冗餘工作。而FleX把所有動態物體,都用同一種方式表達出來,這樣一來,就只需要一個Solver便可以模擬所有這些物體,並原生支援它們之間的雙向互動效果。
FleX 採用粒子來描述所有這些動態物體,也就是說在我們的物理世界中,每一個動態物體都由一組粒子通過某種約束(constraint)連線起來,不同的約束關係可以模擬出不同材質的物體。FleX中主要有如下幾種約束型別:
距離約束,用於模擬布料,包括布料的拉伸和彎曲等行為;
形狀約束,用於模擬剛體和軟體;
密度約束,用於模擬流體;
體積約束,用於模擬充氣體;
碰撞約束,計算粒子之間的碰撞反應,比如把粒子從穿透狀態解開,計算摩擦力等等。
我們現在提供了多平臺的實現,而且D3D11 & D3D12版本和CUDA版本在效能表現上基本一致,同時保留了同一套API,所以使用方式和效能上基本沒有差別。同時我們將FleX以外掛的形式整合到了UE4中,預設使用的是D3D版本,當然也可以通過修改使用CUDA版本來加速。
相關連結:
ofollow,noindex">NVIDIA FleX https:// github.com/NVIDIAGameWo rks/FleX https:// github.com/NvPhysX/Unre alEngine/tree/FleX-4.19.2二、 FleX理論基礎PBD
上一篇文章 《電影工業中的流體模擬(七)----PCISPH》 介紹的方法屬於基於力的方法。這類方法通過計算內力(比如流體內部的粘性力和壓力)和外力(比如重力和碰撞力)的合力,然後根據牛頓第二定律計算出加速度,再根據數值積分求出速度和位置資訊。
這篇文章主要介紹一下基於位置的方法Position Based Dynamics (PBD)[1],這也是Nvidia FleX物理引擎的理論基礎。與基於力的方法先求解力再根據力的值進行數值積分不同,PBD先構建約束,然後通過對約束進行投影(constraint projection)得出位置資訊,並依此更新速度值。
為了對這兩個方法有個直觀認識,我們來看下面兩幅物體碰撞的求解示意圖[2]:

如果使用基於力的方法,在檢測到碰撞之後,需要計算由於物體穿透導致的碰撞力(使兩個發生穿透的物體分開),然後根據該力求解出速度和位置資訊。這種方法需要計算三個步驟(1)力(2)速度(3)位置才能最終更新物體位置,這樣一來就有明顯的反應延遲。另外一個更為明顯的問題是,計算碰撞力的時候需要選擇一個剛度(stiffness)引數(可以將紅色箭頭理解為彈簧,需要選擇合適的彈性係數以產生碰撞力將物體分開)。而剛度係數很難調,剛度值太小會導致物體穿透明顯,而剛度值太大則容易造成整個方程組呈現剛性,也就是說需要很小的步長才能對方程組進行準確的數值求解。( 注:剛度是材料力學中的名詞,定義為施力與所產生變形量的比值,表示材料或結構抵抗變形的能力[3]。剛度係數越高,物體越不容易發生形變;剛度係數越低,物體越容易發生形變。)
同樣的情況,我們看看PBD是怎麼處理的,如下圖:

在PBD方法中,當檢測到兩個物體發生穿透時,直接根據約束脩正物體位置,然後更新速度資訊。從這幅示意圖可以看出PBD提供了更多的控制靈活性,這一點對遊戲很重要。
下面來介紹經典PBD演算法:
在PBD方法中,動力學物體由 個頂點和
個約束組成。
頂點 的質量為
,位置為
,速度為
。
約束 Line"/> 有如下五種特性:
- 約束的基數為
,可以理解為第 個約束所影響的頂點數目為
。
- 約束為值為實數的函式,
。
- 約束索引值為
,
。
- 每個約束都有對應的剛度引數
。在PBD中,剛度引數可以理解為約束的強度。
- 約束分為等式約束
與不等式約束
。
PBD演算法:

演算法思路:
首先,對頂點位置,速度和質量倒數等進行初始化。這裡 設定為質量倒數,除了可以避免過多的除法操作以外,還可以處理靜態物體
(可以理解為質量無窮大)。我們把所有不能轉換為位置約束的力(比如重力)記為
,並根據
的值進行一次數值積分預測速度
。然後新增阻尼(damping),阻尼可以理解為物體在運動中發生能量耗散而導致速度衰減。所以可以在這裡直接對速度進行衰減操作模擬阻尼。計算完速度後我們再計算位置的預測值
。第(8)行主要是生成碰撞約束。物體會與周圍環境發生碰撞,比如布料落在地板上,流水碰上一面牆等等。這些碰撞約束每個時間步都在發生變化。有了內部約束(比如不可壓縮流體的密度約束)和外部約束(比如流體不能穿透地板)的數學公式之後,接下來,我們需要對這些約束進行迭代求解,也就是我們這裡的第(10)行約束投影步驟,得到校正後的粒子位置。然後,更新粒子位置和速度資訊。最後,在(16)行根據摩擦(friction)和恢復(restitution)係數修改速度(如下圖所示[2])。這樣,一個完整的PBD模擬步就算完成了。

三、約束和解算器 :
- 約束投影 :
設有一個基數為 的約束,關聯的點為 ,約束函式為
,剛度係數為 。用
表示這些點的位置組成的矩陣。則該約束可以表示為:
對約束函式 在其當前解
的鄰域內進行線性化操作(一階泰勒展開):
(1)
PBD方法的一個 絕妙之處 就是將 的方向限制在約束梯度
方向。為了更好的理解這一點,參見下圖[2]。約束
所涉及到的所有粒子的位置會形成一個高維空間,下圖為該空間中滿足不同約束條件的粒子位置形成的等值面的二維示意圖,在這裡為等值線(黑色曲線),當粒子位於該等值線上時滿足約束條件
。當粒子處於黑色點位置時,不滿足約束條件,如果我們沿著該點所在的等值線(灰色曲線)移動,此時剛體模態(Rigid body modes)的方向與該等值線相同,新得到的位置仍然在該等值線上,依然不在黑色曲線
上,即不滿足約束條件。這可以理解為,約束中存在的誤差依然沒有得到修正。拿兩個粒子形成的距離約束舉例,就好比同時移動了兩個粒子或者該約束繞自身旋轉,但是存在的誤差並沒有得到更正。而且這樣一來還會引入ghost force,這裡ghost force可以理解為本不該引入系統中的一種外力,導致系統動量不守恆。所以,我們希望該點的位移方向與剛體模態方向垂直,從而保證系統動量守恆,即從黑點指向紅點的方向(
的方向)。

因此令:
(2)
標量 可以看做拉格朗日乘子(Lagrange multiplier)。
可以保持動量(Linear momentum)和角動量(Angular momentum)守恆。
由公式(1)和(2)可得:
(3)
具體到粒子 ,約束投影后其對應的位移向量
(4)
其中,
(5)
我們可以看到 的值對於約束 作用範圍內的所有點都一樣。
前面我們考慮所有粒子質量都相同的情況,現在考慮粒子質量不同的情況。粒子 的質量為 ,則其質量倒數為
。則公式(2)變為:
公式(4)變為:
(6)
公式(5)變為:
(7)
2. 簡單約束舉例 :
我們拿最簡單的約束作為例子應用前面講到的約束投影方法,如下圖所示:

這裡,距離約束可以表示為 ,校正位移為
。根據約束投影方法,首先對約束函式
在點
和
處分別求梯度,得到:
上面求 可以這麼理解: 將
和
拆分成三個分量求解:
從而
應用公式(7)可得:
=
將 代入公式(6)可得位移
=
前面我們提到過每個約束都有對應的剛度係數 ,這裡我們用 去乘以
,這樣
次迭代之後誤差為
,與剛度係數 成線性關係,但與迭代次數
無關。則下一時間步的位置分別為:
3. Solver
PBD的輸入為 個約束和
個點的預測位置
,所需要求解的方程組為非線性非對稱方程組或不等式組(碰撞約束導致)。Solver的主要任務就是修正預測位置使新得到的校正位置值滿足所有約束。而在約束投影過程中,很難找到合適的
使得所有約束能夠同時得到滿足,所以我們通常採用迭代的方式依次對約束進行求解。
PBD中可以使用非線性高斯-賽德爾(Non-Linear Gauss-Seidel, NGS)迭代方法。Gauss-Seidel迭代方法[4]只能求解線性方程組,NGS 在依次對約束進行求解的基礎上,加入了約束求解這一非線性操作。與雅克比迭代方法(Jacobi method)[5]不同,NGS Solver在一次迭代中對於頂點位置的修正立即被應用到下一個約束求解,這帶來的好處就是顯著加快了收斂速度。
NGS雖然很穩定也容易實現,但是該方法收斂速度仍然不是特別快,而且取決於約束求解順序,且不宜並行化。在以後涉及到GPU並行化的時候會介紹更適合並行化的Solver。
4. 其他約束型別
除了距離約束,我們後續還會結合所模擬物體的型別分別介紹其他一些約束,包括:
模擬流體的密度約束(density)和表面張力(Surface Tension)約束。


模擬布料的拉伸/距離約束(Stretching)& 彎曲約束(Bending)& Long Range Attachments約束。


模擬剛體和軟體的形狀匹配約束(Shape Matching)。

模擬充氣體的體積約束(Volume Conservation)。

以及各種碰撞約束:Particle-Particle,Particle-Plane, Particle-Mesh(Triangle/Convex)。




四、總結 :
PBD採用幾何的方式,通過先建立約束再對約束進行投影的方式來直接計算出位置和速度。這裡的約束投影可以理解為通過數學公式計算出物體下一個時間步的位置,使之滿足給定的約束條件。(如下圖的例子[2]) 這裡和PCISPH方法一樣也是採用了預測-校正的思路。

儘管PBD方法不如基於力的方法精度高,但是PBD方法具有模擬穩定,允許大時間步長以及高度可控性等優點,非常適合用於遊戲物理引擎中模擬各種物理特效。
參考文獻:
[1] Müller, Matthias, et al. "Position based dynamics." Journal of Visual Communication and Image Representation 18.2 (2007): 109-118.
[2] Müller, Matthias, et al. "Real time physics: class notes." ACM SIGGRAPH 2008 classes. ACM, 2008.
[3] https:// zh.wikipedia.org/wiki/% E5%89%9B%E5%BA%A6
[4]Gauss-Seidel method