<bdo id="ks4iu"><del id="ks4iu"></del></bdo>
  • 
    <pre id="ks4iu"></pre>
  • <bdo id="ks4iu"><del id="ks4iu"></del></bdo>
    <input id="ks4iu"><em id="ks4iu"></em></input>
    
    
  • <center id="ks4iu"><cite id="ks4iu"></cite></center>
  • 首頁 > 智能影音 >

    網(wǎng)易互娛引擎部技術(shù)專家:這個技術(shù)能實現(xiàn)更復(fù)雜的交互,但入局者尚少

    4月18日至4月21日,由網(wǎng)易互娛學(xué)習(xí)發(fā)展舉辦的2022N.GAME游戲開發(fā)者峰會在線上舉辦。在19號的峰會上,來自網(wǎng)易互娛引擎部的技術(shù)專家許飛,以《構(gòu)建公平的聯(lián)機環(huán)境,服務(wù)器動畫性能優(yōu)化》為主題發(fā)表了演講。

    許飛提到,雖然現(xiàn)在真正使用服務(wù)器動畫的游戲并不多,但這是一個比較有前景的領(lǐng)域,因為可以提供更公平的聯(lián)機環(huán)境,而且可以實現(xiàn)更細致的交互。比如服務(wù)器一旦有了動畫之后,服務(wù)器的角色就是活的,不再只是一堆數(shù)據(jù),它有姿態(tài),可以進行更復(fù)雜的交互。

    我們現(xiàn)在提倡的云游戲也好,元宇宙也好,很難想象里面的東西是沒有動畫的。

    以下是演講全文(有刪減):

    大家好,我是來自網(wǎng)易互娛技術(shù)中心的許飛,很榮幸參加網(wǎng)易N.GAME游戲開發(fā)者峰會。本次分享的題目是《構(gòu)建公平的聯(lián)機環(huán)境,服務(wù)器動畫性能優(yōu)化》,分為四個部分:

    第一部分:服務(wù)器動畫的意義和現(xiàn)狀

    第二部分:服務(wù)器動畫常見優(yōu)化方向與方案

    第三部分:如何優(yōu)化復(fù)雜的動畫狀態(tài)機

    第四部分:服務(wù)器動畫展望

    服務(wù)器需要跑動畫嗎?

    在座很多有經(jīng)驗的開發(fā)者可能會有疑問,服務(wù)器需要跑動畫嗎?因為現(xiàn)在大多數(shù)游戲服務(wù)器是沒有跑動畫的。傳統(tǒng)觀點認為,動畫和渲染特效一樣,屬于表現(xiàn)的層次,只要客戶端看就可以了。

    有限的幾種需要動畫來參與的邏輯,比如打擊部位的判定,服務(wù)器不跑,但客戶端還是有動畫的。我們讓客戶端來進行判斷,然后把結(jié)果發(fā)送給服務(wù)端,也能實現(xiàn)一樣的效果。這種想法是正確的,也是以前常見的做法,但有個前提——你網(wǎng)絡(luò)必須是可信任的。

    但我們實際的網(wǎng)絡(luò)環(huán)境是什么樣的?

    下圖是Peter Steiner在1993年發(fā)布于紐約客上的一副圖畫,被認為揭示了互聯(lián)網(wǎng)環(huán)境的復(fù)雜性。互聯(lián)網(wǎng)環(huán)境非常繽紛多彩,這種多彩一方面給網(wǎng)絡(luò)游戲的發(fā)展提供了肥沃的土壤,另一方面,它的復(fù)雜性也給游戲開發(fā)者造成了很大的挑戰(zhàn)。

    比如,我們其實并不關(guān)心玩家究竟是什么背景,有什么特點,但我們害怕的是玩家用不用外掛。對于一個交手型的游戲來說,一旦使用外掛,對游戲公平性的破壞幾乎是毀滅性的。

    有沒有一種辦法能夠有效地防止或反外掛呢?一個有效的方法叫做服務(wù)器權(quán)威。

    它的思路其實很簡單,外掛是通過劫持游戲客戶端來實現(xiàn)一些非法操作,但相對于玩家的客戶端來講,我們的服務(wù)器是在機房里,機房經(jīng)過非常嚴密的保護,一般的外掛開發(fā)者很難劫持我們的服務(wù)器。

    但如果把關(guān)鍵的邏輯都放在服務(wù)器上面,客戶端僅僅作為一個指令的輸入者,我們就可以防止大部分外掛的操作。

    這個方法只要把客戶端邏輯搬到服務(wù)器就好,很簡單,但為什么現(xiàn)在大多數(shù)游戲沒有這么做呢?

    現(xiàn)實總是比較復(fù)雜。

    看下圖,這是游戲不同系統(tǒng)開銷的展示,橫坐標是游戲某個系統(tǒng)數(shù)據(jù)量的多少,縱坐標是屬性更新頻率。像等級、裝備這些信息,數(shù)據(jù)量相對比較少,更新頻率也相對比較低。像技能或狀態(tài)之類,更新頻率相對高,數(shù)據(jù)量也會相對大。

    很早期的服務(wù)器,其實只會保存等級信息之類的,后來發(fā)展了一段時間之后,就開始保存裝備信息、技能信息。

    動畫在紅色的位置,具有非常龐大的數(shù)據(jù)量和非常高的更新頻率,這兩個軸相乘的結(jié)果才是某個功能對于算力的需求,可想而知動畫對于算力的要求是非常高的。

    如果我們簡單地把動畫從客戶端挪到服務(wù)器,在沒有優(yōu)化的情況下,會導(dǎo)致服務(wù)器直接跑不起來。

    這就是現(xiàn)實,也是為什么很多游戲沒有在服務(wù)器開啟動畫。

    還有人說,隨著技術(shù)的發(fā)展,算力的價格其實在下降,CPU越來越強大,核數(shù)越來越多,技術(shù)的發(fā)展會不會讓服務(wù)器的動畫變得可能呢?

    我收集了三個比較典型的年代:2007年、2016年和2020年,服務(wù)器每條線程成本的變化。這三年剛好也是三款典型射擊游戲的發(fā)布年代。

    從2007年到2016年,CPU單線程的成本大概降到了原來的1/3;從2016年到2020年,更是降到了原來的1/2。

    2007年發(fā)布的《穿越火線》,服務(wù)器幾乎沒有跑任何動畫相關(guān)的東西。2016年的《守望先鋒》,它的服務(wù)器是知道動畫狀態(tài)的,但是只跑了一部分。什么意思呢?服務(wù)器知道這個角色,當前是跑還是跳還是釋放技能。

    到了2020年發(fā)布的《Volarant》,它的服務(wù)器是完全跑動畫的,會完全計算角色在服務(wù)器上的狀態(tài)。他們的主程在分享中也說道,這樣做就是為了反外掛。因為服務(wù)器只有有了非常全面的動畫信息,在判定受擊的時候,才不至于被客戶端的外掛所欺騙。

    所以可以看到,隨著技術(shù)發(fā)展,服務(wù)器動畫的邏輯執(zhí)行程度是越來越高的,最近一些游戲已經(jīng)開始嘗試在服務(wù)器上跑動畫了。

    業(yè)界有哪些常用的服務(wù)器動畫優(yōu)化方案?

    既然要在服務(wù)器跑動畫,那我們就要優(yōu)化它的動畫開銷。業(yè)界常用的方法有哪些呢?

    首先我們分析一下,動畫系統(tǒng)的開銷,大概分成三個部分:系統(tǒng)接收外界的輸入,更新內(nèi)部狀態(tài),最后計算出模型的姿態(tài)。

    輸入部分,一般就是角色速度或者說角色狀態(tài),比如在做什么。內(nèi)部狀態(tài),比如角色的速度變化,可能從一個靜止的狀態(tài)變成跑的狀態(tài),或者從跑到跳這樣的變化,最后再由這些狀態(tài)計算出我的姿態(tài)——姿態(tài)就是從美術(shù)Key幀里面算出角色最終的樣子。

    這三部分的開銷我覺得很明顯:姿態(tài)更新部分的開銷最大。

    正如上文所說,我們評價一個功能開銷,可以從它的數(shù)據(jù)量和頻率兩方面來計算,姿態(tài)更新為什么數(shù)據(jù)量非常大,因為每個人骨骼都有朝向、旋轉(zhuǎn)和位置眾多的屬性,而且?guī)缀趺繋家兓宰藨B(tài)更新占比這么多其實并不意外,我們業(yè)界常見的優(yōu)化方式也正是針對這一塊進行的。

    比如最簡單的LOD,主要是減少了動畫的數(shù)據(jù)量。服務(wù)器跑動畫是為了來判斷受擊,但有些客戶端用來表現(xiàn)的一些骨骼是不需要的,比如披風(fēng)、頭發(fā),對于判斷毫無作用,那么服務(wù)器就可以不跑,把這些剪掉就可以了。這就是服務(wù)器LOD的一種思路、一種做法。

    像下圖里面紅色框里的骨骼,對于服務(wù)器判斷受擊是沒有任何作用的,把它給去掉,一般可以省20-30%的開銷。

    除了減少數(shù)據(jù)量之外,還可以減少數(shù)據(jù)的更新頻率。

    基于事件的姿態(tài)更新,也就是減少姿態(tài)計算的頻率。《Volarant》的技術(shù)就是這樣子。一個角色只有當被擊中的那一瞬間,才需要計算姿態(tài)是什么樣子的,計算模型的姿態(tài)。這種優(yōu)化極大地減少了姿態(tài)更新的頻率。

    這樣做的效果非常驚人,可以把姿態(tài)更新的開銷從84%直接降到9%。基本上做到這一步之后,就可以在服務(wù)器上跑動畫了。可能會有一定的開銷,但不至于完全跑不起來。這是業(yè)界常見的一些優(yōu)化方式。

    而當我們把姿態(tài)更新的開銷降到9%,這時最高的開銷就成了動畫狀態(tài)更新,占比11%,變得更凸顯了。

    如果一個角色很多動畫邏輯非常復(fù)雜,導(dǎo)致狀態(tài)機也非常復(fù)雜,那么開銷可能還會超過11%的占比,這時候如何優(yōu)化狀態(tài)更新就成了當務(wù)之急。

    復(fù)雜的狀態(tài)機如何優(yōu)化?

    我們以UE為例,先來介紹狀態(tài)機的樣子。

    首先里面有一些狀態(tài),比如說走跑跳,下圖是一個最簡單的Locomotion,移動的狀態(tài)機,有在地面idle/walk/Run的狀態(tài),有起跳的JumpStart,在空中循環(huán)播放的JumpLoop,落地的JumpEnd的狀態(tài),它們之間有一些條件連接起來。

    比如外面條件說角色下一刻要騰空了,那我就會改變一個條件,讓他從idle狀態(tài)跳轉(zhuǎn)到JumpStart狀態(tài),起跳結(jié)束就循環(huán)播放一個空中的動作。大概就是這樣的流程。

    所以大概可分成三部分,第一部分叫做Find_Transitions,即從當前狀態(tài)找一個可能的跳轉(zhuǎn)條件。第二部分,如果這個條件為真的話,有一個跳轉(zhuǎn)可能發(fā)生,那么就執(zhí)行這個跳轉(zhuǎn)。第三部分,執(zhí)行完了之后,兩個狀態(tài)之間可能會有一些過渡,那還要更新這兩個狀態(tài)。

    三個部分的開銷占比是怎樣的?

    我們發(fā)現(xiàn),尋找一個可能的跳轉(zhuǎn),和最后的狀態(tài)更新,占據(jù)了絕大部分的開銷。所以再來優(yōu)化這部分的時候,也會選取這些開銷更大的。

    我們從哪些方面去優(yōu)化狀態(tài)機的更新?

    第一,優(yōu)化跳轉(zhuǎn)之后兩個狀態(tài)的過渡。

    第二,因為狀態(tài)跳轉(zhuǎn)每次都要計算一個條件,為真才跳轉(zhuǎn),為假就不跳轉(zhuǎn)了,所以可以優(yōu)化這個條件的計算。

    第三,每次都要判斷所有條件哪些為真,哪些為假,這個頻率可以降低。還是上文所說,我們既可以降低數(shù)據(jù)量也可以降低頻率。

    狀態(tài)過渡優(yōu)化

    以Locomotion為例。我選取的是在空中到落地這一段時間的狀態(tài)跳轉(zhuǎn),比如原來的角色在空中,還在那里不停地播一個循環(huán)的動作,接下來他要著地了,這個時候因為兩個動作之間是有一些變化的,我們不能讓他瞬切,所以中間就會有一個過渡。

    那這個過渡,至少有兩種模式。

    一種是Cross Fade,上一個狀態(tài)權(quán)重逐漸降低,下一個狀態(tài)權(quán)重逐漸升高,這樣兩個權(quán)重會出現(xiàn)交叉,過渡過程中兩個狀態(tài)權(quán)重都不為0 ,所以必須更新這兩種狀態(tài)。如果這兩個狀態(tài)中間又嵌套了別的狀態(tài)機,也是一定要更新的。

    第二種方式,有的引擎稱它為Immediate模式,UE叫做Inertialization模式。

    假如還在空中跳,下一刻要落地了,會把空中跳的狀態(tài)拍個快照,然后直接就不再更新它了。接下來,下一個狀態(tài)的權(quán)重逐漸從0升到1。通過這種方式,只需要更新下一個狀態(tài)就ok了。這樣,當狀態(tài)跳轉(zhuǎn)的時候,開銷降了一半,因為只需要更新一個狀態(tài)。

    做了這樣的優(yōu)化之后,在Update_States狀態(tài)更新這一塊,會降低大概10%的開銷。這是一個很好的事情,因為其實對邏輯沒有影響,是一個無損的優(yōu)化。

    尋找跳轉(zhuǎn)優(yōu)化

    還是以UE、從空中到落地這段時間為例。

    怎么決定接下來需要著陸?一般來講會寫條件來判斷,有兩種寫法。

    下圖上面的寫法,直接接收了一個Bool值,Bool值如果是True就跳轉(zhuǎn)。下面的寫法,是寫了一個表達式,通過判斷速度是不是變化,來決定是否跳轉(zhuǎn)。

    這兩種方式有什么區(qū)別呢?根據(jù)UE官方的提示,這兩種方法的效率大概會相差10倍。

    原因比較簡單,第一種直接使用Bool值來判斷的話會編譯成本地代碼。如果用第二種寫法,編譯的是虛擬機代碼,經(jīng)過藍圖虛擬機來執(zhí)行才能判斷其中的結(jié)果。

    實際情況中,如果不用UE也會有一樣的問題,因為這個條件也有可能不是C++寫的,可能是Python來寫的,那會面臨一樣的問題。腳本語言相比像Python、lua這樣的非本地代碼,性能本來就是低的。

    如果我們過多地使用了不是本地化的語言寫的條件,就會給狀態(tài)機的更新造成很大的性能開銷,那么我們可以把這部分的判斷變成本地化代碼,就獲得了一定的性能提升。

    對UE來講,你可以用它的Nativization工具,自動化地把藍圖代碼變成本地化代碼,這是一個很好的工具,大家可以研究。

    對于動畫狀態(tài)機來講,也會帶有10%左右的性能提升。

    為什么優(yōu)化了10倍,整體只能優(yōu)化10%呢?因為那個10倍對UE來講,僅僅是藍圖的執(zhí)行和本地代碼執(zhí)行的開銷,但是狀態(tài)機是一個基于節(jié)點的結(jié)構(gòu),它的執(zhí)行還是依賴節(jié)點跳轉(zhuǎn)。

    那就會導(dǎo)致一個后果,沒法像優(yōu)化一個語法樹那樣,直接把某些節(jié)點給裁剪掉。所以對于狀態(tài)機這樣的情況來講,它有優(yōu)化,但并沒有我們想的那么高。

    那還有沒有更有效的優(yōu)化方法?我們可以分析一下狀態(tài)跳轉(zhuǎn)的頻率。

    比如像下圖左上角這個狀態(tài)機,每一幀都會判斷,當前狀態(tài)有沒有一個條件可以跳到別的狀態(tài)。

    像左上角這種,每一個狀態(tài)只有一個指向外面的箭頭,只要判斷一次。對于右上角這個狀態(tài)機,就比較復(fù)雜,它的idle狀態(tài)的話有三條路徑可以跳出去,每一幀對應(yīng)的時候,就需要把三個條件全部判斷一遍。

    那狀態(tài)機在什么時候才需要跳轉(zhuǎn)呢?

    有些時候,比如角色站在那兒不動,是不會跳轉(zhuǎn)的,只有當玩家按下了跳躍鍵,或者按下了一個行走鍵的時候,才需要來把狀態(tài)機發(fā)生跳轉(zhuǎn)。而且,玩家的輸入頻率一般是非常低的,頂尖的電競運動員的輸入頻率也就每秒鐘大概7Hz,但是我們服務(wù)器的更新頻率可能是每秒鐘是30Hz以上。

    于是我們發(fā)現(xiàn),這里面有一個方法來降低跳轉(zhuǎn)條件測試的頻率。

    其實跳轉(zhuǎn)條件也是分成兩類的,一類是依賴玩家的輸入,這種條件我們可以把它優(yōu)化掉,因為玩家的輸入本來就沒有那么高的頻率,用一些方法來省掉它的更新就可以了。

    另一種依賴于動畫播放進度,我們可以優(yōu)化前者的更新頻率,因為玩家輸入頻率不高,可以直接省掉更新。具體地,可以通過在UE藍圖中進行人工標注標明可優(yōu)化的跳轉(zhuǎn)信息。

    其實相對比較簡單,寫一個很快的方法來判斷玩家的輸入有沒有發(fā)生變化,如果沒變化根本不用測試,就像剛才idle突然有三條箭頭沖向外面,但如果判斷三個條件都沒變化的話(判斷Cache是不是可用的),如果Cache還是可用的話,那就直接跳過去,來省掉大部分的跳轉(zhuǎn)測試開銷。這個比較簡單。

    UE會比較復(fù)雜一點,因為UE的動畫狀態(tài)機是一個動畫藍圖,這就意味著,相比較那些狀態(tài)機純粹是邏輯結(jié)構(gòu)的情況(判斷某個狀態(tài)依賴的一些條件跳轉(zhuǎn)相對容易一些),UE會編譯成一些藍圖的字節(jié)碼來執(zhí)行。

    當然我們可以通過編譯原理的一些方法,分析藍圖的語法節(jié)點,然后來找到依賴條件。我這里還提供一個相對比較取巧的方法,這種依賴條件其實可以人工標注。

    比如當前是Jump_Loop,還空中不停地循環(huán),它依賴的跳轉(zhuǎn)條件是下一個是不是已經(jīng)著地了,我們把這個條件標注在這個狀態(tài)上面,然后在藍圖編譯的時候,利用這些標注就更容易把優(yōu)化代碼插進去,這樣最后生成的代碼就是優(yōu)化后的代碼。這就是一個比較簡單可行的辦法,也比較容易實現(xiàn)藍圖的優(yōu)化。

    但對于其他引擎來講,如果它的狀態(tài)機僅表示邏輯結(jié)構(gòu),沒有像動畫藍圖這么復(fù)雜,可以用更簡單的辦法來實現(xiàn)這一步跳轉(zhuǎn)的優(yōu)化。

    這部分的優(yōu)化還是挺可觀的。動畫狀態(tài)過渡優(yōu)化到了10%左右,跳轉(zhuǎn)優(yōu)化優(yōu)化了70%。

    這樣就實現(xiàn)了比較好的效果,因為完全不影響動畫的邏輯,只是讓狀態(tài)機跑的更快了,節(jié)省了一些不必要的計算。這就意味著服務(wù)器可以跑更多角色了,

    服務(wù)器的算力沒要那么高,也可以省錢。

    未來:公平的環(huán)境,完備的邏輯,細致的交互

    服務(wù)器動畫按照現(xiàn)在的發(fā)展趨勢,其實好處是非常多的,雖然現(xiàn)在真正使用服務(wù)器動畫的游戲并不多,但這是一個比較有前景的領(lǐng)域,因為可以提供更公平的聯(lián)機環(huán)境,而且可以實現(xiàn)更細致的交互。

    比如服務(wù)器一旦有了動畫之后,服務(wù)器的角色就是活的,就不只是一堆數(shù)據(jù)了,它有姿態(tài),可以進行更復(fù)雜的交互。

    我們現(xiàn)在提倡的云游戲也好,元宇宙也好,大概很難想象元宇宙里的東西是沒有動畫的。

    對于服務(wù)器性能優(yōu)化來講,雖然做了這么多的工作,但其實并不徹底,因為按照我們的傳統(tǒng)看法,動畫還是基于每幀更新的,但服務(wù)器,我們覺得比較徹底的優(yōu)化要完全實現(xiàn)動畫系統(tǒng)的事件更新的驅(qū)動,這樣,服務(wù)器只需要計算它所需要的數(shù)據(jù)就可以了。

    同時,我們知道服務(wù)器雖然越來越強大,但它的性能其實還是有上限的,當服務(wù)器的性能不足以支撐這么多動畫計算的時候,就需要一個動畫的自動分級機制,讓服務(wù)器不至于雪崩。

    我覺得當這兩個方向做的非常的完美了,服務(wù)器動畫可能會迎來更好的發(fā)展。

    本次的分享到此結(jié)束,謝謝大家。

    責任編輯:Rex_08

    關(guān)鍵詞: 消息資訊
    推薦閱讀
    欧美国产在线一区,免费看成年视频网页,国产亚洲福利精品一区,亚洲一区二区约美女探花
    <bdo id="ks4iu"><del id="ks4iu"></del></bdo>
  • 
    <pre id="ks4iu"></pre>
  • <bdo id="ks4iu"><del id="ks4iu"></del></bdo>
    <input id="ks4iu"><em id="ks4iu"></em></input>
    
    
  • <center id="ks4iu"><cite id="ks4iu"></cite></center>
  • 主站蜘蛛池模板: 欧美激情一区二区三区| 两个人看的www高清免费观看| 网站在线观看你懂的| 无码中文字幕日韩专区| 国产免费午夜a无码v视频| 久久国产精品2020免费m3u8| 国产浮力第一页草草影院| 最好看的2019中文无字幕 | 国产成人无码区免费A∨视频网站 国产成人无码区免费内射一片色欲 | 国产鲁鲁视频在线观看| 亚洲经典在线观看| 99热这里只/这里有精品| 69免费视频大片| 永久免费毛片在线播放| 国内少妇偷人精品视频免费| 亚洲欧美综合国产不卡| 4ayy私人影院| 欧美videos在线观看| 国产成人无码av| 久久九九精品国产综合喷水| 色屁屁在线观看视频免费| 成在线人视频免费视频| 免费观看的a级毛片的网站| a资源在线观看| 欧美综合激情网| 国产精品v欧美精品∨日韩| 久久精品国产亚洲精品| 色欲麻豆国产福利精品| 工棚里的换爱系列小说| 亲密爱人免费观看完整版 | 亚洲欧美色图小说| 亚洲网站www| 日本欧美视频在线| 另类重口100页在线播放| av无码一区二区三区| 欧美成人免费观看| 国产成人精品1024在线| 中文字幕欧美一区| 猫咪av成人永久网站在线观看| 国产精品成人va| 久久久久免费精品国产|