[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:遊戲引擎 |