网络游戏之快照插值物理模拟
筆者介紹:姜雪偉,IT公司技術合伙人,IT高級講師,CSDN社區專家,特邀編輯,暢銷書作者,已出版書籍:《手把手教你架構3D游戲引擎》電子工業出版社和《Unity3D實戰核心技術詳解》電子工業出版社等。
CSDN視頻網址:http://edu.csdn.net/lecturer/144
我們使用幀同步網絡物理模擬, 現在,在這篇文章中,我們將使用完全不同的技術對相同的仿真進行網絡連接:快照插值。
隨著玩家數量的增加,幀同步驟變得有問題:您無法模擬幀n,直到您從所有玩家接收到該幀的輸入,所以玩家
最終等待最落后的玩家。 因此,我至多為2-4名玩家推薦幀同步技術,這也是幀同步廣泛應用于競技游戲的原因。
所以如果你的模擬不是確定性的,或者你想要更高的玩家數量,那么你需要一種不同的技術。 快照插值適非常適合。
在許多方面與幀同步相反:幀同步運行兩個模擬,一個在左邊和一個在右邊,并使用同步輸入保持它們同步,快照插值不運行任何模擬 右邊一切!快照
插值不運行任何模擬右邊一切!
相反,我們從左側的仿真中捕獲所有相關狀態的快照,并將其傳輸到右側,然后在右側,我們使用這些快照重建模擬
的視覺近似,所有這些都不運行模擬本身。讓我們發送渲染每個立方體所需的狀態:
struct CubeState{bool interacting;vec3f position;quat4f orientation;}; 現在我已經確定,這項技術的成本增加了帶寬使用。 大幅增加帶寬使用率。 由于快照包含整個模擬的視覺狀態,
有了一些數學,我們可以看到每個立方體可以串行化到225位或28.1字節。 由于在我們的模擬中有900個立方體,
這意味著每個快照大概是25千字節。
當我們以分組的形式發送快照數據時,我們在頂部包含一個16位序列號。 該序列號從零開始,并隨著發送的每
個分組而增加。 我們在接收時使用此序列號來確定數據包中的快照是否比接收的最近快照更新或更早。 如果它更老,
那么它被丟棄。
每幀我們只是渲染右邊收到的最新快照:
仔細觀察,即使我們盡快發送數據(每幀一個數據包),您仍然可以看到右側的掛起。 這是因為互聯網不能保證每秒發送60次
的數據包相當于1/60秒的間隔。 數據包抖動。 一些幀您收到兩個快照數據包。 其他幀你沒有收到。
這實際上是一個很常見的事情,當你第一次開始網絡。 您開始在局域網上玩游戲,并注意到您可以快速地砰擊包(60pps),
并且大部分時間您的游戲看起來很棒,因為在LAN上,這些數據包實際上往往以與他們發送的相同速率達到.。
首先,我們來看看我們用這種天真的方法發送多少帶寬。 每個數據包是25312.5字節加上28個字節的IP + UDP頭和2個字節的
序列號。 每個數據包為25342.5字節,每秒60個數據包,總共每秒1520550字節或11.6兆比特/秒。 現在肯定有互聯網連接,可以支
持這么多的流量...但是,老實說,我們并沒有真正得到很多好處爆炸數據包每秒60秒,所有的抖動,讓我們拉回來 每秒只發送10
個快照:
你可以看到 在右邊沒那么好,但是至少我們已經將帶寬降低了6到2兆比特/秒。 我們肯定是朝著正確的
方向前進。
現在用快照的技巧。 我們所做的是,不是立即呈現接收的快照數據,就是我們在內插緩沖區中緩沖快照
時間短。 此插值緩沖區會持續快照一段時間,以便您不僅具有要呈現的快照,而且從統計學角度來看,您也
很可能擁有下一個快照。 然后,隨著右側時間的推移,我們在兩個稍微延遲的快照之間插入位置和方向,提
供平滑運動的幻覺。 實際上,我們已經為平滑度交易了少量的延遲。
您可能會驚訝于使用線性插值10pps看起來有多好:
現在我們要處理丟包了,我確定你可以看到為什么我們永遠不會考慮通過TCP發送快照。
快照時間是關鍵的,但不同于幀同步快照中的輸入不需要可靠, 如果快照丟失,我們可以跳過它,
并插入內插緩沖區中的更新的快照, 我們不想停止,等待丟失的快照包被重新發送。 這就是為什么你應該始終
使用UDP發送快照。
上述的線性和高音插值畫面不僅以每秒10包的發送速率記錄,而且還記錄在5%的分組丟失,+/- 2幀的抖動(60fps)。
如何處理這些視頻的數據包丟失和抖動是通過簡單地確保在插值之前在插值緩沖區中保存適當時間的快照。
我的經驗法則是內插緩沖區應該有足夠的延遲,這樣我可以連續丟失兩個數據包,并且仍然有一些插值。 實際上,
我發現在2-5%數據包丟失時效果最佳的延遲量是數據包發送速率的3倍。 每秒10個數據包,這是300ms。 我還需要一些
額外的延遲來處理抖動,在我的經驗中,通常只有一個或兩個幀(60fps),所以上面的插值視頻以350ms的延遲被記錄。
添加350毫秒延遲似乎很多, 但是每次數據包丟失時,您最終會掛起1/10秒。 人們
經常用來隱藏內插緩沖區在其他區域(如FPS,飛行模擬器,賽車游戲等)中添加的延遲的一種技術是使用外推法。 但是
根據經驗,外推對于剛體是不正常的,因為它們的動作是非線性的和不可預測的。 在這里,您可以看到200ms的外推,
將總時延從350 ms縮短到僅150ms:
外推對物理模擬不了解, 外推不知道與地板的碰撞,所以立方體可以向下推出地板,然后彈回來糾正。
預測不知道彈簧力將玩家立方體放在空中,所以立方體最初向上移動比它應該更慢,并且必須抓住。 它也不知道
任何關于碰撞和碰撞反應如何工作,所以立方體滾動在地板和其他立方體也是錯誤的。 最后,如果你看到球,
你將會看到,外推可以預測所附立方體當它們與播放器立方體一起旋轉時,沿其切線速度繼續移動。
您可以想象,花費大量的時間來提高這種外推的質量,并使其了解立方體的各種運動模式。 您可以采取每個立方體,
并確保至少多維數據集不會通過地板。 您可以使用多邊形之間的邊界球添加一些近似碰撞檢測或響應。 你甚至可以把這
個立方體放在卡塔馬里的球中,使他們預測運動與玩家立方體一起旋轉。
但是,即使你做了這一切,仍然會有錯誤的預測,因為你根本無法準確地匹配物理模擬和近似值。 如果您的模擬主要
是線性運動,例如。 快速移動的飛機,船只,太空船 - 你可能會發現一個簡單的外推在短時間內(50-250ms左右)工作得很好,
但是根據經驗,一旦物體開始與其他非固定物體碰撞,外推開始 分解。
我們如何減少內插的延遲量? 350ms仍然是不可接受的,我們不能使用外推來減少這種延遲,而不增加大量的不準確性。
解決方案很簡單:增加發送速率! 如果我們每秒發送30個快照,我們可以獲得相同數量的丟包保護,延遲150ms。 每秒60個
數據包只需85ms。
總結
以上是生活随笔為你收集整理的网络游戏之快照插值物理模拟的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 进程和套接字
- 下一篇: openstack使用1——window