手机在线视频精品中文网,色色骚骚操鸡把,精品免费久久久久久久久,中文字幕日韩区二区三区

米哈游技術(shù)總監(jiān):從手機(jī)走向主機(jī),《原神》主機(jī)版渲染技術(shù)分享

2020-12-23 16:19:26

威狐小編:11 月 16 –20 日,中國(guó) Unity 線上技術(shù)大會(huì)以直播形式召開,為廣大開發(fā)者帶來了一場(chǎng)有關(guān)前沿技術(shù)和優(yōu)秀案例的線上盛會(huì)。在11月17日晚舉行的游戲?qū)?chǎng),米哈游的技術(shù)總監(jiān)弋振中現(xiàn)身,為廣大同行帶來關(guān)于《原神》主機(jī)版渲染技術(shù)的精彩分享。

《原神》的主機(jī)版開發(fā)是國(guó)內(nèi)首次嘗試,通過一年多的開發(fā),研發(fā)團(tuán)隊(duì)積累了很多經(jīng)驗(yàn),尤其是關(guān)于寫實(shí)渲染技術(shù)與風(fēng)格化游戲的結(jié)合。隨著次世代主機(jī)的到來,游戲行業(yè)又將面臨了一大波技術(shù)升級(jí),而米哈游的經(jīng)驗(yàn)對(duì)于時(shí)間、資源和人才都很缺乏的國(guó)內(nèi)主機(jī)生態(tài)來說,十分寶貴。

同時(shí),弋振中也提到:“Unity是一個(gè)靈活度很高的引擎,代碼風(fēng)格很簡(jiǎn)潔,所以我們能夠更方便地定制化開發(fā)《原神》的渲染管線。”

以下是演講實(shí)錄:

弋振中:大家好!歡迎參加這次分享!今天我演講的主題是從手機(jī)走向主機(jī),《原神》主機(jī)版渲染技術(shù)分享。首先我簡(jiǎn)單介紹一下《原神》的游戲,《原神》是開放世界的RPG游戲,有獨(dú)特的二次元畫風(fēng),是跨平臺(tái)的,而且長(zhǎng)期運(yùn)營(yíng),長(zhǎng)期更新。

接下來我稍微介紹一下自己,我叫弋振中,大概有十多年的主機(jī)游戲開發(fā)經(jīng)驗(yàn),畢業(yè)之后加入了Ubisoft Shanghai,2012年去了加州的Zindagi Games,為當(dāng)時(shí)還沒有上市的PS4做一款獨(dú)占的游戲。然后去了紐約的Avalanche Studios,參與制作了《正當(dāng)防衛(wèi)》的3和4?;貒?guó)之前的最后一站是在西雅圖的微軟Xbox。2019年初回到上海,加入了米哈游,組建了研發(fā)團(tuán)隊(duì),目前負(fù)責(zé)《原神》的主機(jī)平臺(tái)開發(fā)。這是我做過的一些項(xiàng)目。

今天的內(nèi)容安排大致是這個(gè)樣子,首先我會(huì)介紹一下《原神》主機(jī)平臺(tái)的基本情況,然后按照我們開發(fā)的時(shí)候改造渲染管線的思路,選擇部分的技術(shù)點(diǎn)進(jìn)行更深入的分享。希望從渲染的角度,讓大家對(duì)于我們?nèi)绾螌ⅰ对瘛穾У街鳈C(jī)平臺(tái)有大致的了解。最后是一點(diǎn)我個(gè)人的開發(fā)體會(huì)。

首先,Unity是我們游戲里面使用的引擎。Unity是一個(gè)靈活度很高的引擎,代碼風(fēng)格很簡(jiǎn)潔,所以我們能夠更方便地定制化開發(fā)《原神》的渲染管線。Unity中國(guó)的技術(shù)支持很配合我們,在此對(duì)他們表示感謝!

PS4作為游戲的主機(jī),硬件架構(gòu)可以說是為游戲開發(fā)量身打造的,主機(jī)開發(fā)過程當(dāng)中大量的精力是花費(fèi)在如何更好地利用硬件特性上,也積累了不少我們認(rèn)為還可以的技術(shù)實(shí)現(xiàn)。不過因?yàn)樗髂酦DA的原因,今天的分享就不涉及相關(guān)的內(nèi)容,也不涉及底層的優(yōu)化。前面也提到今天的分享,主要是針對(duì)渲染管線的,所以也不涉及CPU和其他的模板。

下面是主機(jī)渲染管線的簡(jiǎn)介,首先我們有非常強(qiáng)大的引擎團(tuán)隊(duì),在Unity上面為《原神》進(jìn)行了深度的開發(fā)。主機(jī)平臺(tái)和手機(jī)平臺(tái)采用了不同的渲染管線,但是游戲的基調(diào)是一致的,都是基于PBR的風(fēng)格化渲染?!对瘛返闹鳈C(jī)平臺(tái)開發(fā)起步時(shí)間稍晚于手機(jī)平臺(tái),在平臺(tái)管線搭建好以后就進(jìn)入了同步開發(fā)的節(jié)奏。資源的制作、功能的開發(fā)多方面都需要兼顧到多個(gè)平臺(tái)的情況。

基于PBR,是為了讓整個(gè)大世界的光影效果保持統(tǒng)一,因?yàn)槲覀兊墓庥岸际菍?shí)時(shí)計(jì)算的,有24小時(shí)的循環(huán),有動(dòng)態(tài)的天氣系統(tǒng)。PBR能夠確保不會(huì)在不同的光照條件下出現(xiàn)脫離預(yù)期的渲染效果。作為風(fēng)格化的游戲,也需要根據(jù)美術(shù)的需求修改不同的材質(zhì)。

