用手機怎么看自己做的網(wǎng)站網(wǎng)頁設(shè)計大作業(yè)
一、 角色控制器
Character Controller和普通的動態(tài)對象(Dynamic Actor )是不同的,主要的三個特點是:
- 它擁有可控制的剛體間的交互
- 假設(shè)它是有無窮的摩擦力(可以站停在位置上),沒有彈性
- 加速和剎車幾乎立即改變方向并傳送
所以其實角色控制器其實是反物理的。
1.1 構(gòu)建一個控制器
首先,這是一個具有以下兩個特點的運動學(xué)對象(Kinematic Actor):
- 不受物理規(guī)則影響
- 對其他object可以產(chǎn)生力(交互)
形狀上,一般使用膠囊體,且一般有內(nèi)外兩層,內(nèi)層是實際的碰撞體,外層主要是防止對象與其他物體過近(從而避免高速運動下直接發(fā)生重疊的情況以及其他對象過近時相機視角出錯的問題)
1.2 角色控制器的特點和小細節(jié):
- Auto Slide 撞墻后自動沿著墻滑步
- Auto Stepping 爬樓梯要高度合適(跳太高反而會導(dǎo)致上頂很難設(shè)計)
- Max climb slopes 設(shè)置一個角度閾值,高于它時角色控制器應(yīng)該無法沖上去
- Force Sliding Down 在比較陡峭(小于上述閾值,因為上述是基于原本就有沖量的基礎(chǔ))的斜坡應(yīng)該要設(shè)置自動下滑
- Controller Volume Updata 簡單講就是游戲中角色隨狀態(tài)會改變它的體積(比如站蹲趴、變形等),所以會需要實時更新計算它的size,而在處理過程中,應(yīng)該在更新之前進行重疊測試,防止因為物理系統(tǒng)處理的比較快等原因?qū)е略趯嶋H上還不能改變到目標尺寸的時候就進行了更新
- Controller Push Objects 角色可以對其他動態(tài)物體施加力互動,往往以當時角色控制器的沖量進行計算
- Standing on Moving Platform 在這種情況下,一般在邏輯上把角色控制器和平臺物體綁定在一起(除非要進行更高標準精細計算的情況),來防止平臺移走角色下落的情況以及因為幀率問題導(dǎo)致的角色處在上下移動平臺上時不斷彈動的情況。
總的來說,角色控制器本身并不是多復(fù)雜的對象,但其擁有很多小細節(jié)和設(shè)計來模擬各種不同情況下的真實處理。
而作為引擎設(shè)計者,應(yīng)在設(shè)計角色控制器時留有較多的處理空間給開發(fā)者進行不同的細節(jié)設(shè)計。
二、 布娃娃系統(tǒng) Ragdoll
首先,為什么需要布娃娃系統(tǒng)?以一個簡單的例子說明:當一個角色被刺殺后需要播放對應(yīng)設(shè)計好的死亡動畫,由于實際游戲中情況復(fù)雜,如果不引入布娃娃系統(tǒng)的話會導(dǎo)致比如在懸崖邊死亡一半身體在外面的情況。而引入布娃娃系統(tǒng)就可以使其順勢掉落下去,合理很多。
具體來說,布娃娃系統(tǒng)就是利用了人物的joint和骨骼,一般設(shè)置的較粗略,最多也就十幾個joint,然后設(shè)計彼此之間的限制和關(guān)系,從而形成合理的轉(zhuǎn)變動作。
由于布娃娃系統(tǒng)的joint較少,并不覆蓋所有原生骨骼joint,所以如何用布娃娃系統(tǒng)的joint去驅(qū)動整套骨骼呢?
將joint分為三類:
- Active joints — 這些joint上布娃娃系統(tǒng)和原本骨骼重疊,所以只需要直接用原骨骼系統(tǒng)去進行變化即可
- Leaf joints — 在布娃娃系統(tǒng)joint盡頭未被覆蓋的joint,使其保持動畫設(shè)定的變化即可,跟著布娃娃系統(tǒng)盡頭的joint變化延伸
- Intermediate joints — 在兩個布娃娃系統(tǒng)joint之間的原生骨骼節(jié)點,一般使用插值均勻分到這些joint上進行限制性變化
另外,在實際游戲中,整個過程并不完全是由布娃娃系統(tǒng)進行,比如上述刺殺過程,一般是先進行對應(yīng)的動畫,當進行到一定情況時(比如快倒下時)交給物理系統(tǒng)進行判斷布娃娃的處理。
而在更多情況下,動畫和物理的區(qū)分并不像上述一樣清晰,而是直接互相融合,比如抱著一個小女孩跑步的過程,一方面小女孩自身擁有一定的晃動動畫,另一方面隨著整體位置的移動,動畫帶來的角色物理信息會一起輸入到物理系統(tǒng)去更新最終呈現(xiàn)出來的融合效果,使得避免動畫單純重復(fù)(只動畫)和小女孩亂晃(只物理/布娃娃)。
三、 衣料模擬
衣料模擬方面,游戲開發(fā)發(fā)展過程中出現(xiàn)過三個經(jīng)典方法,前兩個為:
基于動畫的衣料模擬 — Animation bone
把衣服當身體一樣進行動畫處理,在衣服上設(shè)置joint和骨骼,并進行相應(yīng)的插值處理。優(yōu)點在于便宜和可控(移動端),缺點在于不夠真實、和環(huán)境沒有交互以及設(shè)計上受限
基于剛體的衣料模擬 — Kinematic bone
像布娃娃系統(tǒng)一樣設(shè)置一些骨骼joint,利用物理系統(tǒng)去進行計算處理。優(yōu)點在于便宜和可交互,缺點在于質(zhì)量不可控、動畫師的工作量大、不魯棒以及需要高質(zhì)量物理系統(tǒng)參與
而我們的重點在于第三個衣料模擬方法:
3.1 基于mesh的衣料模擬
簡單講就是獲得物體的mesh,并對每一個頂點進行計算處理。而由于物理系統(tǒng)計算的昂貴,所以一般不會像渲染時一樣對每個頂點計算,而是相對稀疏。(少幾倍到十倍)
具體做法上細節(jié)如下(以人物身上的衣料為例(披風(fēng))):
首先,對每一個頂點要設(shè)置最大的移動半徑。一般來說,對離人物越近的頂點,最大移動半徑越小(比如脖子處基本不動),一方面更符合物理實際,另一方面可以減少穿模概率
在游戲開發(fā)者角度來說,需要設(shè)置衣料的物理屬性。以UE4為例,有如下屬性:
結(jié)合上渲染系統(tǒng),可以表現(xiàn)出不同材質(zhì)和物理情況的衣料。
3.2 基于Mass-Spring系統(tǒng)
而在引擎開發(fā)者角度,衣料的實現(xiàn)是基于一個Mass-Spring系統(tǒng)。
我們只能把衣料處理成許多彈簧質(zhì)點。針對每一個質(zhì)點,它會收到兩個力,一是彈簧彈力,與彈簧系數(shù)和位移大小有關(guān);另一個是所謂damping force,是一個衰減力,與damping系數(shù)和速度有關(guān)。如下圖:
這個衰減力主要是為了處理空氣阻力(每一個質(zhì)點代表的是實際的衣料上的一個小面,所以空氣阻力并不小)和能量爆炸問題(隨著迭代產(chǎn)生)
根據(jù)不同的需求和衣料特點,實際中如何設(shè)置彈簧質(zhì)點各有不同,以最標準的每個頂點之間一個彈簧為例進行詳細力的分析。取其中某個頂點為例進行受力分析:
其中,空氣阻力是受速度影響的,簡單計算就是速度乘以一個常量系數(shù)(雖然實際上應(yīng)該是速度平方)。
獲得加速度之后,可以直接利用Verlet公式進行計算下一幀的位置。
Verlet公式由上一課所提的半隱式歐拉法為基礎(chǔ)進行轉(zhuǎn)換得到,只需要利用上一幀位置和當前幀算出的加速度即可,成本低速度快。其另外一個值得注意的優(yōu)點是避免了速度的計算,從而避免了速度突變導(dǎo)致的位移不穩(wěn)定。
然而,現(xiàn)在最常用的是處理彈簧算法的方法是:Position Based Dynamics(PBD),其簡單思想是用拉格朗日力學(xué)替代傳統(tǒng)力學(xué)那一套,放棄“約束 - 力 - 速度 - 位置”的邏輯而把所有的力學(xué)關(guān)系描述成一套約束,并直接解出最后的位置,而不關(guān)心速度。
PBD在第六章會詳細介紹。
衣料的另一個問題是自碰撞問題,同一件衣服之間、不同件衣服之間的碰撞十分復(fù)雜,解決方案有四個:
- 單純把衣服變厚即可,這樣即使有一定穿模也不影響
- 使用很多substep去精細的處理物料間的碰撞
- 設(shè)置一個最大速度閾值,防止衣料之間穿模的過深,還能彈回來
- 第三點的進階,在衣料內(nèi)部設(shè)置一個反向的力場,當有其他衣料穿進來時對其施加反方向的力將其彈出。
四、 破壞模擬
破壞系統(tǒng)的制作大概分為如下步驟:
-
設(shè)計架構(gòu) Chunk Hierarchy。將完整未被破壞的物體自然分割成不同大小的塊并生成樹狀結(jié)構(gòu)進行描述它們的關(guān)系。
-
建立不同塊之間的聯(lián)系,此時是指同一層的不同塊之間的關(guān)系。設(shè)置它們聯(lián)系的緊密程度。實時更新。
-
對每一個聯(lián)系設(shè)置一個value值,表示當多大的力打到該部分時會打斷其間的聯(lián)系。其實也就是“硬度”。每次打擊后更新其值(比如不斷變小)。變成0時即斷開。
-
計算從沖量產(chǎn)生的傷害值 D = I / H 。I是指撞擊給的沖量,H是指剛體的材料硬度。
-
計算球體撞擊的傷害值D。結(jié)果分段,在比較小的范圍內(nèi)物體收到相同的完全的傷害,在最大傷害范圍外物體不受到傷害,在中間從內(nèi)到外插值不斷減小。
-
另外,當撞擊發(fā)生時,有沒有support graph也會影響結(jié)果
-
步驟1中所述自然分割怎么實現(xiàn)?— Voronoi Cell。簡單講就是在物體上隨機撒一些種子,每個種子不斷擴大直至撞到其他種子區(qū)域,當全部穩(wěn)定下來后就形成不同的塊。3維物體的切割也是類似。只是最后要用一個分割四面體的方法。
-
分割3維物體的一個難點是處理切割處的紋理問題,一般有兩種方式:1、直接制作對應(yīng)的三維紋理,切割時直接用(麻煩、貴)2、離線計算好這些紋理,一旦破碎則切換到對應(yīng)的紋理,(要瞬時處理)。簡而言之都很復(fù)雜。
-
另外,碎的方式也可以設(shè)計的不一樣,均勻的、隨機的、中心往外碎等等。
-
再另外,碰撞對應(yīng)的聲效、粒子效果等都會增加真實性。
五、 載具模擬
-
首先是形狀,由一個剛體構(gòu)成,還有一些彈簧等組件。
-
其次是動力(靜摩擦力)組成,如下圖:
由引擎扭矩經(jīng)過一系列操作獲得輪胎扭矩,再從而獲得摩擦力F。 -
懸掛力(Suspension Force)。輪胎是懸掛在車上的(利用彈簧),所以有一個隨著輪胎離車體距離形成的彈簧彈力。
-
輪胎力。分兩個:一是向前的縱向力,由向前的拉力(如上述)和反向的拉力和轉(zhuǎn)動阻力組成;二是橫向力(用于轉(zhuǎn)彎),是由滑動摩擦力和角度構(gòu)成。最終方向由兩個力的合力構(gòu)成。
-
重心也很影響車的設(shè)計和體驗。重心本身的計算就是兩輪之間重量的中心點;在跳躍、轉(zhuǎn)彎時重心靠前和靠后會發(fā)生不一樣的接過,一般來說,重心靠后會讓車更穩(wěn)定、轉(zhuǎn)彎時更容易轉(zhuǎn)大彎。
-
Weight Transfer。在實際駕駛中,汽車的重心是會發(fā)生變化的,主要是由驅(qū)動力產(chǎn)生(加速時靠后,減速時前移等)。
-
Steering angles 駕駛角度。當前面兩個輪胎轉(zhuǎn)動一樣角度時,靠外的輪胎會發(fā)生空轉(zhuǎn)。所以實際駕駛中兩個輪胎的轉(zhuǎn)動角度是不一樣的,具體是由輪胎到轉(zhuǎn)動圓的圓心的連線(半徑)的垂線(其實就是切線)決定。
-
Advanced Wheel Contact。比如在過減速帶時,如果簡單的進行raycast(當前輪胎被減速帶穿模過了就往上抬,否則下降),會出現(xiàn)穿模。實際處理中要用spherecast,將輪胎整體以圓的形式去判斷。
六、 高級:PBD與XPBD
6.1 PBD
拉格朗日力學(xué):不同于牛頓力學(xué)中提到的物體的運動會受到限制(比如能量守恒),拉格朗日力學(xué)的思路正好相反,它由這些限制可以得出物體的運動方式(由能量守恒可以推出牛一定律)。
從而把很多力學(xué)問題化成了求解約束的問題。
具體來講,以圓周運動為例:
其中X就是位置的向量。通過位置的約束和速度的約束可以反向得到運動的方式。
同理還有彈簧的約束:𝐶𝑠𝑡𝑟𝑒𝑡𝑐? (𝐱1,𝐱2) = ||𝐱1 ? 𝐱2|| ? 𝑑
總結(jié)下來,PBD就是一個迭代的不斷優(yōu)化約束狀態(tài)的過程(有點類似神經(jīng)網(wǎng)絡(luò)…),不需要計算速度等中間量,只需要讓每一個量都梯度變化,去優(yōu)化最終結(jié)果即可。一般停止迭代是要么當前約束誤差小于閾值、要么迭代次數(shù)達到一定量。
PBD也需要在最后結(jié)束迭代時加上一個damping項來防止爆炸。
可以參考PBD (Position Based Dynamics)
6.2 XPBD
在PBD基礎(chǔ)上加入stiffness參數(shù)來調(diào)節(jié)約束的軟硬程度,具體可以參考XPBD (Extended PBD)