GDC演講翻譯——看門狗2的載具同步
文章轉自Funny David的知乎專欄(文末可點選原文連結檢視),我根據自身理解對部分內容做了調整和優化。之前騰訊遊戲團隊也出過一篇講物理載具的文章《手遊中載具物理同步的實現方案》,基本的實現方式也是參考這個GDC分享。
下面是視訊連結,長按圖片識別二維碼開啟
以下是GDC演講分享的具體內容:
這是在GDC 2017上的一篇關於《看門狗2》中車輛系統同步的分享。
上來先放了一段視訊,描述Watch Dogs 2裡“混亂”的車輛碰撞情況。(0:19)
然後講了一下網路架構:沒有中心伺服器的P2P形式(狀態同步),支援4個玩家,有很多實體要去同步,而且這些實體屬於不同的分散式所有者。
文章中本地(Master)和複製方(replica)都是針對某個物件而言的。
假如有兩個客戶端,玩家A控制小車1,玩家B控制小車2。小車1在玩家A的客戶端上就是主控的,小車2在玩家A的客戶端上就是模擬的。同理,小車2在B客戶端上就是主控的,小車1在B客戶端上就是模擬的。
一、載具同步的難點分析
講車輛同步的困難
- 移動速度快,100ms的網路延遲就意味著2-3米的差異
- 存在碰撞,看門狗2的開放世界中有大量的交通工具,不僅限於玩家之間
- 人眼對於不規則的速度很敏感
涵蓋內容:
- 軌跡除錯工具
- 標準的技術:投影速度混合(有小調整)
- 基於快照快取的外插值和/或內插值
- 混合物理模擬來處理碰撞
- 未解決問題
- 未來研究方向
二、軌跡除錯工具
軌跡除錯工具是most important thing,所以放前面講,通過除錯工具可以看到物體移動的位置資訊。
綠色的軌跡是車輛經過的真實路徑,藍色的是通過dead reckoning(外插值)預測的路徑,紅色的點是做同步的快照點(即從主控端Master同步過來的準確位置)。
接著講最為標準的做法,就是投影速度混合(Projective Velocity Blending)。分享者說這個公式來自於wikipedia,追溯了下,最終來源是《Game Engine Gems 2》(遊戲引擎精粹)這本書中的一篇文章《Believable Dead Reckoning for Networked Games 》。
首先大前提是使用航位推測(Dead reckoning)法來做位置的同步預測:
航位推測法(英語:Dead reckoning,縮寫:DR)是一種利用現在物體位置及速度推定未來位置方向的航海技術,現已應用至許多交通技術層面,但容易受到誤差累積的影響。英語中“Dead”是從“deduced(推導)”轉化而來。這裡就理解成位置預測就行。
然後一個運動學狀態會(對應這裡的快照)包含位置、速度、加速度、朝向和角速度。最簡單的解決方案是基於線性物理的模擬:
這是高中物理的知識,但這裡有一個問題就是我們有兩個運動學狀態,當前模擬的位置和最近收到的真實位置。一種解決方法是通過在這兩個狀態之間建立一條曲線來進行模擬,另外一個技術就是分享者選擇的投影速度混合。
P0表示車輛所在位置,V0表示當前的速度,P0‘是上一個運動學狀態的位置,V0'是上一個執行學狀態的速度,Tt表示從T0開始經歷過的時間長度,而頭頂帶個尖的T表示歸一化之後的比例,即它是一個0-1之間的值。
這樣這裡的幾個公式就比較清晰了,先對速度做融合,然後使用融合後的速度計算位置Pt,注意這裡已經在使用A0'的加速了,接著計算根據收到的運動學狀態預算一個位置,最後根據歸一化之後的時間比例對兩個位置做差值融合。
跑出來的結果是這樣的:
可以看出,綠色的原始軌跡是一個圓形,而藍色的根據快照資料預測的結果是帶有比較強的鋸齒狀的,通過視訊可以看出車呈現出了很強烈的抖動。(5:30)
接著就講twist(轉彎)的內容了:
- 對正在轉彎的車輛使用直線進行外插值是不理想的;
- 新增了方向盤(或者說車輪)角度資訊
- 但是車輛的物理模擬很複雜
- 無法依據方向盤的角度準確預測轉向軌跡,因為雖然方向盤角度給出了車輛未來執行的方向,但是在物理世界中速度、地表材質等等因素都會影響結果。
- 傳輸了車輛的位置、速度和角速度
- 使用角速度中的水平朝向(yaw)值來預測轉向
- 對於漂移的車輛不管用,但是對於Watch Dog 2來說並不是個問題(因為不是個賽車遊戲=_=)
這樣就很圓了……(7:45)
四、基於快照快取的外插值和/或內插值?
接著說快照快取的使用部分:(8:53)
- 在最近的兩個快照中做內插值的做法
- 優勢是軌跡精準(因為等待主控的權威資料到來後才插值模擬)
- 劣勢是渲染物件軌跡其實是在模擬一段時間之前的狀態,比如圖中渲染的就是晚了5幀之前的狀態
這會帶來“在不同客戶端上因為位置不一致而導致結果不同”(A客戶端上發生了碰撞,但是B客戶端上沒有發生碰撞),所以下面要解決這個問題。
外插值和內插值的對比
- 我們不是一定要完全使用內插值
依然可以從上一個收到的快照進行外插值
- 引入一個“時間偏移”(TimeOffset)
- 我們渲染出來的這輛車在時間上晚了多久
- 檢查 當前時間 - 時間偏移
- 如果這個插值落在了兩個已經收到的快照時間之間的話,使用內插值
- 如果比最後收到的一個快照還要晚的話,使用外插值
- 快照要帶時間戳
這裡用視訊講解了具體效果,最好直接看視訊更直觀。(11:01)
時間偏移相關
- 選擇不是一件容易的事情
- 太多內插值導致錯誤的碰撞
- 太多外插值導致軌跡不連續
- 要找平衡
- 使用 平均度量延遲 + 常量值
- 減震
- 最多300ms
- 常量值範圍在100ms-200ms的區間
根據車輛速度成比例改變,當車輛以較慢的速度執行的時候,錯失碰撞的概率比較小,因此可以儘量使用內插值來做,這時候對應的就是增大時間偏移的值。
五、混合物理模擬來處理碰撞
這樣下來航位推測出來的軌跡就看著不錯了,現在我們讓車相撞看看
看視訊,車輛在相撞的時候會互相向後退,這和我們預期的不太一樣。(13:22)
相撞的車應當都停住,或者把對方推開的力量更小一些。但是遊戲裡面,兩邊的車輛都推到很遠的位置。
藉助網路工具幫助我們逐幀來看發生了什麼。
這裡是一段逐幀視訊,白色的車在這裡是第三方,它在黑車的客戶端上發生碰撞之後,因為它自身沒有開ragdoll(但其實有碰撞體),要等在它自己所在的客戶端把碰撞之後的位置資料同步過來之後才會後退(這個時候還處於外插值的狀態),於是它繼續往前走,就把當前客戶端用物理模擬(開了ragdoll)的那輛車給推到更遠的位置去了。在白車自己的客戶端上,黑車也有同樣的行為,因此兩輛車都產生了更大的碰撞後退效果,而實際上兩個車相撞不應該產生如此大的位移。(14:30)
如何解決?
- 把你推開的複製方(replica)並不知道碰撞的發生
他會保持前進的狀態直到一個新的包到達
- 這是一個無解的問題
因為沒有人有碰撞的完整決定權(因為網路框架是P2P的)
- 這時候很希望有個權威伺服器……
但是問題還是要處理,這時候就引入了物理模擬融合(Physics Simulation Blending),即在發生碰撞前開啟其他車的物理模擬(開啟ragdoll),然後在模擬位置與快照傳送的位置之間進行blend
- 無論我們是否喜歡,碰撞總會發生
- 給本地物理一個機會來模擬碰撞
- 然後融合回航位推測得出的軌跡
- 需要調校兩種速度之間的融合引數:
- 一種速度來自剛體模擬
- 一種速度要達到航位推測得到的位置
- 表現本地可信的一些效果,然後將碰撞考慮在內的情況下融合進快照。
關於Blend方案的問題:文中提到的"Physics Simulation Blending"是用本地模擬的與伺服器快照進行混合。而本地計算是先行的,收到的伺服器快照皆是過去的位置,所以混合的並不是同一時刻的位置,所以理論上可能會有一些不正常的情況(而且無法預測)。這裡的例子都是汽車相撞然後一段時間內趨於靜止,所以通常情況下沒什麼問題。
融合引數調整(不同階段調整物理模擬以及快照位置的權重)
- 通過播放多次碰撞選擇看上去表現好的融合引數,包括
- 在碰撞發生時融合比例的最大值
- 在結束之後以多快的速度回到完全的航位推測演算法中
圖中展現了對於自行車和汽車,恢復的時間長度是不同的,其中汽車較重,相對需要更長的時間。
效果已經不錯了哦,這塊要看視訊。雖然不完美,還是會有一些推開的情況,但是沒有之前那麼遠了。(19:10)
接下來說說進一步可能發生的問題——碰撞結果的不可預測性
- 本地模擬的碰撞在不同的客戶端上結果可能不同,比如兩輛車相撞,在兩個客戶端上一個可能被撞到了左側,一個被撞到了右側。
- 將複製品從本地碰撞模擬融合回航位推測軌跡的時候可能會比較“震撼”,來回抖動
- 使用的優化方法是當碰撞開始的時候,儘量將車輛放置到他們主機所在的位置
- 讓它們更可能得到一致的碰撞結果
其實由於看門狗2採用的帶有預測的狀態同步,所以誤差是無法避免的,在物理模擬的參與下更難保證一致性,只能通過快照來糾正錯誤資訊
如何做到讓在碰撞發生時將車輛放置到他們主機所在的位置呢?這裡就要做碰撞預測了。
- 在如下幾種情況會預測即將發生的碰撞並做外插值(通過調小時間偏移那個值)
- 不太能夠避開的情況,車輛要轉向畢竟是需要一個時間的,當兩輛車距離太過接近的時候,通過射線檢測之類的方式(我猜)來預測碰撞是否很可能要發生了。貌似這種效果並不是非常好,但是有任何一點可以改善的點都值得做。
- 使用AI系統中已經存在的碰撞預測演算法,這裡沒講演算法細節。
六、未解決的同步問題
一些沒解決的問題,其實有更多,這裡只列舉一部分。
- 和靜態網格的碰撞
- 時間偏移差異
- 恐怖谷效應
靜態碰撞的問題:
這塊看視訊更直觀,真正的快照目標點在樹的左側,而碰撞模擬到了右側,由於中間有一顆樹的遮擋,這時候需要融合過來就很奇怪。(視訊中可以看到劇烈的抖動,火花四射,然後一點點滑過去)(22:35)
- 靜態物體不會讓路
- 樹是最壞的一種情況
- 一些選擇:
- 保持當前位置
- 軟物理碰撞
- 最終直接傳送,雖然效果不好,但是在一些特定情況下還是需要的。
- 消除抖動是最為重要的部分
他們最終的做法是如果發現你被擋住了,但是又無法移動到目標位置,就讓你保持當前位置的,等有之後新的位置同步之後再處理。
不同的時間偏移:
- 人物角色比較傾向於內插值(速度慢)
不同的時間偏移導致了在不同客戶端上的碰撞效果不同,左側的圖車完全沒碰到人,右側的把人撞飛了。分享者說這塊可以基於前面碰撞預測的同樣思路來解決或者優化
- 對於可破壞物有同樣的問題,但是對於玩法的影響比較小。
恐怖谷效應:
- 運動軌跡已經正確了,但是依然感覺不好
- 輕微的搖擺效果在複製方(遠端)丟失了
- 車不能圍著它們的重心旋轉
- 人眼對於甚至很微小的不連貫現象都很敏感
- 應用一些後處理平滑
- 平滑速度和角速度,而不是位置和旋轉
- 需要和投影速度融合共存,它在航位預測之上,因為航位預測法雖然希望給出一個平滑的曲線過渡,但是在實際結果中可能並不是這樣,還是會有位置和速度上的突變。雖然加這個有點髒,但是效果好,管他呢。=_=
七、未來的研究方向
- 調引數太難了,希望用機器學習的方法讓AI來調
- 平滑演算法
卡爾曼濾波(Kalman filter)
卡爾曼濾波(Kalman filter)是一種高效的自迴歸濾波器,它能在存在諸多不確定性情況的組合資訊中估計動態系統的狀態,是一種強大的、通用性極強的工具。
https://zhuanlan.zhihu.com/p/39912633
最後強調偵錯程式的重要性,然後說雖然在這個過程中做了很多數學工作,是科學性的,但是依然有很多內容是需要從藝術/美術的視角去思考和改進的,畢竟要做到的最終結果是讓玩家feeling good。(其實這個偵錯程式本質是一個回放工具,需要把每一幀當前所有的物件位置以及行為資訊都記錄下來,方便後面做除錯)
八、問答
問題:第一個問題關於timehop(跳時)的,如果某輛汽車在執行時切換了控制權(比如玩家A中途掉線,AI計算由客戶端A切換到客戶端B)如何處理這個跳時造成的問題?
回答:這個時候一般你會知道當前的汽車執行情況,比如車是沿著直線開的時候,就減速等著新的控制端計算位置逐漸追上去。
問題:車輛在爬坡之類的情況下的顛簸在同步方怎麼表現,會限制外插值在一個平面麼?
回答:一個解決方案是用物理模擬Z軸的變化,然後在車離地面比較近的情況下Z方向上不要外插值,但是比如飛躍到空中的時候還是需要切換到航位預測法來預測落點位置。
問題:似乎是在討論是否有必要區分不同的物理物件,決定是否使用物理或者調整同步方式?
回答:其實在遊戲裡面是有區分的,比如自行車和汽車的物理模擬融合時的權重計算曲線不同。
來源:遊戲開發那些事
原文:https://mp.weixin.qq.com/s/WMLWEVnBwWVaGwwP1mH8XA
相關文章
- 十五、WDG看門狗
- iOS 的看門狗機制iOS
- 【GDC2023首日】開門紅!四場雷火UX演講來了!UX
- 【GDC演講】互動敘事:《Florence》製作回顧
- GDC暴雪演講:如何設計遊戲裡的獎勵系統?遊戲
- [翻譯]理解非同步JavaScript非同步JavaScript
- shell實戰之tomcat看門狗Tomcat
- MCU看門狗使用注意事項
- Retrofit 2 0非常簡單的入門(翻譯官方文件)
- 陳星漢GDC演講:《光·遇》如何鼓勵玩家互愛互助?
- Xilinx-ZYNQ7000系列-學習筆記(2):私有看門狗(AWDT)的使用筆記
- Redisson的看門狗機制底層實現Redis
- ArkUI中的執行緒和看門狗機制UI執行緒
- AURIX TC397 SCU 之 Watchdog 看門狗
- Redisson 分散式鎖原始碼 02:看門狗Redis分散式原始碼
- 蝴蝶書-task2: 文字推理、摘要、糾錯 transformers實現翻譯 OpenAI翻譯 PyDeepLX翻譯 DeepLpro翻譯ORMOpenAI
- docker官方文件翻譯2Docker
- rabbitmq 官方文件翻譯-2MQ
- 關於看門狗的兩種模型以及帶來的思考模型
- [非專業翻譯] Mapster - 非同步支援非同步
- 米哈遊CEO蔡浩宇GDC演講:《原神》如何打造動人的開放世界?
- 網易GDC2022演講實錄:《永劫無間》的UX設計——從原型到成品UX原型
- 我為什麼會玩《看門狗:軍團》
- [譯]Python中的非同步IO:一個完整的演練Python非同步
- [翻譯] Go 語言入門Go
- 演講的技巧
- 網易雷火UX在GDC演講:大資料視角下的多人線上開服策略UX大資料
- Electron教程翻譯2:安裝
- 學php之翻譯wordpress(2)PHP
- 4.看門狗、定時器、觸控電容定時器
- 手遊中載具物理同步的實現方案
- win10系統玩看門狗軍團閃退怎麼辦 win10玩看門狗軍團閃退如何處理Win10
- Serilog文件翻譯系列(一) - 入門指南
- Gradle入門(翻譯自Graddle官網)Gradle
- 騰訊互動翻譯的坑爹翻譯
- C# 10分鐘完成百度翻譯(機器翻譯)——入門篇C#
- 翻譯 | Learning React Without Using React Part 2React
- 2006考研閱讀Text2翻譯