《原神》在PS4上的分辨率是這樣設(shè)置的,PS4 pro上面是原生的4K分辨率,在PS4的base,我們是把1440P作為我們的渲染分辨率,最后是輸出到1080P上面,這樣我們得到的最終后面會(huì)更加清晰,也會(huì)更加銳利。作為《原神》為主機(jī)開發(fā)的功能,大量使用了compute shader,compute shader有很多很好的特性,而且在支持Async compute管線的平臺(tái)上,我們還能夠進(jìn)一步隱藏開銷。

《原神》的風(fēng)格化渲染是非常獨(dú)特的,因此美術(shù)對(duì)于圖形功能的要求也和寫實(shí)類游戲不一樣,尤其是光影效果,大家可以看到臟、黑、死、焦、噪這些詞都頻繁地出現(xiàn)了美術(shù)和程序的溝通當(dāng)中。

下面我們提到的所有的技術(shù),都經(jīng)歷了很長(zhǎng)的磨合期,有一些甚至還在磨合當(dāng)中。在經(jīng)歷了反復(fù)的打磨和修改,直到美術(shù)對(duì)最終效果滿意,程序?qū)ψ罱K實(shí)現(xiàn)方案的性能也滿意的情況下,我們才會(huì)大規(guī)模鋪開制作。

接下來再介紹具體的功能之前,我跟大家講一下在PS4平臺(tái)剛開始開發(fā)的時(shí)候,我們面臨的一個(gè)狀況。首先是我們有一個(gè)已經(jīng)針對(duì)手機(jī)做大量開發(fā)的Unity引擎,這就意味著簡(jiǎn)單的切換平臺(tái)就想讓游戲能夠在PS4上跑起來,這是不可能的了。很多項(xiàng)目之前做的改動(dòng),在實(shí)現(xiàn)的時(shí)候也沒有考慮到主機(jī)平臺(tái)的特性。再加上各種計(jì)劃為PS4開發(fā)的圖形和游戲的功能,這都意味著大量的工作量。

另外還有TRC、索尼賬號(hào)等等一系列PS4獨(dú)有的問題需要解決,工作量和工作難度都非常大,然而我們能夠給主機(jī)開發(fā)的資源又很有限。一開始的主機(jī)團(tuán)隊(duì)就我一個(gè)人,光桿司令。為了全球同步上市,留給我們的開發(fā)時(shí)間大概只有一年半,一年半的時(shí)間要讓一個(gè)平臺(tái)從無到有,還要達(dá)到一定的品質(zhì),這期間還要準(zhǔn)備ChinaJoy、TGS等展會(huì),能夠順利地完成這一切,真的是非常感謝《原神》的整個(gè)開發(fā)團(tuán)隊(duì)的努力,非常的不容易。

下面講一下我們?cè)阡秩竟芫€做改動(dòng)的時(shí)候一些思路,因?yàn)殚_發(fā)的時(shí)間很緊,所以在選擇技術(shù)改造點(diǎn)的時(shí)候,遵循下面幾個(gè)原則。

第一個(gè)是關(guān)于功能的選擇,我們首先排除掉開發(fā)周期長(zhǎng)的,需要過多地前期研究工作的功能,因?yàn)槲覀儧]有時(shí)間。

然后根據(jù)游戲的美術(shù)風(fēng)格,我們選擇一些對(duì)于畫質(zhì)的幫助更大的地方去做提升。另外因?yàn)闀r(shí)間不多,所以我們希望新加的功能能夠更多地發(fā)揮作用,所以最好是能夠在相互之間產(chǎn)生互動(dòng),這樣會(huì)顯得畫面更加系統(tǒng)化,得到的畫質(zhì)提升也會(huì)有1+1>2的效果。

下面就是我們做一些技術(shù)點(diǎn)的解析。首先我們從場(chǎng)景的光影方面選擇了幾個(gè)技術(shù)點(diǎn),主要是側(cè)重一些方法,會(huì)稍微涉及到一點(diǎn)點(diǎn)的優(yōu)化思路。

第一個(gè)是關(guān)于方向光的陰影,《原神》的大量游戲時(shí)間是在室外,室外方向光的陰影質(zhì)量非常重要。一方面近處的陰影細(xì)節(jié)需要更加細(xì)膩,才顯得畫面更干凈。另外一方面是陰影覆蓋范圍需要足夠大,因?yàn)橛螒虻目梢暰嚯x非常遠(yuǎn)。《原神》的陰影范圍是800米。大家可以看一下這張貼圖,即使在遠(yuǎn)處墻壁上一小片的綠植產(chǎn)生的陰影,在放大之后都能夠看到樹葉的輪廓。這個(gè)地方放大之后,能夠看到樹葉輪廓,而且非常穩(wěn)定。整體上來說,我們對(duì)于《原神》的方向光陰影的質(zhì)量是比較滿意的。

我們陰影的技術(shù)還算是比較常規(guī),使用了Cascaded shadow map 加上基于Poisson disc的soft shadow,我們游戲沒有使用通常的4級(jí)cascades,而是用了8級(jí),這屬于大力出奇跡的方式。大力出奇跡帶來了更好的陰影效果,當(dāng)然也帶來了更多的性能開銷。更多的drawcall會(huì)帶來CPU開銷,更多的cascades也會(huì)帶來GPU的開銷。我們把質(zhì)量提升上去之后,會(huì)想辦法來解決性能問題,那我們?cè)趺慈プ龅哪兀?/p>

首先在CPU端,我們做了一個(gè)shadow cache,8級(jí)cascades前4級(jí)我們每幀都更新,后面4級(jí)是采用輪流更新的方式,確保每8幀所有的cascades都能至少更新一次。每一幀的話,我們只更新5級(jí)cascades。

