Unity 3D定點數(shù)物理引擎實戰(zhàn)系列1.1BEPUphysicsint 3D定點數(shù)物理引擎介紹
1.1BEPUphysicsint 3D定點數(shù)物理引擎介紹
幀同步的游戲中如果用物理引擎,為了保證不同設備上的結(jié)果一致,需要采用定點數(shù)來計算迭代游戲過程中的物理運算。也就是我們通常說的定點數(shù)物理引擎(確定性物理引擎)。本系列教程給大家詳細的講解如何在你的項目中內(nèi)置一個確定性物理引擎。確定性物理引擎我們使用github上開源的物理引擎BEPUphysicsint v1庫。本節(jié)內(nèi)容主要有:
定點數(shù)計算的原理與優(yōu)缺點;
BEPUphysicsint v1的由來;
BEPUphysicsint v1項目的github地址:
https://github.com/sam-vdp/bepuphysics1int
定點數(shù)計算的原理與優(yōu)缺點
首先來給第一次接觸定點數(shù)的開發(fā)者介紹一下定點數(shù)計算的基本原理。定點數(shù)計算的原理很簡單, 例如: 1.2 * 1.2, 我們用整數(shù)來模擬小數(shù),原理就是確定一個精度,把小數(shù)的小數(shù)部分放大, 比如1.2, 我們確定精度為在10進制下精確到小數(shù)點后1位, 那么1.2對應的定點數(shù)為12, (定點數(shù)是對應的小數(shù)擴大10倍后取整), 如果確定精度是小數(shù)點后2位,那么1.2對應的定點數(shù)位120(定點數(shù)是對應的小數(shù)擴大100倍)。我們都知道計算機是二進制的,一個int在32位的機器上, 為32bit, 最高位表示的是符號位,剩下的是31位, 31位中多少表示小數(shù)位,就代表定點數(shù)的精度。比如 8個bit表示小數(shù)部分的精度,那么這個定點數(shù)就擴大了2^8。所以1.2變成定點數(shù)就是 int (1.2 * 256 = 307.2 整數(shù)化后就為307)。
32bit位: 1111 1111 1111 1111 1111 1111 1111 1111, 當你把精度定在哪個bit位,就相當于把小數(shù)點定在了多少位, 如上面, 小數(shù)點定在了8bit地方, 1111 1111 1111 1111 1111 1111 . 1111 1111所以叫做”定點數(shù)”。通過擴大倍數(shù),把小數(shù)部分按照特定的精度變成了整數(shù),后續(xù)都基于整數(shù)來進行運算。如果我們的物理引擎使用定點數(shù)計算,最后雖然將定點數(shù)轉(zhuǎn)化為Unity Transform的相關(guān)浮點數(shù)顯示物體位置,但是最終在決定物理碰撞,游戲事件中, 物理移動中都是定點數(shù)化后的整數(shù)運行,所以這樣就做到了物理引擎迭代的確定性。做到了不同機器上跑物理引擎模擬,結(jié)果一致。
搞懂了原理后,我們來看下定點數(shù)的加,減,乘,除的模擬,以上述小數(shù)點后一位小數(shù)為例(擴大10倍):
加法:?直接讓兩個定點數(shù)相加即可, 1.2 + 1.2 = 2.4, 12 + 12 = 24
減法:?直接上兩個定點數(shù)相減即可, 1.2 – 1.4 = -0.2 12 – 14 = -2;
乘法:?兩個定點數(shù)相乘相當于多擴大了一倍,最后再除以精度倍數(shù)
1.2 * 1.2 = 1.44 12 * 12 = 144 / 10 = 14
除法:兩個定點數(shù)的除法,分子,分母都擴大10倍,結(jié)果相當于沒有擴大, 我們可以先把分子再繼續(xù)擴大十倍,然后再除以分母。也可以把分母縮小10倍再計算(有很多種處理方式)。一般做除法,我們會把分子擴大10倍,再除以分母。1.4 / 1.2 = 1.166 定點數(shù): 14 * 10 / 12 = 11,表示的結(jié)果為1.1,也是精確到小數(shù)點后1位。
搞懂了上述的計算過程后,我們知道定點數(shù)的優(yōu)點就是都是基于整數(shù)計算,結(jié)果確定,在沒有浮點運算器的CPU下計算性能好。接下來分析下定點數(shù)計算的缺點,就是定點數(shù)在做乘法?or?除法的時候容易溢出。我們拿乘法為例,假設32 bit的整數(shù),16bit作為小數(shù)部分,那么就是 15.16的定點數(shù)(最高表示符號,15個bit表示整數(shù)部分,16bit表示小數(shù)部分),如果兩個數(shù)相乘,很大的概率就溢出了(計算結(jié)果超過32bit)。如2^20與2^21兩個定點數(shù)相乘為: (2^20 * 2^21)?/ (2^16) =?2^41?/ 2^16, 計算分子相乘的時候得2^41次,在32bit的int存儲中就溢出了。而2^20與2^21都是合法的定點數(shù)。
BEPUphysicsint v1的由來
在github中有一個開源的3D物理引擎的項目,叫做BEPUphysics, 它分成了v1, v2兩個重大版本的分支如圖1.1-1:

圖1.1-1
BEPUphysicsint v1 開源項目是將BEPUphysics v1的代碼中的浮點運算用定點數(shù)來代替而fork出的一個分支。BEPUphysicsint v1與BEPUphysics v1使用方式上基本都是一致的,只是內(nèi)部采用的是定點與浮點的區(qū)別。在BEPUphysicsint這個項目中,采用定點數(shù),所以精度很有限,無法達到浮點的精度,而且經(jīng)常容易溢出,所以它有一個要求,物理世界中x, y, z每個軸的范圍在1000的范圍內(nèi)。BEPUphysicsint?定點數(shù)物理引擎的性能要比BEPUphysics float版本的性能要差4倍左右。以后可能差距沒有那么大,但是定點數(shù)版本的要比浮點數(shù)版本的性能差。如圖1.1-2:

圖1.1-2 官方關(guān)于性能與精度的介紹
如果在實際的項目中發(fā)現(xiàn)性能問題,也可以自己實現(xiàn)物理引擎或者基于自己項目實現(xiàn)一個閹割版的高性能物理引擎。
今天的分享就到這里了, 關(guān)注我們, 接下來還會繼續(xù)更新定點3D物理引擎系列教程。
更多教學資料:https://bycwedu.vipwan.cn/promotion_channels/829468798? ?