標籤:

[Siggraph16] The devil is in the details: idTech 666

SIGGRAPH 2016 idTech

每步驟大概的時間

Frustum rasterize 每個job處理1個depth slice,一共64個job

對於每個物體都是OBB或者frustum,對於每個depth所有的voxel光柵化

在clip space做(projection之後統除以w),這樣每個cell都是AABB,演算法就是N個plane與AABB相交,代碼使用SIMD

數據結構:

-offset list:8B*xyz

-item list: 4B*256*xyz

(最壞的情況是每個cell都有item)

~300光源 ~1200 decals

紅色代表有10個以上的overdraw

cell,綠色大概5個左右,藍色很好

Albedo/Specular/Smoothness/Normal/Lightmap進行VT,smoothness里bake了Toksvig。BC3/5的壓縮使用async compute,確實會有poping現象

Decal類似光源一樣在geometry光柵化的時候計算,是用來替代「貼」在Mega-Texture上的一種實時的方法,它有更快的美術workflow(不需要貼完之後在bake),更少的磁碟存儲(decal和原貼圖都可以復用),使用BC7的8k*8k atlas

Decal的模型是個OBB,lighting時需要計算出位置朝向,從world space反投到decal space計算uv,利用scale

bias參數來索引在atlas中實際的uv。

由美術來手動擺放,並且指定blend方式,美術設置和視頻選項來控制Decal的LOD。對於動態物體的Decal,可以設置一個物體的相對矩陣給decal

統一的光照代碼,不再組合shader:現代的branch效率已經很高了,對於靜態模型用同一套shader(是ps吧,否則inputLayout不一樣怎麼搞),更少的context switch(不用再setPS)。

-Diffuse GI:靜態模型Lightmap、動態模型irradiance volume

-Specular GI:environment

probe、SSR、Specular Occlusion

-Dynamic:Lights & Shadows

Self-explained

對於所有的光源都用相同的PCF代碼,更少的register pressure流水效率更高,包含了cascaded shadow,會在每層之間做dither,1tap sample。嘗試過使用vsm預濾波,但是會有點瑕疵比如漏光,對於forward的好處顯而易見,不需要再lighting時費時費力的PCF filter。

Register pressure在console上看來還挺吃緊的,連長生命周期的float都建議壓縮成uint

Glass的表面屬性通過decal來獲取的

粒子的光照如果per vs,會缺失高頻信息(陰影),如果加上tessellation又太費;如果per ps,粒子所佔的pixel又太多

解耦粒子光照的好處

Console specific的AMD架構,一般對於有分歧的MIMD指令用vector unit(VGPR),對於沒有分歧的指令用scalar unit,能減少register pressure、具有一致性的branch、更少的指令(為什麼),對於cluster shading做個分析:

圖示是什麼意思沒解釋,大概是wavefront id,fetch data id等

大部分wavefront都只會access一個cell,臨近的cell公用大部分內容,一個wavefront中的threads大部分會fetch相同的數據,每個thread去獨自fetch數據會造成指令divergence,最好對於獲取數據的步驟進行指令convergence,也就是scalar iteration去sample data

如圖所示,事先算好一個wavefront需要共同fetch的數據index,因為sample

index相同,所以是scalar instruction

對於只處理一個cell的wavefront使用另一段fastpath code,因為有空間連續性所以大部分時候這樣做更快,但是如果處理的cell太多會很慢,而且在particle lighting步驟不適用,benchmark挺好,console的register pressure差不多讓1/4的threads飢餓。。。

根據GPU的負載動態改變解析度,只改變viewport

Async compute去做PP,因為Shadow和Depth基本不用compute

unit,Opaque Pass也不會100%負載GPU,那麼可以把上一幀的PP跟他們重疊計算。

-要分離出UI

-PP等CPU都放到compute queue中

-等待下一幀Geometry render一起執行

-全計算好了present

*PC上可能有問題,這樣大規模的initiate command queue會造成runtime和driver的CPU負載特別不均,GPU也有可能因此受到影響,可能console上自己管理不會考慮這一個中間層吧,DX12這麼做應該沒問題。

Console specific的,不懂略過

VS/PS/CS是公用register的,所以可以用各種tweak讓concurrent的shader加起來大約256個VGPR

光源類型,支持面光源…錐光的參數保存在BC4的texture里,有時會用於假的陰影(Light Profile?),Environment Probes使用BC6H的cubemap array,128*128

DOOM3整體架構感覺非常簡明,設計的思路支持的特性非常明確,不愧是Carmack大神的公司

推薦閱讀:

從零開始手敲次世代遊戲引擎(四十二)
[GDC16] Optimizing the Graphics Pipeline with Compute
Dirty Game Engine
[CppCon14] How Ubisoft Montreal develops games formulticore – before and after C++11
[翻譯]DOOM(2016) - Graphic Study

TAG:遊戲引擎 |