主要的工作量其實(shí)在GPU端,用了8級(jí)cascades以后,我們的screen space shadow map的開銷長(zhǎng)期是大于2毫秒的,在某些情況之下能夠超過2.5毫秒。GPU比4級(jí)cascades的情況下,爆漲了0.5到0.8毫秒。

我們的軟陰影采用的是泊松分布的采樣,而且每個(gè)像素會(huì)去做一個(gè)旋轉(zhuǎn),來消除重復(fù)的pattern,這一整套的操作都是很重量級(jí)的。但是我們仔細(xì)想一想,真的需要對(duì)每個(gè)像素都要做這么多操作嗎?所以我們的優(yōu)化思路是盡量只在必要的地方做軟陰影計(jì)算,我們會(huì)生成一張Mask貼圖,在貼圖里面標(biāo)出陰影、半影和非影片區(qū)。陰影區(qū)和非陰影區(qū)只需要直接返回0和1就好了,只有在半影區(qū)才會(huì)去計(jì)算軟陰影,通過這種方式,我們的GPU開銷大致減少了30%左右。甚至比采用4級(jí)cascades還要再快一些。

大家可以看一下這張圖,圖里面被紅色標(biāo)注的區(qū)域,就是我們的半影區(qū),這個(gè)是需要我們?nèi)プ鲕涥幱疤幚淼膮^(qū)域。其他的區(qū)域,就是在陰影區(qū)域或者是非陰影區(qū)域,我們直接返回0和1就好了。大家可以看出來,絕大部分的像素都可以去掉軟陰影計(jì)算這個(gè)繁瑣的步驟。

這張神奇的Mask貼圖是怎么生成的呢?這張Mask貼圖的分辨率是屏幕分辨率的1/4×1/4,也就是說一個(gè)Mask值對(duì)應(yīng)的是一個(gè)4×4的block。然后我們對(duì)4×4的block里面的每一個(gè)像素,來判斷它是不是在陰影中,最后匯總成一個(gè)陰影、半影和非陰影的三個(gè)狀態(tài),保存到Mask貼圖里。這樣我們能夠得到一個(gè)準(zhǔn)確的半影信息,但是它不夠快,所以我們做了進(jìn)一步的優(yōu)化,只選擇4×4這個(gè)block里面很少的幾個(gè)像素,來判斷是不是在陰影當(dāng)中。

這幾個(gè)像素的判斷結(jié)果,就代表了整個(gè)block的信息,顯然這樣會(huì)出現(xiàn)一些誤差,因?yàn)槲覀兪悄脦讉€(gè)少數(shù)幾個(gè)像素的結(jié)果來代表整個(gè)block,所以我們把這樣計(jì)算得到了Mask貼圖做了模糊處理,讓半影的區(qū)域稍微擴(kuò)散出去。整個(gè)Mask貼圖的生成,包括模糊處理大概的開銷是在0.3毫秒左右。大家可以看一下對(duì)比圖。

優(yōu)化出來的效果非常好,肉眼可以說是看不出任何的區(qū)別。這樣優(yōu)化完之后,我們的GPU開銷時(shí)間大概穩(wěn)定在1.3到1.7毫秒。

把陰影搞好以后,下面我們來看看AO(Ambient Occlusion環(huán)境光遮蔽)。大家可以考慮一種情況,就是人物和場(chǎng)景的物體都已經(jīng)處在山或建筑物的陰影當(dāng)中,這個(gè)時(shí)候人物和物體的投影跟山和建筑的投影是融為一體的。這種情況之下,畫面缺乏對(duì)比,人和物體就會(huì)顯得浮空。為了解決這個(gè)問題,我們?cè)谟螒蚶锩娌捎昧硕喾N的AO技術(shù),針對(duì)不同的情景生成不同的AO。

首先我們使用了HBAO,這是一個(gè)比較常規(guī)的實(shí)現(xiàn),能夠提供一些比較細(xì)節(jié)的AO效果。同時(shí)我們對(duì)靜態(tài)物體和動(dòng)態(tài)物體分別采用了AO Volume和Capsule AO這兩種技術(shù)。大家可以看一下這是HBAO開關(guān)的對(duì)比圖,效果還是很明顯的。

下面這個(gè)是AO Volume的開關(guān)情況,大家可以重點(diǎn)看一下我們?cè)诩t圈里面的區(qū)域。椅子對(duì)地面產(chǎn)生了柔和的投影,在我們打開AO volume的情況下。

和HBAO相比,AO Volume能夠產(chǎn)生更大范圍的AO。它可以針對(duì)類似桌子或者椅子產(chǎn)生大面積AO。因?yàn)榧夹g(shù)原理和性能的限制,HBAO是沒辦法產(chǎn)生這種效果的。AO Volume這個(gè)時(shí)候就體現(xiàn)很好的補(bǔ)充,要實(shí)現(xiàn)AO volume,首先我們是在離線的時(shí)候?qū)π枰a(chǎn)生AO volume的物體做一個(gè)遮擋信息的計(jì)算。這個(gè)計(jì)算是在物體的本地空間(Local space)去做的,生成的遮擋信息我們保存下來,在運(yùn)行的時(shí)候注入到volume texture中去使用。這個(gè)技術(shù)在2012年GDC關(guān)于《InFamous 2》的講座上有提到過,大家有興趣可以去看一下。

下面是關(guān)于Capsule AO的對(duì)比圖,大家可以重點(diǎn)看一下屏風(fēng)和地面,被我們紅色的圈給圈出來的區(qū)域。大家可以看到相鄰在屏風(fēng)和地面,能夠產(chǎn)生出能夠反映體形和人影的投影。而且如果在游戲中大家去觀察的話,隨之相鄰動(dòng)作的改變,陰影的形狀也會(huì)隨之產(chǎn)生變化。

