一、物理對象與形狀
1.1 對象 Actor
一般來說,游戲中的對象(Actor)分為以下四類:
- 靜態(tài)對象 Static Actor
- 動態(tài)對象 Dynamic Actor ---- 可能受到力/扭矩/沖量的影響
- 檢測器 Trigger
- Kinematic Actor 運動學對象 ---- 忽略物理法則,由游戲邏輯直接控制(可能表現(xiàn)的反物理)
1.2 形狀 Shape
由于真實世界中很多物體形狀極其復雜,所以游戲中會先設定較為簡單的對象。常見的物理對象的形狀有如下:
每一種形狀都有常用的實際游戲?qū)ο?,比如Height Fields用來做地形等。
當我們利用這些對象去組成實際需要的物體對象時,有兩個原則:
- 形狀接近就好,不一定要完美
- 簡單性。要盡量用簡單的對象去拼接(比如盡量少用三角網(wǎng)格),且越少越好。
此外,一些比較重要的物理概念:
- 質(zhì)量和密度 Mass and Density
- 質(zhì)心(做載具時很重要)Center of Mass
- 摩擦和恢復(彈性) Friction & Restitution
二、 力與運動
2.1 力 Forces
一般我們把力分成兩種:
- Force 可以理解為直接的重力、拉力、摩擦力等
- Impulse 沖量,比如說爆炸導致的沖擊力等(雖然其實沖量就是力x時間(恒力條件下))
2.2 運動 Movement
經(jīng)典的定理(游戲中需要用數(shù)學表示):
牛頓第一定律 無外力 —> 勻速直線運動
牛頓第二定律 F = ma (質(zhì)量的本質(zhì)是改變物體物理狀態(tài)的傾向性)
當這個力是恒力時:
當這個力是變力時:
其中上圖中 v ( t ′ )中的 t 是二次積分(位移和時間關(guān)系公式就是二次的)
具體以圓周運動為例,如果簡單去模擬物體隨時間變化,并不是很困難。
但實際游戲中時間不是連續(xù)的,而是由一幀幀實現(xiàn)的,所以通常需要解決的問題是在已知當前物體位置和速度的前提下獲取之后某時刻的物體位置和速度信息。
2.2.1 顯示歐拉法 Explicit (Forward) Euler’s Method
最簡單的估計方法,假設在這個時間片里力是恒定的
每一時刻仍按照傳統(tǒng)的牛頓力學方法去計算:
這種方法下,由于實際游戲中的時間片Δt不可能和現(xiàn)實中一樣小,所以會導致能量不守恒(變多)(如圖中右側(cè)所示,實際位移是偏多的),誤差越來越大,物體逐漸甩出去。
2.2.2 隱式歐拉法 Implicit (Backward) Euler’s Method
與顯示近似,不過將力的值和速度的值以未來(終點)為參考,如下圖:
其中未來的值是假設能夠通過解析解強行算出來的。
和顯示方法類似,該方法的問題是能量會衰減,但由于這個衰減相對較慢,所以用戶可能會認為是摩擦力、空氣阻力等其他力的影響導致,從而使得這個衰減在游戲?qū)嶋H中相對不明顯。
從另一個角度來說,我們在游戲引擎中設計中認為衰減肯定是好過增多的,前者頂多最后停下來,但后者會不可控會爆炸。
通過一系列復雜計算可以證明這種隱式方法是無條件穩(wěn)定的。
但其缺點是:
- 計算成本高(計算未來值)
- 運動非線性時難以計算
- 能量衰減。
2.2.3 半隱式歐拉法 Semi-implicit Euler’s Method
綜合前兩者的特點:
計算未來速度時用當前的力,計算未來位移時用未來的速度。
前提假設:力是不變的(很危險的假設,因為實際上力跟物體位置是相關(guān)的)。
優(yōu)點是:
- 條件性穩(wěn)定
- 計算簡單有效
- 隨著時間的推移能夠保存能量
缺點是:
- 做一些sin cos等運動時,積分出來的周期會比正確值長一點點,所以在相位上會有偏移差。
牛頓第三定律 F = -F’ (相互作用的兩個物體之間的作用力和反作用力總是大小相等,方向相反,作用在同一條直線上。)
三、 剛體動力學
前面所說的所有內(nèi)容都是把物體看作一個質(zhì)點的前提,然而事實上真實世界中大部分物體是有形狀的。
一般來說,我們在引入旋轉(zhuǎn)時大都針對剛體(因為柔體太難了),因為剛體就是假設物體的所有粒子之間綁定相對不動。
所以我們在剛體動力學中常常會比普通的線性計算(圖中右側(cè))多一些概念,同一行概念有對應性:
具體相關(guān)概念建議看視頻或講義。
動量守恒:在宇宙中任意一個位置做實驗的得到的結(jié)果是一樣的–空間一致性
角動量守恒:在一個位置的任意一個方向做的實驗得到的結(jié)果是一樣的–朝向一致性
課外拓展:諾特定理
四、 碰撞檢測
碰撞檢測一般分為兩個階段:
- Broad phase 初篩 – 利用AABB等找到剛體有沒有相交
- Narrow phase – 獲取進一步信息(碰撞點、方向、深度等)
4.1 Broad Phase
一般常見的有兩種方法:
BVH Tree – 更新成本低,適合動態(tài)場景。
Sort and Sweep – 先排序再逐個掃描,效率高,更符合大部分為靜態(tài)物體小部分為動態(tài)物體的現(xiàn)實。更好。
4.2 Narrow Phase
4.2.1 Basic Shape Intersection Test
比較簡單,把所有物體看作球或膠囊狀去判斷相交即可。
4.2.2 Minkowski Difference-based Methods
首先需要知道m(xù)inkowski Sum(閔可夫斯基和)的概念,以兩個三角形各自圍成的點集為例,兩個點集相加的結(jié)果是指所有A點集的點加上所有B點集的點,幾何表示如下:
拓展到兩個凸包也是一樣道理。
然后同理,還有minkowski Difference(閔可夫斯基差)
簡單講就是化A-B為A+(-B)。而-B是利用對原點的對稱獲得。
這樣一來就獲得了一個很重要的結(jié)論(方法):
如果兩個凸包有重疊,則它們的閔可夫斯基差必定包含原點
我們把閔可夫斯基差這些點形成的形狀叫slmplex(單純形)
由此問題轉(zhuǎn)換為了如何判斷兩個凸包的閔可夫斯基差包含原點。
具體可查看我的文章:多邊形碰撞檢測算法
4.2.3 Separating Axis Theorem
如果兩個物體分離,則肯定能找到空間中一根軸把它們分隔開,不然就是相交。
簡單做法是把凸包A的每條邊和凸包B的每條邊當分隔線試試,比如對凸包A的邊a,把所有頂點投影到這條邊上去進行判斷有沒有重疊。如果所有邊做分隔線都有重疊,那就是兩個凸包相交。
在這個基礎上,優(yōu)化方法是取凸包A的某條邊a做軸時,直接將凸包B的所有頂點投影到a的垂線上,因為這樣可以保證凸包A的所有頂點都在垂線上a的一側(cè),所以只需要判斷凸包B上所有頂點在垂線上的投影是否在另一側(cè)就行。
延伸到3D空間,需要多加步驟:
簡單講就是如果只判斷面的法線作為分隔線的可行性的話,會出現(xiàn)圖中下面前兩種情況,并誤以為是兩個物體相交,所以需要再加上一個檢測來判斷第三種情況。
五、碰撞解決
如果兩個物體發(fā)生了碰撞,并且相交了怎么辦?
最簡單的早期是方法是加一個與重疊反方向的penalty force,但是會導致物體突然分隔開,很假。
現(xiàn)在比較合適流行的方法是利用拉格朗日力學中對速度的約束的方法。簡單講大概類似于給碰撞物體加個沖量從而影響下速度,看是不是還碰撞,不斷重復直到可以接受?;蛘叩螖?shù)過多不管了。
六、 場景請求
6.1 Raycast
通過發(fā)射一條光來判斷場景中的某個點能否直接看到/射擊到。
當這束光有多個撞擊點時,有三種處理方式:
- 都進行計算處理、
- 只處理最近的、
- any hits(不管哪個,反正有撞擊就行)
6.2 Sweep
比如判斷人有沒有被擋住時是把人的整個膠囊體進行掃描判斷的,只要有一部分被擋住就是被擋住了。文章來源:http://www.zghlxwxcb.cn/news/detail-846042.html
6.3 Overlap
比如判斷手雷爆炸時能炸到哪些人。文章來源地址http://www.zghlxwxcb.cn/news/detail-846042.html
七、 效率、準確性與確定性
- Sleeping
物理引擎中常把場景的不同物品或部分分成所謂不同的island,而引擎設計中很重要的一部分是讓沒有變化或不需要參與計算的island進入sleep,所以如何讓更多island進入sleep從而減少計算量是一個關(guān)鍵問題。 - Continuous Collision Detection(CCD)
當一個快速運動的對象碰撞一個比較薄的物體時容易發(fā)生錯誤直接穿過去(因為前后兩次計算時發(fā)現(xiàn)都沒有碰撞,但其實不可以)
一種比較質(zhì)樸的方法就是把墻等物體做的厚一點。
更規(guī)范的做法就是CCD:先計算一個安全時間(在這個時間內(nèi)兩個物體不會碰撞),然后開始一點點詳細計算會不會碰撞,知道它們的距離小于一定閾值。 - Deterministic 確定性
游戲引擎設計時需要保證確定性,即同樣的代碼操作下跑起來是要盡可能一樣的,而不會受那么多復雜計算和浮點問題的影響導致不同(從而在Online Gaming)中出現(xiàn)兩方不一樣的問題。
到了這里,關(guān)于游戲引擎中的物理系統(tǒng)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!