今天來(lái)學(xué)習(xí)下《殺戮地帶-暗影墜落》(以下簡(jiǎn)稱《暗影》)在GDC2014年上的技術(shù)分享氓仲,下面是原文鏈接邮偎。
本文內(nèi)容主要包括《暗影》開(kāi)發(fā)過(guò)程中的重要里程碑夸赫,追尋下一代圖形效果的過(guò)程介紹以及一些塑造了最終效果的一些關(guān)鍵技術(shù)的實(shí)施細(xì)節(jié)介紹:
《暗影》項(xiàng)目開(kāi)始于2011年锭亏,下面是早期規(guī)劃的一些目標(biāo):
由于《暗影》瞄準(zhǔn)的全新的硬件平臺(tái),因此項(xiàng)目開(kāi)發(fā)早期充滿著摸索與艱辛:
下面是第一個(gè)demo的效果(提供基礎(chǔ)的游戲交互體驗(yàn)十绑,場(chǎng)景中只包含一些主要元素):
過(guò)了兩個(gè)月推出第二個(gè)demo酪夷,主區(qū)域基本完好,沒(méi)有添加光照跟特效:
又過(guò)了三個(gè)月孽惰,第三個(gè)demo晚岭,物體表現(xiàn)基本接近最終效果,已經(jīng)添加了主要的特效與光照勋功,還加了反射效果坦报。
第四個(gè)demo,開(kāi)始質(zhì)量上的迭代過(guò)程(第二輪美術(shù)方向迭代)狂鞋,在美化與優(yōu)化之間打轉(zhuǎn)片择。這個(gè)過(guò)程中為了方便直觀看到表現(xiàn)的變化,Guerrilla工作室開(kāi)發(fā)了一個(gè)自動(dòng)統(tǒng)計(jì)工具骚揍,定時(shí)跑圖并統(tǒng)計(jì)場(chǎng)景中的一些相關(guān)信息(內(nèi)存字管,性能等)。
《暗影》發(fā)布demo信不,添加了體積霧
上面展示的是單個(gè)場(chǎng)景的開(kāi)發(fā)節(jié)點(diǎn)嘲叔,實(shí)際上還有很多其他場(chǎng)景也在同步開(kāi)發(fā)當(dāng)中,下面來(lái)從asset的角度來(lái)對(duì)下一代圖形效果的含義進(jìn)行解釋抽活,這里給出《殺戮地帶2》跟兩部《殺戮地帶3》的尺寸對(duì)比:
Killzone 2 -> Corinth River (1st level)
Killzone 3 -> Pyrrhus Outskirts (2nd level)
Killzone SF -> Pyrrhus Deep (8th level)
場(chǎng)景尺寸上硫戈,《暗影》要比上一代《殺戮地帶3》打上10~100倍。這種急劇擴(kuò)展對(duì)于開(kāi)發(fā)而言帶來(lái)了不少問(wèn)題:
- 原有的引擎不再適用于如此大尺寸的開(kāi)放場(chǎng)景
- 尺寸過(guò)大會(huì)導(dǎo)致浮點(diǎn)精度的問(wèn)題
- 大量的幾何物體與復(fù)雜的光照
- 每個(gè)level section包含一萬(wàn)到兩萬(wàn)五千個(gè)幾何物體實(shí)例下硕,實(shí)例不等于DP
- 200個(gè)靜態(tài)光源與200個(gè)烘焙光源以及其他數(shù)百個(gè)動(dòng)態(tài)光源(粒子丁逝,爆炸,開(kāi)槍火光等)
- 復(fù)雜的模型
- 頂點(diǎn)與像素細(xì)節(jié)豐富程度上升到了4倍
- 每個(gè)角色身上的面片數(shù)大概是4萬(wàn)左右
- 使用的材質(zhì)也變得更為復(fù)雜(占用貼圖數(shù)為6~12張)
為了應(yīng)對(duì)上述轉(zhuǎn)變梭姓,這里就需要一個(gè)專為PS4所開(kāi)發(fā)的第四代引擎霜幼,這個(gè)引擎應(yīng)該要具備如下特征:
下面對(duì)這些特征的具體細(xì)節(jié)進(jìn)行詳細(xì)介紹。
光照開(kāi)發(fā)過(guò)程中學(xué)到的非常重要的一課是誉尖,千萬(wàn)不要對(duì)光照罪既,反射以及半透物件分開(kāi)進(jìn)行處理,跟光照相關(guān)的這些特征與信息實(shí)際上都是相輔相成的,多個(gè)看似獨(dú)立的特征應(yīng)該要具有一致的表現(xiàn)萝衩,否則會(huì)顯得非常的別扭回挽。
這個(gè)圖是《暗影》為材質(zhì)調(diào)優(yōu)而單獨(dú)創(chuàng)建的“Shader Zoo”場(chǎng)景的截圖。
在開(kāi)發(fā)過(guò)程中認(rèn)識(shí)到猩谊,PBR系統(tǒng)實(shí)際上存在不少的局限性千劈,比如,由于菲涅爾效應(yīng)的存在牌捷,會(huì)使得物件變得比較shiny墙牌,然而很多美術(shù)同學(xué)希望在部分材質(zhì)上實(shí)現(xiàn)全diffuse光照效果,或者其他的比如只反射50%光照的需求暗甥,這就需要對(duì)模型進(jìn)行反復(fù)的調(diào)整喜滨,對(duì)于使用人員來(lái)說(shuō)是一個(gè)不小的挑戰(zhàn)。
開(kāi)發(fā)過(guò)程中發(fā)現(xiàn)面光源效果非常好撤防,因此考慮將所有的光源都用面光源來(lái)代替虽风,這種做法還有其他的好處:
- 可以通過(guò)調(diào)高cos指數(shù)的數(shù)值以及強(qiáng)度來(lái)模擬大面積的高光效果
- 可以避免其他光照類型在日夜循環(huán)中的不連貫表現(xiàn)(breaks,斷裂寄月,為什么會(huì)有這種表現(xiàn)辜膝?)
這個(gè)場(chǎng)景中的大部分光照都是來(lái)自于實(shí)時(shí)反射與cubemap。為了保持光照的一致性漾肮,Guerrilla將反光結(jié)果做得跟直接光照結(jié)果高度一致厂抖。下面再來(lái)看下間接光的一些實(shí)施細(xì)節(jié)。
這個(gè)視頻對(duì)比了間接光與lighting only(直接光加間接光)之間的效果差異克懊,可以看到間接光對(duì)于《暗影》有著重要的貢獻(xiàn)忱辅,尤其是在一些HDR管線中,一些較暗場(chǎng)景要想擁有較好的視覺(jué)效果就必須要依賴于間接光谭溉。
Guerrilla此前的項(xiàng)目中墙懂,光照的做法是,對(duì)于動(dòng)態(tài)物件夜只,直接分配一個(gè)probe垒在,而靜態(tài)物件則直接使用lightmap(lightmap難用且存在較大浪費(fèi),因?yàn)樾枰紤]padding扔亥,UV Shells之間的空白區(qū)域等)
期望結(jié)果是一張干凈整潔的貼圖,而實(shí)際上由于存在著眾多小尺寸貼圖谈为,考慮padding以及貼圖之間的縫隙旅挤,整個(gè)貼圖看起來(lái)非常混亂(對(duì)于計(jì)算機(jī)而言不混亂就行了伞鲫,有什么關(guān)系粘茄?)。
最終Guerrilla決定在《暗影》項(xiàng)目中直接使用light-probe cloud來(lái)對(duì)所有的物體進(jìn)行光照計(jì)算,這樣就不用的單獨(dú)對(duì)動(dòng)態(tài)物件跟靜態(tài)物件進(jìn)行分開(kāi)處理了柒瓣,實(shí)現(xiàn)邏輯是清晰了不少儒搭。light probe是在延遲pass的PS中使用的,最終給出的效果在所有物體上(不論大小動(dòng)靜)都是一致的芙贫。
這里是light-probe的debug view(debug view中沒(méi)有給出AO數(shù)據(jù))
這里是這套系統(tǒng)的實(shí)施細(xì)節(jié)搂鲫,根據(jù)重要程度不同,light-probe覆蓋的區(qū)域也有所變化磺平。
看下側(cè)視圖魂仍,light-probe一般放置在幾何物體附近的空白區(qū)域。
probe的放置會(huì)按照四面體的方式來(lái)進(jìn)行組織(方便進(jìn)行插值拣挪,可以允許probe放置在任意位置)擦酌,不過(guò)在現(xiàn)在的情況下,系統(tǒng)可能會(huì)生成一些非常長(zhǎng)的四面體菠劝,這就會(huì)導(dǎo)致插值精度的下降赊舶。
這里的解決方案是,在一些找不到第四個(gè)頂點(diǎn)或者第四個(gè)頂點(diǎn)距離較遠(yuǎn)的地方放置一些額外的probe赶诊,這些probe數(shù)量通常比較少笼平,這種做法能夠有效的減輕前面的問(wèn)題,同時(shí)也能夠?yàn)槟切┻h(yuǎn)離了靜態(tài)物體的動(dòng)態(tài)物體提供精度更高的光照信息(因?yàn)橹饕膌ight-probe都是依托靜態(tài)物件放置的)甫何,下面來(lái)看下直觀的效果展示:
一個(gè)靜態(tài)場(chǎng)景內(nèi)部
將之進(jìn)行voxelize
靠墻放置主要的light probes
填充輔助probes出吹,下面看下另外一個(gè)場(chǎng)景的表現(xiàn):
下面介紹light-probe方案的實(shí)施細(xì)節(jié),要想在PS中獲取light-probe數(shù)據(jù)進(jìn)行光照計(jì)算辙喂,就需要找到像素所對(duì)應(yīng)的四面體捶牢。這里的做法是,將四面體分割成一個(gè)個(gè)稀疏均勻網(wǎng)格(sparse uniform grid)巍耗,之后再這個(gè)基礎(chǔ)上構(gòu)建一個(gè)BSP樹(shù)秋麸,這樣就可以實(shí)現(xiàn)快速查找了。
開(kāi)發(fā)中發(fā)現(xiàn)四面體可能會(huì)與墻面發(fā)生穿插炬太,從而導(dǎo)致漏光問(wèn)題灸蟆。圖中藍(lán)色的線條表示的是一種解決方案:occlusion split plane(遮擋分割平面)。在需要的時(shí)候存儲(chǔ)遮擋分割平面信息(最多三個(gè))亲族,通過(guò)對(duì)這個(gè)數(shù)據(jù)進(jìn)行查詢來(lái)忽略墻面另一邊的light probe的作用炒考;圖中棕色折線表示的是另一種解決方案:對(duì)于一些復(fù)雜的幾何物體,這里會(huì)需要存儲(chǔ)triangular occlusion shadow maps(每個(gè)四面體最多四個(gè))霎迫,其基本思想跟shadow map相似斋枢,通過(guò)判斷當(dāng)前像素到probe的距離與shadow map上的數(shù)值來(lái)判斷當(dāng)前像素是否會(huì)受到probe的光照影響。
由于這套系統(tǒng)開(kāi)發(fā)時(shí)間過(guò)晚知给,導(dǎo)致并沒(méi)有完全取代原始的lightmap方案瓤帚。目前只用于動(dòng)態(tài)物體上在gameplay區(qū)域之外的地方描姚。
下面看下粒子系統(tǒng)上的光照方案,在粒子系統(tǒng)上施加光照會(huì)使得場(chǎng)景看起來(lái)更為生動(dòng)真實(shí)戈次。
大多數(shù)的項(xiàng)目都沒(méi)有考慮粒子系統(tǒng)的光照問(wèn)題轩勘,而部分項(xiàng)目則是直接在前向渲染中對(duì)粒子系統(tǒng)進(jìn)行光照計(jì)算,但這種做法有不少的問(wèn)題怯邪,其中一個(gè)限制就是由于大量的overdraw绊寻,有限的shadow maps會(huì)使得渲染速度非常慢。
Guerrilla這邊希望粒子系統(tǒng)的光照效果能夠跟環(huán)境實(shí)現(xiàn)良好的匹配擎颖,當(dāng)然榛斯,性能是不可忽略的因素。
《暗影》的粒子光照是按照普通物體相同的延遲渲染方式進(jìn)行計(jì)算的搂捧。這里增加了一張額外的小尺寸G-buffer用于存儲(chǔ)每個(gè)粒子所對(duì)應(yīng)的多個(gè)參考點(diǎn)(reference points)數(shù)據(jù)驮俗,參考點(diǎn)數(shù)目可變,這個(gè)是通過(guò)一個(gè)LOD來(lái)進(jìn)行控制允跑,LOD切換方案由美術(shù)同學(xué)主導(dǎo)王凑,可以用于實(shí)現(xiàn)一套穩(wěn)定的效果表現(xiàn)。由于每個(gè)粒子代表的是一個(gè)volume聋丝,而非一個(gè)面片索烹,因此法線數(shù)據(jù)實(shí)際上應(yīng)該要朝外彎曲。
這個(gè)視頻給出了實(shí)施效果以及對(duì)應(yīng)的G-buffer數(shù)據(jù)變化弱睦,每級(jí)LOD中的8x8或者4x4點(diǎn)數(shù)據(jù)會(huì)在內(nèi)存中緊挨著存放(方便cache百姓?)。
延遲粒子光照是集成到普通光照pass中的况木,在on-screen light之后計(jì)算垒拢,還可以對(duì)shadow map數(shù)據(jù)進(jìn)行重用。
霧氣或者灰塵在平時(shí)渲染的時(shí)候效果不是很明顯火惊,看起來(lái)就像是透明的一樣求类,但是在強(qiáng)光作用下的可見(jiàn)性就會(huì)變化非常顯著。
粒子系統(tǒng)光照計(jì)算框架沒(méi)什么特別的,跟其他物體的光照計(jì)算一致,這就避免了單獨(dú)一套處理邏輯而導(dǎo)致的效果不一致問(wèn)題仿畸,方便擴(kuò)展。缺點(diǎn)就在于G-buffer尺寸限制了所能支持的粒子的數(shù)目寿弱,在粒子間進(jìn)行光照插值可能會(huì)存在較為明顯的痕跡。
給出帶光照與不帶光照粒子系統(tǒng)的效果對(duì)比按灶,粒子系統(tǒng)上的柔軟光照還能模擬一種散射效果脖捻。接下來(lái)看看陰影優(yōu)化相關(guān)的內(nèi)容:
導(dǎo)致陰影渲染高消耗的原因有很多,除了下面列舉的這些之外:陰影渲染時(shí)需要對(duì)很多細(xì)小物件進(jìn)行渲染兆衅,以及當(dāng)光照方向跟地平線夾角很小時(shí),會(huì)導(dǎo)致每個(gè)cascade都塞滿了物件——這兩個(gè)也是重要的原因:
下面先給出局部光源的優(yōu)化方案:
對(duì)于靜態(tài)物體跟靜態(tài)光照而言,這里的做法是在離線的時(shí)候創(chuàng)建shadow proxy羡亩,之后運(yùn)行時(shí)使用proxy來(lái)替代物體進(jìn)行shadow map渲染摩疑。
為了提升shadow 渲染的效率,這里還會(huì)通過(guò)減面方法(light volume剔除畏铆,back face剔除雷袋,遮擋剔除等)移除那些不可能產(chǎn)生陰影的面片,大概能做到60~80%的優(yōu)化力度(猜測(cè)這個(gè)方法就是用來(lái)進(jìn)行proxy創(chuàng)建的)辞居。
為了節(jié)省Draw Call楷怒,這里應(yīng)該是通過(guò)某種合批渲染方法,將對(duì)應(yīng)于同一個(gè)light的所有物件一次性繪制了瓦灶。
動(dòng)態(tài)物件會(huì)在靜態(tài)物件shadow map的基礎(chǔ)上進(jìn)行渲染鸠删。
上面兩圖分別是為spot light制作的proxy的過(guò)程說(shuō)明,前者是原始模型贼陶,后者是優(yōu)化后的proxy模型刃泡。
由于太陽(yáng)光覆蓋面積大,覆蓋物件多碉怔,因此此前對(duì)局部光源的優(yōu)化方法不能直接用在太陽(yáng)光上烘贴。這里采用的是一種混合優(yōu)化方法:
- 烘焙陰影貼圖
- Proxy delta mesh(含義暫時(shí)不明,推測(cè)跟前面局部光源的shadow proxy類似)
這里給了個(gè)視頻展示撮胧,分別介紹了太陽(yáng)光陰影的實(shí)現(xiàn)方案的各個(gè)部分:
- 使用小尺寸的shadow map來(lái)對(duì)整個(gè)場(chǎng)景進(jìn)行覆蓋桨踪,這個(gè)shadow map渲染時(shí)的分辨率為16k x 16k,不過(guò)后面會(huì)降分辨率輸出(降低存儲(chǔ)空間芹啥,內(nèi)存锻离,同時(shí)得到軟影效果),shadow map主要用于捕獲大尺寸細(xì)節(jié)
- Signed Distance Field(SDF叁征,存儲(chǔ)每個(gè)點(diǎn)到最近的陰影邊緣的距離)用于維持陰影邊緣細(xì)節(jié)
- 跟局部光源一樣的Shadows Proxy Mesh纳账,不過(guò)這里的Mesh只包含陰影貼圖中所忽略的面片數(shù)據(jù)(陰影貼圖忽略了哪些面片?)
這里給出了這個(gè)方案的一些優(yōu)劣對(duì)比捺疼,實(shí)踐證明疏虫,單獨(dú)使用shadow map跟SDF的效果就已經(jīng)足夠好了,而在后面兩個(gè)cascade中甚至只需要shadow map就已經(jīng)足夠啤呼。
下面看下體積光的實(shí)現(xiàn)方案卧秘,先來(lái)看一個(gè)視頻:
因?yàn)轶w積光對(duì)于《暗影》效果的影響非常顯著,因此這里基本上所有的光源都會(huì)支持體積光官扣〕岬校基本上所有的光源類型都會(huì)支持ray march方法,通過(guò)調(diào)整參數(shù)可以很好的實(shí)現(xiàn)消耗與質(zhì)量之間的平衡惕蹄。
這個(gè)算法是按照類似于延遲光照的方式執(zhí)行的蚯涮,在屏幕空間完成某個(gè)光源的光照計(jì)算之后治专,使用ray marching shader在對(duì)這個(gè)光源的體積光shading進(jìn)行計(jì)算,將結(jié)果存儲(chǔ)到volumetric buffer中遭顶。
為了降低消耗张峰,體積光渲染是在半分辨率buffer中計(jì)算的,且劃定了marching范圍棒旗,并不會(huì)對(duì)ray上的所有點(diǎn)進(jìn)行采樣喘批。
這里有一個(gè)實(shí)現(xiàn)上的技巧,即ray marching的step尺寸是不固定的铣揉,而是按照一個(gè)隨機(jī)算法生成的饶深,這種做法有如下的好處:
- 感知上的質(zhì)量會(huì)更高
- 加上雙邊模糊之后可以移除dither pattern(抖動(dòng)紋樣)
這種做法有點(diǎn)類似于PCF中的隨機(jī)采樣點(diǎn),如上圖所示逛拱,同樣的采樣點(diǎn)數(shù)敌厘,將采樣點(diǎn)打散看起來(lái)有助于增加每條射線上的采樣點(diǎn)數(shù)目。
這里給出了不同處理方案的效果對(duì)比橘券,可以看到通過(guò)一系列的手段额湘,可以使用8步采樣達(dá)到近似128步采樣的效果。
單純的體積光效果會(huì)比較單調(diào)旁舰,《暗影》這邊決定通過(guò)粒子系統(tǒng)來(lái)為之進(jìn)行增色锋华。粒子系統(tǒng)完全由美術(shù)同學(xué)把控,且能夠跟物理箭窜,角色移動(dòng)以及風(fēng)力等產(chǎn)生交互毯焕。
其實(shí)現(xiàn)方式為,將粒子系統(tǒng)渲染到一個(gè)3D的Scattering Amount Buffer中磺樱,這個(gè)Buffer是在相機(jī)空間中定義的纳猫,平面分辨率為屏幕分辨率的1/8,深度采用16個(gè)切片來(lái)實(shí)現(xiàn)竹捉。這個(gè)Buffer中存儲(chǔ)的數(shù)據(jù)在raymarch的時(shí)候會(huì)對(duì)采樣點(diǎn)的volumetric強(qiáng)度進(jìn)行影響芜辕。
這里來(lái)看下這個(gè)buffer的直觀展示效果。
這里給出了添加了粒子系統(tǒng)(右邊)跟沒(méi)有添加粒子系統(tǒng)(左邊)的效果對(duì)比块差,影響還是很卓著的侵续。
不過(guò)將體積光跟其他的半透效果組合起來(lái)其實(shí)還挺艱難的,需要考慮到單獨(dú)的buffer(不知道說(shuō)的是不是前面的Scattering Amount Buffer還是其他的buffer)憨闰,且沒(méi)有可以比對(duì)的depth數(shù)據(jù)等(比如上圖就是depth問(wèn)題導(dǎo)致的效果異常)状蜗。
這里的效果問(wèn)題也是因?yàn)樯疃仍驅(qū)е隆?/p>
在實(shí)際開(kāi)發(fā)中發(fā)現(xiàn),使用2D的體積光強(qiáng)度buffer跟透明物件很難匹配起來(lái)鹉动,這也是前面放出的兩個(gè)效果異常的原因轧坎。因此這里的做法是仿照Scattering Amount Buffer,直接使用3D的體積光強(qiáng)度Buffer來(lái)進(jìn)行數(shù)據(jù)存儲(chǔ)泽示,不過(guò)這里的平面分辨率是屏幕分辨率的一半缸血,里面存儲(chǔ)的是raymarching的結(jié)果蜜氨,每次執(zhí)行一個(gè)step的raymarching,都會(huì)將結(jié)果存儲(chǔ)到這個(gè)buffer中對(duì)應(yīng)的depth切片上属百,到后面渲染透明物件(比如煙霧)的時(shí)候记劝,就可以通過(guò)查詢這個(gè)buffer獲取到從相機(jī)到這個(gè)透明物體上位置之間有多少可見(jiàn)的volumetrics,之后將這個(gè)結(jié)果添加到透明物體顏色上族扰,效果上看起來(lái)就像是透明物體實(shí)際上是位于體積效果之后一樣。
詳情參考GPU Pro5中的實(shí)現(xiàn)細(xì)節(jié)定欧。
當(dāng)前的渲染方法其實(shí)還是比較粗糙的渔呵,每幀需要花費(fèi)大量的時(shí)間來(lái)對(duì)反射、體積效果進(jìn)行繪制砍鸠,用完就扔了扩氢,等到下一幀又從頭開(kāi)始渲染。這里給出的一個(gè)新的想法是使用Reprojection來(lái)提升渲染速度或者渲染質(zhì)量爷辱。
Reprojection的基本思想是录豺,連續(xù)多幀渲染結(jié)果是非常相似的,因此可以考慮在當(dāng)前渲染幀對(duì)前面渲染幀的結(jié)果進(jìn)行重用饭弓。
《暗影》這邊對(duì)Reprojection的期望是用之來(lái)提升渲染質(zhì)量(就像是TAA一樣)双饥,從而在較少的采樣點(diǎn)的情況下得到較高的渲染質(zhì)量。
對(duì)上一幀數(shù)據(jù)重用需要進(jìn)行篩選弟断,避免Reprojection到錯(cuò)誤的數(shù)據(jù)上:
- 需要根據(jù)顏色與深度相似性來(lái)判定
- 并根據(jù)相似性來(lái)對(duì)兩幀的結(jié)果進(jìn)行混合
具體實(shí)現(xiàn)上還有一個(gè)小竅門(mén)咏花,那就是每一幀會(huì)來(lái)回切換一套step offset(一共兩套),這樣做的好處就是看起來(lái)像是增加了采樣點(diǎn)的數(shù)目阀趴。
這里給出的是使用4個(gè)采樣點(diǎn)來(lái)進(jìn)行raymarching的結(jié)果昏翰,通過(guò)Reprojection處理之后,噪聲得到了大大的降低刘急。
除了對(duì)體積光效果起到質(zhì)量?jī)?yōu)化之外棚菊,對(duì)于其他的后處理(這些后處理通常是在低分辨率下渲染的,如Bloom叔汁,SSAO统求,Godrays,Exposure measurement(這個(gè)是啥))的質(zhì)量也有一定程度的提升(移動(dòng)更為平滑)攻柠。
這里給出了Bloom跟AO的優(yōu)化結(jié)果對(duì)比球订。
灰塵跟雨效是通過(guò)粒子系統(tǒng)來(lái)實(shí)現(xiàn)的,在normal pass渲染完成后瑰钮,通過(guò)后處理的方式添加到G-buffer的冒滩。其實(shí)施效果能夠跟腳步或者槍擊產(chǎn)生交互。為了將雨點(diǎn)限制在戶外浪谴,會(huì)通過(guò)一張類似于shadow map的從上到下的貼圖來(lái)進(jìn)行判斷开睡,實(shí)現(xiàn)細(xì)節(jié)可以參考這篇文章因苹。
這里給出了灰塵交互的實(shí)施效果,在后處理渲染中篇恒,會(huì)使用user channel來(lái)對(duì)貼花decal周邊的灰塵進(jìn)行擦除扶檐。
雨效主要通過(guò)對(duì)specular進(jìn)行修改來(lái)實(shí)現(xiàn),注意查看albedo的亮度會(huì)被稍微減弱(PBR胁艰,能量守恒)
雨滴位置是通過(guò)一張3D texture來(lái)給出的款筑。這個(gè)貼圖中的每張depth切片表示的是不同階段的雨效——從清晰的強(qiáng)雨到表示逐漸淡出雨效的較為模糊的圓點(diǎn)。
下面來(lái)看一下《暗影》的反射效果實(shí)現(xiàn)方案腾么。
《暗影》反射系統(tǒng)由三個(gè)組件組成奈梳,按照下面順序逐次取用數(shù)據(jù),當(dāng)上一級(jí)獲取數(shù)據(jù)失敗時(shí)解虱,就會(huì)自動(dòng)fallback到下一級(jí):
- 實(shí)時(shí)Raytrace反射系統(tǒng)
- 用于表示位于不同距離的動(dòng)態(tài)物件的反射
- 局部靜態(tài)cubemap反射
- 用于表示局部反射
- 靜態(tài)背景cubemap反射
- 用于表現(xiàn)遠(yuǎn)景的反射
這里給出的是靜態(tài)局部cubemap的反射效果攘须。為了優(yōu)化性能,這里使用了tiled renderer殴泰,每個(gè)tile會(huì)提取出影響到這個(gè)tile的所有cubemap list于宙,之后在渲染的時(shí)候就可以忽略那些無(wú)干涉的cubemaps了。
每個(gè)局部cubemap對(duì)應(yīng)于一個(gè)zone悍汛,這個(gè)是由美術(shù)同學(xué)手動(dòng)擺放的捞魁。整個(gè)渲染流程包含兩個(gè)pass,每個(gè)section大概需要花費(fèi)一個(gè)小時(shí)(離線進(jìn)行):
- 關(guān)閉反射员凝,normal render pass(作為下一輪繪制的輸入貼圖)
- 開(kāi)啟反射署驻,進(jìn)行第二輪render
這里還會(huì)通過(guò)mipmap filtering來(lái)實(shí)現(xiàn)對(duì)BRDF specular cone的模擬,詳情參考Siggraph 2012年的 Local Image-based Lighting With Parallax-corrected Cubemap 文章健霹。
反射的光澤計(jì)算與兩個(gè)因素有關(guān):
- 表面粗糙度旺上,參考上圖中的左邊跟中間的小圖,可以看到糖埋,這個(gè)因素會(huì)影響到反射椎體的aperture(孔洞)
- 反射射線的長(zhǎng)度:長(zhǎng)度越長(zhǎng)宣吱,椎體最終的半徑越大。
最終輸出的光澤度會(huì)用于計(jì)算cubemap的mip層級(jí)瞳别。
實(shí)時(shí)反射渲染使用的是屏幕空間的算法(其實(shí)就是屏幕空間反射征候,SSR)∷盍玻總共可以分為三個(gè)階段:
- 對(duì)需要反射的像素進(jìn)行raytracing疤坝,在屏幕空間貼圖中找到對(duì)應(yīng)的反射color
- 對(duì)反射結(jié)果進(jìn)行filtering跟reprojection處理,用于計(jì)算光澤馆铁,并遮蓋錯(cuò)誤跟孔洞
- 將實(shí)時(shí)反射結(jié)果跟cubemap相結(jié)合跑揉,用于處理那些實(shí)時(shí)反射缺失的部分
實(shí)時(shí)反射輸出貼圖采用的是半分辨率,實(shí)施上有如下細(xì)節(jié)可供參考:
- 每個(gè)反射貼圖上的像素對(duì)應(yīng)于2x2個(gè)屏幕空間像素,每幀都會(huì)從這四個(gè)像素中取用不同的位置的像素
- 經(jīng)過(guò)4幀之后正好完全覆蓋全分辨率屏幕貼圖
這里給出最終的效果展示历谍,忽略由于水面動(dòng)畫(huà)導(dǎo)致的高光閃爍现拒。
這里給出Raytracing實(shí)現(xiàn)平面反射的細(xì)節(jié):
- 根據(jù)反射向量的方向在屏幕空間按照常量step(step尺寸受表面粗糙度以及反射方向影響)進(jìn)行raymarching
- 同時(shí),為了避免出現(xiàn)大面積區(qū)域獲取不到反射信息的情況望侈,還特意增加了一層處理印蔬,即允許射線從部分物件(比如武器)下方穿過(guò)
- 為了提升表現(xiàn)的穩(wěn)定性,這里會(huì)在raymarching的時(shí)候選取最近的兩個(gè)點(diǎn)脱衙,并在其中進(jìn)行插值
- 提升穩(wěn)定性的另一個(gè)策略侥猬,就是利用上一幀的數(shù)據(jù)來(lái)對(duì)本幀反射結(jié)果進(jìn)行補(bǔ)充
接下來(lái),從ray-trace的輸出結(jié)果中生成mipmap chain岂丘,生成的過(guò)程會(huì)采樣跟前面cubemap一樣的filtering策略以實(shí)現(xiàn)對(duì)BRDF的逼近與模擬陵究。為了提升準(zhǔn)確率,這里還會(huì)使用mask來(lái)對(duì)那些空缺的像素進(jìn)行屏蔽奥帘,避免mipmap輸出錯(cuò)誤結(jié)果。
之后構(gòu)建對(duì)應(yīng)的反射buffer仪召,在使用的時(shí)候寨蹋,會(huì)需要根據(jù)gloss來(lái)計(jì)算mipmap層級(jí)。
為了提升反射結(jié)果的穩(wěn)定性扔茅,前面說(shuō)到已旧,會(huì)使用上一幀的結(jié)果通過(guò)Reprojection來(lái)對(duì)本幀的反射結(jié)果進(jìn)行補(bǔ)充。其實(shí)現(xiàn)過(guò)程跟TAA類似:
- 選取的結(jié)果會(huì)根據(jù)顏色是否相近來(lái)進(jìn)行剔除
- 比對(duì)時(shí)會(huì)考慮本幀反射結(jié)果周邊像素的顏色范圍
- 詳情參考Siggraph上的文章:‘Real-Time Global Illumination and Reflections in Dust 514’ - Hugh Malan
ray-trace反射buffer生成之后召娜,可能還依然存在部分漏洞运褪,之后就是通過(guò)前面提到的cubemap來(lái)對(duì)這些漏洞進(jìn)行填充。
下面來(lái)介紹下《暗影》中的抗鋸齒技術(shù)方案玖瘸。
第一套方案框架是以MSAA為基礎(chǔ)秸讹,在上面添加了TAA Reprojection。
第二套方案則是TAA+FXAA雅倒,其穩(wěn)定性要優(yōu)于第一套方案璃诀。TAA會(huì)將多幀結(jié)果填充到history buffer中(大概16幀),填充的時(shí)候會(huì)根據(jù)顏色是否相近進(jìn)行剔除蔑匣。在開(kāi)發(fā)的時(shí)候還嘗試過(guò)使用subpixel抖動(dòng)來(lái)獲取更多的采樣點(diǎn)劣欢,不過(guò)后面發(fā)現(xiàn)結(jié)果不太穩(wěn)定就舍棄了。
這套方案存在的一個(gè)問(wèn)題是裁良,即隨著不斷的累加凿将,數(shù)值會(huì)發(fā)生空間上的傳播,從而導(dǎo)致最終的結(jié)果顯得有點(diǎn)模糊价脾,而這個(gè)現(xiàn)象是MSAA所看不到的牧抵。
這里給出的解決方案是通過(guò)反復(fù)的補(bǔ)償與修正方法來(lái)消除,基本思路如圖所示:
- 將history buffer Reprojection到本幀上
- 之后再將結(jié)果Reprojection回上一幀
- 最終history pixel reprojection的結(jié)果就等于二者的加權(quán)平均彼棍。
詳情參考:‘An Unconditionally Stable MacCormack Method’
效果對(duì)比灭忠。
下面來(lái)介紹下場(chǎng)景中多個(gè)角色的渲染方案膳算。
單個(gè)玩家,1080P弛作,目標(biāo)是30FPS涕蜂。多個(gè)玩家,1080P映琳,60FPS(因?yàn)閱瓮婕一叮恍枰@么快的響應(yīng),而多玩家如果響應(yīng)慢了萨西,可能會(huì)被玩家慢)有鹿。項(xiàng)目組不希望降低顯示質(zhì)量,怎么辦呢谎脯,又沒(méi)有時(shí)間對(duì)assets進(jìn)行優(yōu)化葱跋,只能通過(guò)一些技術(shù)手段來(lái)完成。
這里依然準(zhǔn)備借助reprojection來(lái)實(shí)現(xiàn):將縱向分辨率降低一半源梭,奇偶幀交替渲染一半像素娱俺,之后通過(guò)reprojection來(lái)模擬出全分辨率效果。從結(jié)果上來(lái)看废麻,很難分辨出來(lái)質(zhì)量有下降荠卷,但是性能上確有80%的提升。
為了保證質(zhì)量足夠高烛愧,這里一共緩存了兩幀數(shù)據(jù)油宜,reprojection依然需要驗(yàn)證顏色一致性。
在實(shí)際計(jì)算的時(shí)候有兩種情況怜姿,第一種情況當(dāng)前幀渲染結(jié)果可用慎冤,那么此時(shí)就直接使用這個(gè)結(jié)果;第二種情況是當(dāng)前幀渲染結(jié)果不可用社牲,那么就需要通過(guò)reprojection來(lái)計(jì)算得到粪薛。
這里reprojection是針對(duì)當(dāng)前第N幀跟N-2幀的,通過(guò)比對(duì)顏色相似性搏恤,決定結(jié)果是否可用违寿。而如果兩者結(jié)果很相似,那么N-1幀結(jié)果大概率是可用的(為什么這么復(fù)雜)
在使用的時(shí)候熟空,會(huì)在內(nèi)存中保存下全分辨率的history buffer以提升reprojection的穩(wěn)定性藤巢,reprojection需要保證結(jié)果的可靠性(即只有結(jié)果可靠才會(huì)采用,那么不可靠的時(shí)候怎么辦呢息罗,直接從相鄰像素插值得到掂咒?):
- 移動(dòng)是穩(wěn)定的可預(yù)測(cè)的
- 顏色相似度要夠高
SP-Single Player,MP - MultiPlayer。
下面介紹bounus slide上的一些技術(shù)绍刮。
力場(chǎng)的模擬采用的是美術(shù)同學(xué)驅(qū)動(dòng)的基本框架温圆,這樣在效果上的表現(xiàn)力會(huì)更強(qiáng)一點(diǎn)。
影響面片的因素包括如下幾個(gè)方面:
- 風(fēng)力
- 爆炸
- 渦流
這些因素的影響方式有如下幾種:
- 靜態(tài)放置在場(chǎng)景中
- 附加到角色或者其他道具上
力場(chǎng)影響的asset包括布料孩革,粒子系統(tǒng)以及shader實(shí)現(xiàn)岁歉。。
早期的力場(chǎng)系統(tǒng)是直接集成在植被上(采用的是Position Based Dynamics方法)膝蜈,這些效果包括植被搖動(dòng)以及掉落物體對(duì)粒子的推動(dòng)效果等锅移。
最終的力場(chǎng)方案實(shí)際上依賴的就是大量的計(jì)算:每幀大概需要對(duì)6萬(wàn)個(gè)采樣點(diǎn)進(jìn)行計(jì)算。
這里又兩種查詢(Query)饱搏,顯式(explicit)以及隱式(implicit)非剃。
顯式查詢用于返回給定點(diǎn)的力場(chǎng)結(jié)果,多用于布料或者粒子模擬推沸。
隱式查詢針對(duì)的則是緩存在角色周邊網(wǎng)格中的力場(chǎng)备绽。網(wǎng)格有多重規(guī)格,數(shù)據(jù)可以直接在shader中獲取鬓催,多用于樹(shù)葉水面等系統(tǒng)疯坤。
這里給出一個(gè)力場(chǎng)cascade的可視化展示。
這里還用力場(chǎng)來(lái)對(duì)背景人群進(jìn)行驅(qū)動(dòng)深浮,這些人群都是適用sprite制作的。
《killzone 3》使用的是根據(jù)boundingbox進(jìn)行的貼圖streaming眠冈,不過(guò)對(duì)于建筑內(nèi)部沒(méi)啥用飞苇。