我們前面提到AO Volume主要是針對(duì)靜態(tài)物體的,因?yàn)檎趽跣畔⑹峭ㄟ^離線計(jì)算的方式保存下來。像角色這種帶骨骼動(dòng)畫的,是不能采用這種方式的,因?yàn)樾螤钍遣煌5卦诎l(fā)生變化。Capsule AO的做法就是用一些膠囊體包裹住人物的四肢和軀干,這些膠囊體和角色的骨骼動(dòng)畫綁定進(jìn)行同步更新。然后這些膠囊體會(huì)被用來做遮擋計(jì)算,計(jì)算的時(shí)候我們把它分為無方向的環(huán)境遮擋計(jì)算,以及帶方向的遮擋信息計(jì)算。帶方向的遮擋信息計(jì)算采用的方向是主光源方向和法線進(jìn)行混合之后的得到的虛擬遮擋方向。通過這種方式,角色可以同時(shí)在周圍的墻和地面等投出多個(gè)陰影。

下面是一個(gè)關(guān)于AO的優(yōu)化技巧,《原神》的AO都是在1/2×1/2分辨率的RT(Render Texture)上去做計(jì)算。為了保證畫面的干凈,我們對(duì)AO還做了一個(gè)模糊處理(blur)。然后再Upsample一個(gè)全分辨率的貼圖上面去。所有的模糊處理和Upsample pass,我們都用了一個(gè)Bilateral filter,確保不會(huì)有無效的AO滲透到周圍的區(qū)域。

從前面的描述可以看出來,模糊處理和Upsample加起來一共有三個(gè)pass,這就意味著AO需要被讀取和寫入多次。而且你如果你了解Bilateral Upsample的話,大家可以知道相鄰的像素之間有很多的計(jì)算其實(shí)都是重復(fù)的,所以我們采用的優(yōu)化方式是將所有的計(jì)算都放到一個(gè)compute pass里面去做。然后通過LDS來保存blur的中間值,通過同時(shí)輸出四個(gè)像素的方式,來重用相鄰像素的計(jì)算。最終我們還可以通過async compute pipe把性能開銷進(jìn)一步降低。

關(guān)于我們的Local Light,我們?cè)谟螒蚶锩娌捎昧薈lustered deferred lighting。我們支持是視野內(nèi)同時(shí)出現(xiàn)最多1024盞燈。大概的做法是我們將屏幕分成64×64像素的tile,然后每一個(gè)tile在深度的方向上面繼續(xù)分為16級(jí)的clusters。通過這兩個(gè)圖,可以大概看出我們能夠支持多少燈。

這張圖是一個(gè)游戲里面的截圖,是一個(gè)典型的通過Local Light的陰影提升畫面的情況,多個(gè)不同的Local Light,它們的照明范圍是交錯(cuò)存在的,然后角色也投下多個(gè)不同的陰影朝不同的方向,畫面就顯得細(xì)節(jié)很豐富。

我們?cè)趺醋龅哪??我們的Local Light 陰影系統(tǒng)支持接近100盞燈的實(shí)時(shí)陰影,理論上我們可以支持更多的,不過這已經(jīng)很夠用了。陰影的分辨率是根據(jù)優(yōu)先級(jí)和距離進(jìn)行動(dòng)態(tài)調(diào)整,最終的陰影是通過烘焙的靜態(tài)場(chǎng)景陰影和實(shí)時(shí)生成的動(dòng)態(tài)場(chǎng)景陰影結(jié)合得到的。游戲里面有很多的Local Light,如果每一個(gè)Local Light都去烘焙它的shadow texture的話,會(huì)占用的硬盤空間非常大。而且因?yàn)槭巧疃荣N圖,所以不能夠隨便使用BCn的壓縮,那樣瑕疵會(huì)非常風(fēng)險(xiǎn),所以需要一個(gè)好的算法來對(duì)于烘焙的shadow texture做一個(gè)壓縮。這個(gè)壓縮需要在精度損失足夠低的同時(shí),還要保持壓縮率足夠高,同時(shí)我們的解壓開銷要非常小才行。

我們開發(fā)的這個(gè)系統(tǒng)是在離線制作的時(shí)候,對(duì)于shadow texture做一個(gè)壓縮,盡量地去保持精度,運(yùn)行的時(shí)候解壓的速度也非???,用compute shader去解壓的情況,1K×1K的shadow texture,我們解壓只需要0.05毫秒,可以說非常非常快。

那壓縮率和壓縮質(zhì)量呢?我們先介紹一下壓縮的算法思路。首先我們對(duì)于shadow texture按照一個(gè)2×2的block來進(jìn)行編碼,每4個(gè)深度值,我們用32bit來保存。如果想要降低精度損失,可以選擇高精度壓縮,這種情況之下每個(gè)block的大小變成64bit。編碼的方式有兩種,一種是基于深度平面方程的方式,或者是通過壓縮的浮點(diǎn)數(shù)方式。編碼完成之后,還要進(jìn)一步通過一個(gè)quad tree來合并編碼以后的數(shù)據(jù),進(jìn)一步提高壓縮率。quad tree是每個(gè)tile要保存一個(gè),而每個(gè)tile又包含了16×16個(gè)block,大家可以看到下面的三個(gè)圖,從左到右分別是沒有壓縮的深度貼圖,中間是我們的平面方程編碼的視圖,最右邊是我們quad tree 0到4級(jí)的深度視圖,黑的地方是深度為0的區(qū)域。我們參考了Li Bo在2019年Siggraph上面的講座,大家有興趣可以去看一下。

壓縮比:在一個(gè)典型的室內(nèi)場(chǎng)景默認(rèn)精度壓縮比是在20%到30%左右。如果開啟高精度模式壓縮的話,大概默認(rèn)精度壓縮到40%到70%。陰影貼圖的壓縮是非常必要的,可以幫我們?nèi)萘肯陆狄粋€(gè)數(shù)量級(jí)。

