2020年11月17日晚的Unity線上技術(shù)大會中钠至,米哈游技術(shù)總監(jiān)弋振中《原神》在主機平臺上的渲染技術(shù)要點葛虐,主要包括了陰影,AO,Local Light,Volumetric Fog & God Ray效果牲尺,Reflection以及HDR等多個方向的主要內(nèi)容,這里是原文傳送的诵,下面我們將對其主要內(nèi)容進(jìn)行學(xué)習(xí)與梳理,希望在后續(xù)工作中能夠有所助益佑钾。
1. 陰影
陰影的實現(xiàn)分為動態(tài)陰影與烘焙陰影兩項西疤,動態(tài)陰影這里使用的是8級的CSM方案覆蓋800米視距,其中前面四級陰影每幀更新次绘,后面四級陰影則是輪流更新(即輪流間隔四幀更新一次)。
軟影采用的是泊松圓盤Random Sample Pattern的PCF邮偎,每個像素對應(yīng)的Sample數(shù)目為11個這個會導(dǎo)致較高的計算消耗,為了降低這一塊的消耗豁跑,使用了一個mask貼圖來標(biāo)記屏幕上各個區(qū)域的陰影屬性,只對處于半影區(qū)的像素進(jìn)行軟影PCF計算艇拍。
Mask貼圖使用的是分辨率為屏幕分辨率的1/4 x 1/4卸夕,正常來說婆瓜,要判斷Mask貼圖中的某個像素是否屬于半影(繪制輸出Mask貼圖)贡羔,就需要對屏幕分辨率下這個像素所覆蓋的16個像素進(jìn)行遮擋判斷乖寒,之后整合輸出(視頻中沒有給出,所謂的整合輸出指的是求取平均值嗎院溺?)當(dāng)前像素的半影判斷結(jié)果楣嘁,但是這種做法會有較高的消耗,為了進(jìn)一步提高計算效率珍逸,決定采用抽樣調(diào)查算法逐虚,從16個子像素中按照一定的pattern抽取樣本進(jìn)行判斷,這種做法會有一定的誤差(某些本該是軟影的被錯認(rèn)為只有硬影)弄息,為了降低誤差痊班,這里會對Mask貼圖進(jìn)行模糊處理(擴大了半影的半徑),這樣一定程度上可以緩解前面將軟影錯認(rèn)為硬影的誤差摹量。
整個Mask貼圖的生成與模糊處理消耗大概為0.3ms左右,而整個陰影計算的GPU消耗大概為1.3~1.7ms左右馒胆,而優(yōu)化開關(guān)的陰影質(zhì)量基本上肉眼無法區(qū)別缨称。
2. AO
陰影只能表示對光照的宏觀的單層的遮擋效果,卻無法模擬細(xì)微的多層(指多光源作用)的效果祝迂,比如處于陰影中的地面睦尽,只使用陰影的話,將無法模擬地面上的其他物體在其上的投影型雳,從而顯得物件懸空当凡。這些瑕疵可以通過Ambient Occlusion方案來解決,而《原神》提供了多種AO方案纠俭,可以針對不同的情景進(jìn)行選擇使用沿量。
2.1 HBAO
HBAO是horizon based ambient occlusion的縮寫(另外,這里需要注意的是冤荆,我們平時說HDAO(High Definition Ambient Occlusion)與HBAO朴则,其實這兩者是等價的,只是前者是AMD給出的稱呼而后者是NVidia給出的名字)钓简,這是一種非常常規(guī)的AO方案乌妒,可以通過屏幕空間的后處理來為物件提供更為細(xì)膩的細(xì)節(jié)表現(xiàn),其基本實現(xiàn)原理為:通過對各個方向上的深度進(jìn)行采樣求得最大遮擋角度撤蚊,通過對各個方向上的最大遮擋角度的正弦進(jìn)行累加來得到AO侦啸,這個算法的質(zhì)量比SSAO要好夏漱,實現(xiàn)邏輯更加物理真實挂绰,但是其性能消耗會比較高葵蒂,業(yè)界通常使用的是其優(yōu)化版HBAO+缺厉。具體可以參考此前關(guān)于AO實現(xiàn)算法的一篇綜述:Ambient Occlusion技術(shù)方案綜述命爬。
2.2 AO Volume
AO Volume是為靜態(tài)物體所開發(fā)的AO方案嗜价,相對于HBAO而言,AO Volume可以生成更大尺寸的遮擋效果,如上圖所示潮模,對于這類近似陰影效果的AO,HBAO算法是無能為力的芬探,因此這里需要增加額外的AO Volume算法邏輯偷仿。
AO Volume的實現(xiàn)邏輯可以參考此前做過的一篇AO算法的綜述分享。
《原神》中對于AO Volume的使用方案是别智,在離線的時候完成靜態(tài)物體的AO數(shù)據(jù)的烘焙薄榛,之后在運行時根據(jù)烘焙數(shù)據(jù)計算出最終的遮擋效果蛇数。
2.3 Capsule AO
靜態(tài)物體的陰影可以通過lightmap+AO Volume來實現(xiàn)碌上,而動態(tài)物體的陰影如果僅僅依靠HBAO的話會顯得過于簡陋馏予,但是如果額外增加一個shadow map用于應(yīng)付這種情況又會顯得過于浪費呢岗,《原神》這邊的做法是通過Capsule AO來為動態(tài)物件(比如角色)等添加(相對于HBAO)更為精細(xì)的陰影效果后豫。
Capsule AO的具體實現(xiàn)原理可以參考之前的AO算法的綜述分享挫酿,簡單來說早龟,這個算法是通過用多個膠囊體(會跟隨角色的骨骼發(fā)生位置等變換)對角色進(jìn)行模擬壹店,之后通過計算膠囊體在待渲染位置上半球的投影面積占比實現(xiàn)對環(huán)境光AO(或者陰影)的輸出硅卢,通過計算膠囊體在帶渲染位置以主光源方向為軸線方向老赤,以一定的角度為錐角的圓錐上的占比來計算主光源AO(陰影)抬旺,從而實現(xiàn)更為精細(xì)的AO(陰影)效果开财。
2.4 AO的優(yōu)化處理
為了提升AO計算的性能责鳍,《原神》這邊所有的AO計算都是在1/2分辨率上進(jìn)行的历葛,且在計算完成后恤溶,為了進(jìn)一步柔化效果減少瑕疵咒程,這里還會增加一個雙線性模糊處理(橫向+縱向)帐姻,最后在使用的時候饥瓷,還會需要一個額外的上采樣過程(這個在使用的時候直接使用1/2分辨率的貼圖就可以扛伍,應(yīng)該不再額外需要一個上采樣)鳖宾。
在進(jìn)行模糊處理的時候逆航,每個像素需要采取周邊多個像素的數(shù)值進(jìn)行混合拇惋,可以看到撑帖,如果使用傳統(tǒng)的PS胡嘿,每個像素都會需要多次貼圖采樣衷敌,且這些采樣結(jié)果實際上是可以在相鄰其他像素的計算中進(jìn)行重用的缴罗,因此為了進(jìn)一步提升計算性能面氓,《原神》這里的做法是將模糊處理放到Compute Shader中來完成。
具體的做法是,將相鄰像素的采樣結(jié)果存儲在局部存儲空間(Local Data Share)中屁药,之后再模糊的時候取用复亏,一次性完成四個像素的模糊計算缭嫡,并將結(jié)果輸出耕突。
3. Local Light
《原神》采用的渲染管線是Clustered Deferred lighting(詳情可以參考此前的分享:常見渲染管線整理與總結(jié) - Clustered Forward Rendering),將場景劃分為16個slice炕泳,每個slice的尺寸為64x64個像素培遵,最多可以支持到1024盞局部光源籽腕。
上面這張圖中展示了多個局部光源的光陰效果,可以看到廊宪,局部光源也是有實時陰影的箭启,但是并不是所有的局部光源都會添加投影(應(yīng)該是美術(shù)同學(xué)控制的),這里說到支持實時陰影的局部光源數(shù)不超過100盞北救。
整體的陰影效果由烘焙的靜態(tài)陰影與動態(tài)陰影(推測使用的是陰影貼圖托启,但是計算消耗會很高屯耸,其中做了什么優(yōu)化疗绣,從給出的材料中難以推斷)的結(jié)合。
對于局部光源的靜態(tài)陰影而言塔逃,需要烘焙對應(yīng)的shadow map,由于光源數(shù)目較多,每盞燈都烘焙丙挽,會導(dǎo)致硬盤空間占用較大颜阐,且由于shadow map是一張深度貼圖凳怨,也不能使用Block Compression進(jìn)行壓縮肤舞,為了解決這個問題李剖,《原神》團(tuán)隊自己設(shè)計了另外一套壓縮思路篙顺。
具體思路(參考了Siggraph 2019的文章A Scalable Real-Time Many-Shadowed-Light Rendering System)給出如下:
- 對原始的shadow map以2x2為block進(jìn)行壓縮,每個block包含4個深度值宰僧,總共使用32bits進(jìn)行保存(如果需要更高的精度,也可以使用64bits)键兜,具體的編碼方法暫時未知。
- 每個block的編碼方式有兩種:
2.1 基于深度平面方程進(jìn)行編碼(即對四個深度值進(jìn)行共面計算现诀,輸出AX+BY+CZ+D=0平面方程中的ABCD四個參數(shù))
2.2 通過浮點數(shù)壓縮算法將FP16轉(zhuǎn)換為FP11坐桩? - 通過Quad Tree對block進(jìn)行匯總绵跷,輸出稀疏四叉樹,通過這種方式進(jìn)一步提升壓縮率。這里的四叉樹不是全局的像啼,而是將整個貼圖分成多個tile,每個tile包含64x64個像素(即16x16個blocks)萄传。
這個方案的表現(xiàn)為甚颂,在室內(nèi)場景的精度壓縮比為0.2 ~ 0.3左右(即從10k壓縮到2 ~ 3k,效果上可能會存在輕微瑕疵)秀菱,高精度模式下的壓縮比為0.4 ~ 0.7(瑕疵基本上難以肉眼辨別)振诬。
4. Volumetric Fog & God Ray效果
首先基于相機空間,將整個frustum分割成多個voxel衍菱,這些voxel跟前面clustered deferred lighting中的cluster是一致的赶么,這種設(shè)定有助于后續(xù)局部光源的scattering計算。
更新每個voxel上的光照數(shù)據(jù)脊串,在這個過程中會考慮到fog參數(shù)與局部光作用
使用raymarching算法對射線上的voxel進(jìn)行數(shù)據(jù)進(jìn)行累加,將累加結(jié)果輸出
體積霧計算方式本身就能夠?qū)崿F(xiàn)God Ray效果缕坎,但是用這種方式實現(xiàn)的God Ray可能會不太明顯(由于voxel數(shù)目少,導(dǎo)致這種做法輸出的貼圖分辨率比較低,且由于霧氣濃度可能不足以產(chǎn)生God Ray企孩,都會使得God Ray效果不明顯)补疑,這里《原神》團(tuán)隊為了使得God Ray效果更好看一些锹杈,使用了一個額外的Ray Marchingpass用于實現(xiàn)God Ray,并且還添加了一些額外的參數(shù),在ray marching結(jié)束之后會使用這些參數(shù)來對God Ray效果做進(jìn)一步調(diào)整杖小,從而產(chǎn)生更為美觀的藝術(shù)效果(雖然并不物理)扫腺。
5. Reflection
5.1 IBL
視頻里展示的場景Reflection Probe與Ambient Probe都是隨著時間24小時連續(xù)變化的,而傳統(tǒng)的反射貼圖等都是離線Capture的蒋荚,通常不能做到隨著時間而變化播赁,那么這個表現(xiàn)是如何實現(xiàn)的呢?
5.1.1 Reflection Probe
對Reflection Probe而言耿戚,這里的做法是不再直接烘焙一張環(huán)境貼圖墅茉,而是烘焙一套mini GBuffer貼圖(包括Normal/Depth/Albedo等信息)洋魂,之后根據(jù)當(dāng)時的光照數(shù)據(jù)實時生成環(huán)境貼圖(Reflection Cubemap)膀懈,跟傳統(tǒng)Reflection Probe一樣疑苫,美術(shù)同學(xué)也可以在場景中擺放大量這樣的Probe不瓶。
實時生成環(huán)境貼圖主要通過如下幾步完成:
- Relight泥兰,根據(jù)當(dāng)前的光照數(shù)據(jù)雁刷,利用mini GBuffer的相關(guān)數(shù)據(jù)智末,進(jìn)行一遍Lighting計算
- Convolve何乎,對Lighting完成后的cubemap结洼,先生成mip-chain,之后對每級mipmap進(jìn)行卷積運算更扁,目的是得到各個面能夠正確銜接mip貼圖风范。
- Compress硼婿,為了降低cubemap的內(nèi)存消耗,這里還使用了BC6H壓縮算法對cubemap進(jìn)行壓縮處理
整個過程是通過Compute Shader完成的特笋,在Compute Shader中通過多個線程可以同時完成六個面的處理侥猩,且由于單個Reflection Cubemap的更新其實已經(jīng)比較費了榔至,為了減輕單幀壓力,這里將Reflection Cubemap的更新分散到多幀進(jìn)行欺劳,每幀只對一個Probe進(jìn)行更新唧取,通過時間輪轉(zhuǎn)完成所有Probe的更新铅鲤。
5.1.2 Ambient Probe
前面更新完Reflection Probe之后,就得到了當(dāng)前Probe的光場數(shù)據(jù)兵怯,而Ambient Probe的光照數(shù)據(jù)就是從這個光場中提取出來的彩匕,而由于Ambient Probe的低頻特性,這里可以用SH系數(shù)來保存整個光場媒区,進(jìn)一步壓縮內(nèi)存消耗驼仪。
光場提取也是通過Compute Shader實現(xiàn),一次性完成6個面的計算處理袜漩。
5.1.3 改進(jìn)
在完成上述步驟之后绪爸,能夠得到隨著時間動態(tài)變化的光照信息,但是還存在一些問題:
- 陰影數(shù)據(jù)缺失宙攻,mini GBuffer無法完成陰影重建
- Relight計算過程只考慮了主光源奠货,如果需要考慮局部光源的話,會導(dǎo)致大量消耗
- 室內(nèi)外光照環(huán)境不一致問題座掘,因為光照環(huán)境不一致递惋,如果不做處理,會讓人感覺到不和諧
針對這些問題溢陪,《原神》給出了如下的解決方案:
- 陰影缺失問題萍虽,通過在離線的時候?qū)?4小時的陰影數(shù)據(jù)烘焙后用Shadow SH系數(shù)保存下來,在運行時根據(jù)當(dāng)前的時間選擇對應(yīng)的Shadow SH進(jìn)行插值解決形真,且從效果上來看基本上看不出瑕疵
- 局部光源的Relight問題杉编,也可以采用與Shadow缺失同樣的解決方案,在離線的時候?qū)⒕植抗庠碨H保存下來咆霜,在Relight的時候進(jìn)行使用
- 室內(nèi)外光照環(huán)境不一致的問題是通讓Reflection Probe與Ambient Probe在室內(nèi)與室外進(jìn)行不同的處理來解決的邓馒,為了更精確的標(biāo)注室內(nèi)的范圍,美術(shù)同學(xué)還需要額外擺放一個interior mesh蛾坯,下面是效果對比
此外光酣,為了避免在室內(nèi)外過渡區(qū)域出現(xiàn)硬切,這里還在過渡區(qū)域處進(jìn)行一下平滑處理脉课,下面是根據(jù)interior mesh生成的Mask貼圖:
Reflection & Ambient Probe在使用的時候會同時將AO數(shù)據(jù)也考慮進(jìn)去挂疆,這樣可以有效減輕漏光問題。
5.2 Screen Space Reflection
SSR在PS4 Pro上的開銷是1.5ms左右下翎,為了增強顯示質(zhì)量缤言,還添加了一個Temporal filter來混合歷史數(shù)據(jù);此外视事,為了能夠快速得到各種粗糙度下的反射結(jié)果胆萧,這里還為SSR生成了一個類似于Hi-Z的buffer貼圖。
6. HDR
這個原文比較詳細(xì)了,就不贅述了