大家可以看一個(gè)對(duì)比,這是默認(rèn)精度壓縮,能夠看到紅圈里面有一些瑕疵。這個(gè)實(shí)際上是我們找到的可以說是最差的一個(gè)情況。這是高精度壓縮,基本上看不出任何瑕疵來。這個(gè)是默認(rèn)精度壓縮。如果把高精度壓縮的圖和不壓縮的情況做對(duì)比的話,其實(shí)肉眼是看不出什么差別,所以沒有放這個(gè)圖。

剛才的圖是一個(gè)2K×2K的shadow texture,大小如果不壓縮的話是在8MB,默認(rèn)精度壓縮大小變成了274.4KB,壓縮率是29.85%。如果替換成高精度壓縮,就是肉眼看不出差距的壓縮,貼圖大小變成了583.5KB,這種情況的壓縮率還是有14%左右,所以還是相當(dāng)不錯(cuò)的。

在搞好了Local Light以后,我們接下來為游戲添加了體積霧,體積霧是可以接受Local Light的照明影響,在燈的影響范圍內(nèi)形成一圈光暈,可以極大地提升畫面的體積感。大家可以看到圖里面近處的燈籠周圍會(huì)有一圈泛光。包括畫面遠(yuǎn)處的建筑物,因?yàn)榛\罩在燈光下會(huì)使得周圍的體積霧也被照亮,而顯得有一絲的朦朧。

這個(gè)圖是一個(gè)更有意思的情況。如果我們給Local Light加一個(gè)projection texture,也就是我們通過這個(gè)貼圖來控制Local Light光照的形狀,就像右邊這樣,體積霧也會(huì)產(chǎn)生相應(yīng)的變化。

我們的體積霧的計(jì)算是基于物理的。我們也支持通過不同的參數(shù)讓體積霧在大世界里面的不同區(qū)域有不同的表現(xiàn)。體積霧支持Local Light,這個(gè)在前面已經(jīng)展示過了。為了讓體積霧更加穩(wěn)定,畫面更加細(xì)膩,我們給體積霧添加了Temporal filter,進(jìn)行了多幀的混合。整體的GPU開銷,也控制的不錯(cuò),在PS4 Pro下面大致在1毫秒甚至更少。

大致的實(shí)現(xiàn)是這樣的:首先是基于相機(jī)空間,我們把view frustum分成很多的voxel,這些voxel跟我們前面提到的clustered deferred lighting的clusters是對(duì)齊的,這樣方便我們?cè)诤竺鎸?duì)Local Light做scattering計(jì)算的時(shí)候進(jìn)行一個(gè)加速。

前面提到的體積霧參數(shù)和Local Light的信息,都會(huì)被注入到這些voxel里面去,然后我們通過Ray marching的方式去計(jì)算體積霧。在這個(gè)時(shí)候,Local Light的信息就自然而然被考慮進(jìn)去了。

有了體積霧,我們不得不提到God Ray效果,首先大家可以先看看游戲里面God Ray的表現(xiàn)。對(duì)于方向光進(jìn)行遮擋就可以產(chǎn)生God Ray的效果,我們的做法是有一個(gè)單獨(dú)的pass來生成God Ray,然后是在1/2×1/2分辨率下面。God Ray也是通過Ray marching的方式去生成的,我們會(huì)去采樣shadow map,但是最多會(huì)采樣5級(jí)的cascades。

God Ray生成完之后,我們會(huì)提供美術(shù)一些可以調(diào)整的參數(shù),然后將God Ray的結(jié)果疊加到體積霧上面去。它在使用上面,并不是一個(gè)物理上正確的東西,但是它的效果是能夠讓美術(shù)滿意的。

了解體積霧的人可能會(huì)有一個(gè)問題,為什么要單獨(dú)使用一個(gè)pass呢?體積霧本身就可以產(chǎn)生God Ray。這個(gè)就是一個(gè)很好的技術(shù)和美術(shù)磨合的例子,我們有體積霧直接生成的God Ray,在游戲里面實(shí)際效果其實(shí)不能夠讓美術(shù)滿意,原因有兩點(diǎn)。

第一個(gè)是分辨率不夠,因?yàn)轶w積霧的分辨率是靠Voxel,而我們的Voxel是不會(huì)劃分的特別精細(xì)的。第二是因?yàn)轶w積霧生成的God Ray強(qiáng)度是完全依賴于體積霧的濃度。要想得到很明顯的God Ray,就需要霧的濃度提的非常高。霧的濃度一旦提高了,畫面就會(huì)顯得不通透,太臟,這就是回到前面提到的兩組詞里面,這是美術(shù)不能夠接受的。

所以我們是采用了單獨(dú)的pass去生成God Ray,這樣可以得到更銳利、更清晰的效果,美術(shù)調(diào)整也更靈活。美術(shù)想要什么,我們就給他做什么。

下面給大家看看對(duì)比圖,大家就能更好地體會(huì)到我說的是什么意思。這個(gè)God Ray就是通過體積霧生成的,包括整個(gè)畫面的表現(xiàn)。這張是我們游戲里面現(xiàn)在使用的方式,就是單獨(dú)的pass去生成,做一個(gè)對(duì)比。

大家可以看到第一張God Ray不是很明顯,而且畫面霧的濃度非常高。而第二張圖,God Ray會(huì)更清晰一些,而且整個(gè)畫面是更加干凈、更加通透,這就是美術(shù)想要的效果。

接下來是IBL(Image Based Lighting)系統(tǒng),大家先看一下演示視頻。圖中左邊的是Reflection probe(反射探針),右邊是Ambient probe,隨著24小時(shí)的變化,我們的Reflection probe和Ambient probe的內(nèi)容也會(huì)跟著變化。

我們先看一下左邊的Reflection probe,Reflection probe是用來給場(chǎng)景提供反射信息的。因?yàn)橛螒虻墓庥安粩嘧兓?,我們是不能夠?jiǎn)單地為反射探針烘焙一張環(huán)境貼圖作為反射信息之用。所以對(duì)于每一個(gè)Reflection probe,我們是烘焙了一個(gè)mini GBuffer。產(chǎn)生在游戲當(dāng)中,根據(jù)當(dāng)時(shí)的光照條件去實(shí)時(shí)生成環(huán)境貼圖,美術(shù)可以在游戲里面擺很多個(gè)這樣的Reflection probe,只要他們需要。

然后在運(yùn)行的時(shí)候,我們會(huì)去更新場(chǎng)景的Reflection probe的cubemap。整個(gè)過程我們大致分為三步,第一步是Relight,第二步是Convolve和Compress。我們使用Compute Shader去同時(shí)處理六個(gè)面,然后分幀進(jìn)行,同時(shí)只處理一個(gè)probe,不停地做循環(huán)。

第一個(gè)步驟,就是Relight步驟,大家可以通過圖能看出來,就是一個(gè)簡(jiǎn)單的把當(dāng)前的光照環(huán)境用來照亮mini GBuffer,得到環(huán)境貼圖的過程。然后生成的環(huán)境貼圖,需要經(jīng)過Convolve這一步,得到mipmap的正確信息。最后這個(gè)貼圖需要再通過一個(gè)Compute Shader的做法,壓縮成BC6H的格式,然后送到渲染管線里面去使用。大致是這么三步的過程。

下面是我們的Ambient probe。Ambient probe也是實(shí)時(shí)生成的。我們?cè)谧鐾闞elight以后,Reflection probe是包含了當(dāng)前的整個(gè)光照信息,我們可以從中提取出當(dāng)前的Ambient的信息,并且把它轉(zhuǎn)化成一個(gè)3階的SH(Spherical Harmonic)系數(shù)保存下來。

這個(gè)提取的過程,在我們把Reflection probe處理完成以后會(huì)自動(dòng)進(jìn)行,也是同時(shí)使用Compute Shader來處理六個(gè)面。

這么看下來,我們整個(gè)系統(tǒng)算是完成了,但實(shí)際上里面有很多地方是可以改進(jìn)的。第一個(gè)是Relight是沒有陰影的,因?yàn)閱慰縨ini GBuffer我們是沒有辦法在Relight pass生成陰影,這樣會(huì)導(dǎo)致一個(gè)很大的問題。就是在Relight完成得到的環(huán)境貼圖是漏光的,本來應(yīng)該處于陰影當(dāng)中的地面也會(huì)變得非常明亮。

通過這樣的環(huán)境貼圖算出的環(huán)境光(ambient)也會(huì)出現(xiàn)有問題的情況,那怎么解決呢?我們的做法是,我們把24小時(shí)的shadow都烘焙下來,就是隔一段時(shí)間我們烘焙一下,把shadow轉(zhuǎn)化成一個(gè)shadow SH保存起來。在運(yùn)行的時(shí)候簡(jiǎn)單通過當(dāng)前的時(shí)間對(duì)shadow SH進(jìn)行插值,用來壓暗Relight以后的結(jié)果。

這樣得到的效果是出乎意料的好,而且我們需要保存的數(shù)據(jù)非常的少。因?yàn)閟hadow SH很糊,所以我們做插值也沒有什么大的問題。

同樣的方式,我們還可以把Local Light的信息也保存下來,作為L(zhǎng)ocal Light的SH在Relight的時(shí)候也加上去,這樣可以得到非常好、非常廉價(jià)的一個(gè)Local Light 反彈的效果。大家可以看一下對(duì)比,這張圖是沒有添加shadow SH,這張是添加的,大家可以看到?jīng)]添加的情況之下,屋檐和地面都莫名其妙的亮,添加之后就能夠看出來是在陰影當(dāng)中了,所以效果是很明顯的。

下面是我們把Local Light SH加進(jìn)去的情況對(duì)比。這是沒有添加的,大家注意看一下畫面右上角那片屋檐下面暗的區(qū)域。

我們現(xiàn)在已經(jīng)解決了漏光的問題,并且添加了Local Light SH。接下來是一個(gè)室內(nèi)室外光照環(huán)境不一致帶來的問題,因?yàn)槭覂?nèi)和室外的光照環(huán)境往往是很不一樣的。如果不加區(qū)分的話,室內(nèi)外的環(huán)境光(ambient)混在一起,得到的效果就很容易讓人家覺得不對(duì)勁。

我們是把Reflection probe分成室內(nèi)、室外兩種,然后美術(shù)通過擺放一個(gè)室內(nèi)環(huán)境用的網(wǎng)格(interior mesh)來標(biāo)記受室內(nèi)光影響的像素。Ambient probe也會(huì)相應(yīng)地為室內(nèi)、室外生成不同的環(huán)境光。

下面看一下對(duì)比,這是沒有開的情況,如果不區(qū)分的話,室內(nèi)跟室外一樣都會(huì)受天光的影響而變得很藍(lán),然后做了室內(nèi)(interior)標(biāo)記,室內(nèi)的像素就能夠正確地反應(yīng)出室內(nèi)的光照條件,會(huì)顯得更黃一些。

而且我們還做了一個(gè)過度的處理,就是在門口這個(gè)區(qū)域當(dāng)室內(nèi)光照和室外光照環(huán)境切換的時(shí)候,不會(huì)出現(xiàn)一個(gè)因?yàn)槊黠@的光照差異不一樣而產(chǎn)生的硬邊的效果。

下面這個(gè)就是室內(nèi)環(huán)境用的網(wǎng)格(interior mesh)生成的Mask標(biāo)記圖,紅色區(qū)域就是室內(nèi)的區(qū)域,大家可以看一下對(duì)照關(guān)系。除了通過Reflection probe得到的反射,我們還有Screen space reflection來提供實(shí)時(shí)的反射信息。SSR在PS4 Pro上面的GPU開銷大概是在1.5毫秒左右,我們對(duì)SSR也加了一個(gè)Temporal filter,通過當(dāng)前幀的SSR信息和歷史信息混合起來,來提高SSR計(jì)算結(jié)果的穩(wěn)定性,讓畫面也更平滑一些。

為了得到更多的反射信息,我們?yōu)镾SR生成了Hi-Z的buffer,我們可以讓每條射線通過Hi-Z最多能夠跟蹤的距離達(dá)到整個(gè)屏幕。

下面是一個(gè)SSR(Screen space reflection)效果開關(guān)的對(duì)比圖,在比較光滑的地板上效果尤其明顯。從前面的截圖大家也能夠看到,在沒有SSR的情況之下,我們還有Reflection probe,它也是可以提供場(chǎng)景的反射信息。我們是使用了一個(gè)Deferred reflection pass來計(jì)算Reflection和Ambient信息。在計(jì)算Reflection的同時(shí),我們把AO信息也考慮進(jìn)去,這樣可以有效地降低漏光。

接下來是我們的最后一個(gè)技術(shù)點(diǎn),HDR Display。這里面的HDR Display包含了兩個(gè)方面,一個(gè)方面是指亮度,需要使用PQ ST2084的EOTF,最高是能夠讓畫面亮度達(dá)到10000 nits。另外一方面就是在色彩空間這邊,我們需要支持Rec.2020色彩空間,Rec.2020色彩空間和現(xiàn)在普遍的電視機(jī)使用的Rec.709相比,它可以顯示的色彩范圍要大得多。大家可以看看在CIE 1931色度圖里面的覆蓋范圍對(duì)比。Rec.2020色彩空間覆蓋范圍大概能達(dá)到75.8%,相比之下Rec.709只能在35.9%的樣子。

在這里我們稱使用了ST2084和Rec.2020色彩空間的渲染管線為HDR管線,而使用的Rec.709色彩空間的非HDR管線,我們把他們叫做SDR管線。關(guān)于HDR Display很多基礎(chǔ)的信息,有很多人都已經(jīng)講過在這里面就不細(xì)講了。下面主要講一下,為了讓這個(gè)技術(shù)放到《原神》里面去,我們做了哪些調(diào)整。

這張圖是《原神》的SDR和HDR的管線對(duì)比圖,和SDR管線相比,HDR管線沒有了tone mapping,color grading變成了HDR的color grading。而代替tone mapping的是RRT+ODT(reference rendering transform + output display transform)的組合,這就是很多人熟悉的ACES調(diào)色。

另外,UI在HDR下面,也是單獨(dú)畫到一張RT的。然后再跟場(chǎng)景做一個(gè)合并,這是因?yàn)閁I的亮度處理方式跟場(chǎng)景是不太一樣的。在圖上大家看到RRT+ODT是灰掉的,我們待會(huì)會(huì)再來細(xì)講這個(gè)事情。

《原神》從1.2開始,會(huì)在PS4上面支持HDR10的模式,然后替換SDR的Color grading是我們的HDR Color grading,美術(shù)會(huì)在Davinci這種軟件上面去做HDR校色。然后通過我們的腳本輸出HDR的Look-Up-Table(LUT)。

在運(yùn)行的時(shí)候,白平衡HDR的Color grading,還有我們的Color expansion這些操作,都會(huì)在一個(gè)compute pass里面,輸出到一張Color的Look-Up-Table里面去。因?yàn)檫@個(gè)Look-Up-Table很小,所以盡管前面提到的這些都是需要大量的計(jì)算操作,但實(shí)際上開銷是很小的,大概不到0.05毫秒。

前面管線圖的RRT+ODT部分是灰掉的,雖然這個(gè)是一個(gè)主流的調(diào)色方式,但是我們并沒有采用它,因?yàn)楹臀覀兊挠螒蝻L(fēng)格不太搭。所以盡管主流,我們還是放棄了。

為了保證在低亮度范圍內(nèi)的畫面和SDR版本的游戲一致,我們將HDR的渲染畫面和tone mapping處理之后的畫面做了一個(gè)基于亮度的混合,然后在亮度不高的地方,就盡量保證了filmic tonemapping的關(guān)于toe部分的處理。

在低亮度范圍內(nèi)一致性的問題,這里面涉及到OOTF的事情。前面我們提到在HDR上面是用了BT1886作為一個(gè)EOTF曲線,然后在設(shè)備處理游戲輸出的時(shí)候會(huì)用到,相應(yīng)的游戲在輸出信號(hào)給電視機(jī)的時(shí)候也會(huì)增加一條曲線,這個(gè)就是OETF。然后在HDR的管線里面,實(shí)際上就是一條gamma曲線。

但是這里面存在一個(gè)問題,就是1886的gamma是2.4,但是SDR的OETF是一個(gè)分段函數(shù),大致上可以看作是gamma 2.2,這就出現(xiàn)了一個(gè)問題,也就是在PPT上寫的問題。OETF處理完的顏色,經(jīng)過EOTF,它得到的并不是它本身,就產(chǎn)生了一個(gè)誤差。

但是在HDR下面,因?yàn)槲覀僌ETF和EOTF是被很好的定義了的情況,所以他們是互逆的,于是這個(gè)顏色在經(jīng)過這兩個(gè)處理之后能夠得到原來的顏色,所以在HDR下面沒有這么一個(gè)問題。

但是大家已經(jīng)習(xí)慣了在HDR下面有這么一個(gè)誤差的畫面,所以為了模擬這個(gè)誤差,我們是在HDR管線里面添加了OOTF,把差異給補(bǔ)上去了。

做完這些,是不是HDR就徹底沒問題了呢?并不是。這還有一個(gè)大坑,叫做Hue Shift。什么解釋一下什么是Hue Shift?

舉個(gè)例子,大家可以看一下游戲里面火焰制作的示意圖,我們通過一個(gè)灰度圖,就是下面像饅頭一樣的東西,加一個(gè)噪聲貼圖,然后進(jìn)行擾動(dòng),得到了火焰擾動(dòng)的紋理,然后我們用橘色去染色。最后我們把火焰的整體亮度往上提,這個(gè)時(shí)候就得到大家可以看到的見證奇跡的時(shí)刻,在SDR下面因?yàn)橛衪one mapping的原因,tone mapping在亮部是有一條曲線的,會(huì)讓亮度增加逐漸變慢,于是橘色的R通道跟G通道的差異本來是很大,但是隨著亮度的增加,tone mapping曲線介入了,R通道的增長(zhǎng)就變慢,G通道就逐漸趕了上來,于是就產(chǎn)生了Hue Shift,畫面漸漸開始發(fā)黃,于是就得到了后面看到的SDR下面火焰的效果。

但是這個(gè)是美術(shù)想要的一個(gè)效果,只不過他是通過這種神奇的方式得到的。但是問題來了:因?yàn)樵贖DR下面,我們是沒有tone mapping的,Hue Shift是不會(huì)發(fā)生的。它叫做Hue Preserving。R通道跟G通道的比例關(guān)系是得到一個(gè)保持的,所以能夠得到亮度非常高的橘色。但是在視覺上,不會(huì)讓人家覺得很明亮,因?yàn)闆]有黃色。

那怎么去修改呢?一種常用的方法,也是很多大作都用的方法,叫做黑體輻射。這是一個(gè)基于物理的算法,美術(shù)去指定溫度,根據(jù)溫度計(jì)算出應(yīng)該是什么顏色。通過這種方式,我們是需要修改美術(shù)的資源。不過我們沒有采用這種方式,為什么?一方面是因?yàn)镠DR 這個(gè)功能是在很后期才加入的,我們不能夠讓美術(shù)去大量修改已有的資源。

另外游戲并不是寫實(shí)類的游戲,我們的火可以是各種顏色,而且還有很多其他的特效是隨著元素反應(yīng)去轉(zhuǎn)換顏色的。所以我們自己搞了一個(gè)方法,我們?cè)趕hader里面去模擬了Hue Shift,并且把模擬放到了color grading pass里面去,合并到Look-Up-Table的計(jì)算中。

這樣的好處是,首先我們是不需要修改任何的效果,得到的效果非常滿意,我們不僅僅是讓火焰特效在HDR下面的效果跟SDR幾乎一致。而且因?yàn)橥ㄟ^引入tone mapping的方式模擬了Hue Shift,所以我們前面提到的在非HDR的亮度部分的畫面一致性的問題,也被順手解決掉了,不需要跟tone mapping處理之后的畫面做混合。而且這個(gè)操作,也是在生成Look-Up-Table的時(shí)候去做的,所以它的性能增加是可以忽略不計(jì)的。

技術(shù)介紹我們就到這里介紹了,下面是我一些個(gè)人的總結(jié)和感想。

首先是全球玩家對(duì)《原神》主機(jī)版的接受程度之高是出乎我們的預(yù)料,非常誠(chéng)惶誠(chéng)恐,也非常的感慨。從零開始,我把PS4版做起來,看著它逐漸地變化,就像看著自己的孩子逐漸長(zhǎng)大一樣。隨著PS版越做越完善,很多的小伙伴就逐漸加入了開發(fā)隊(duì)伍中,于是PS4版變成了大家的孩子,大家努力讓它變得更好,最后就懷著忐忑的心情送出來跟全球玩家見面。沒想到現(xiàn)在這么受歡迎,所以是一件非常有成就感的事情。而且很開心,能夠和這么好的團(tuán)隊(duì)一起做這個(gè)項(xiàng)目,后面我們也會(huì)繼續(xù)努,不斷地改進(jìn),也不斷地去優(yōu)化,不斷地出更好的內(nèi)容給大家。

就像前面提到的,《原神》的主機(jī)版開發(fā)是第一次嘗試,時(shí)間、資源和人才都很缺乏。通過一年多的開發(fā),我們積累了很多的經(jīng)驗(yàn),尤其是如何把寫實(shí)的渲染技術(shù)跟風(fēng)格化游戲結(jié)合的經(jīng)驗(yàn),非常的寶貴!隨著新的主機(jī)平臺(tái)的到來,我們又面臨了一大波的技術(shù)升級(jí)。不過和在美國(guó)的時(shí)候相比,國(guó)內(nèi)主機(jī)開發(fā)的從業(yè)人員太少了,希望大家能夠多多交流,和我們探討一下技術(shù),交流一下開發(fā)經(jīng)驗(yàn)。

我這次的分享就結(jié)束了,感謝大家!

0.027996s
延边| 温宿县| 岗巴县| 长丰县| 利辛县| 惠东县| 法库县| 织金县| 霸州市| 邵武市| 泸溪县| 新疆| 丽江市| 辽宁省| 安丘市| 通许县| 信丰县| 桦甸市| 绥芬河市| 佳木斯市| 诸暨市| 辽阳县| 桓仁| 资溪县| 和林格尔县| 滦平县| 镇坪县| 沙洋县| 元阳县| 新昌县| 昭平县| 张家港市| 张北县| 曲阜市| 荆门市| 云浮市| 冷水江市| 郴州市| 永泰县| 白城市| 元江|