DOOM4圖形研究

    原文地址 http://www.adriancourreges.com/blog/2016/09/09/doom-2016-graphics-study/


     由於本人英語水平有限,對於圖形學技術領悟有限,錯誤之處在所難免,讀者體諒,也歡迎高手 翻譯此篇,

拋磚引玉 。   本文你可以隨意轉載,但請你最好註明出處,畢竟我翻譯也不容易。請尊重一下勞動成果!

                              DOOM4 圖形研究






    DOOM在1993年開創了遊戲設計和開發的根本變革,這是一個世界性的現象,

推動了像約翰·卡馬克(John Carmack)和約翰·羅梅洛(John Romero)這樣的
標誌性人物。
    23年後,id Software現在屬於Zenimax,所有的原創始人都已經走了,但
    並沒有什麼能阻擋該公司的所有人才來做出一個超級偉大的遊戲。


   新的DOOM(2016)是專利權的完美補充,使用新一代的ID Tech 6引擎。   前Crytek Tiago Sousa在約翰·卡馬克(John Carmack)離職後,現在擔任首

席渲染程序員的角色。

   在id公司的歷史上,引擎源碼開源廣爲人知,新一代遊戲引擎,通常幾年後會

開源引擎,這通常會導致很好的重製和改造。id Tech 6是否開源,但仍然有待觀

察,但我們並不一定需要源代碼來了解在引擎中實現的漂亮圖形技術。

How a Frame is Rendered(一幁是如何被渲染的)


   我們將在下面的場景中檢查玩家攻擊由一些擁有的敵人防守的gore nest(戈爾
巢,doom4遊戲的地圖之一)的場景,首先在遊戲開始之前先取得Praetor Suit(doom4的裝甲服裝)。

現在發佈的大多數Windows遊戲不同,DOOM並不使用Direct3D接口,但提供了一個OpenGL和Vulkan後端。

   Vulkan是新的熱點,Baldur Karlsson最近在RenderDoc(一個圖形調試器,支

持DX12.dx11,Opengl)中增加了支持,DOOM4是一個很困難的的選擇。使用Vulkan 

運行遊戲在NVIDIA  GTX 980上的設置爲最高級別(譯者注,這麼翻譯是根據我的

理解,Vulkan是一個支持低端機器運行Opengl的渲染接口,因此開到了最高模式),一些猜測來自於


Siggraph大會上Tiago Sousa(id首席程序員) 和Jean Geffroy.的展示。


Megetexture Update (巨型紋理更新)


   首先第一步是Mega-Texture更新,這是一種已經存在於RAGE中使用的ID Tech 

5中的技術,現在也在DOOM中使用。 如果要闡述這個算法的基本原理的話,這個

算法是在GPU內存上分配了幾個巨大的紋理(16K x 8k的DOOM),每個紋理都是

128 x 128個 Tile(瓷磚拼圖)拼貼的集合。


16k x 8k storage with 128 x 128 pages


    所有這些Tile(瓷磚)都應該在好的mipmap級別代表理想的實際紋理集合,像

素着色器稍後將會渲染你現在正在看的遊戲畫面。


     當Pixel Shader(像素着色器)從“虛擬紋理”讀取數據時,它只能從這些

128x128的某些物理Tile(瓷磚)中讀取。

   當然這取決於玩家看的地方,玩家移動位置的時候,這個畫面將會改變:新的

模型會出現在屏幕上,然後引用它所關聯的虛擬紋理,新的Tile圖塊將會被

stream in(流式傳入),舊的Tile流將被導出...
 
      所以在一幀的開始, DOOM4引擎使用vkCmdCopyBufferToImage命令來更新

了一些Tile瓷磚,將一些實際的紋理數據帶入GPU內存。

對於idtech5 megetexture 技術的更詳細的一個介紹,乃是出自,2012年的Siggraph,id程序員所寫的論文

如果感興趣, 05_ip_id_tech5_challenges.pdf 請去此處下載 
  
https://page35.ctfile.com/fs/14244535-201397199


H3D姚勇寫的  RAGE來了-Megatexture信息更新.pdf 論文對於megetexture的一個敘述

下載地址 


對於Megetexture描述更加清晰的論文,由id程序員寫的 Software-Virtual-Textures.pdf

如果感興趣的話,請到此處下載 


shadow Map atlas (陰影貼圖圖集)


  對於每個燈投射一個陰影,生成一個獨特的深度圖,並將其保存到巨大的8k x   8k texture atlas (紋理圖集)的一個Tile(瓷磚)中。然而,並不是每個幀都需要

計算出每一個深度圖:DOOM4大量地重新使用前一幀的結果,並只重新生成需要更新的深度圖。



燈是靜態的,並且僅在靜態對象上投射陰影時,只需簡單地將其深度圖保

8k * 8k的深度緩存器前一幁








8k*8k的深度緩衝器當前一幁


原樣,而不是進行不必要的重新計算是有意義的。但是如果一些敵人在光線下移

動,則深度圖必須再次生成。

  深度圖尺寸可以根據與相機的光距離來變化,重新生成的深度圖也不一定保持

在圖集內的同一Tile內。

    DOOM4具有某些特定的優化,例如緩存深度圖的靜態部分,僅計算動態網格投
影併合成結果。

Depth Pr-Pass(深度預處理)

  現在渲染所有不透明的網格,僅將其深度信息輸出到深度圖中。首先是玩家的

武器,然後是靜態幾何數據,最後是動態幾何數據。





速度圖

但實際上深度並不是在深度預處理期間輸出的唯一信息。
雖然動態對象(殭屍,電纜,玩家的武器)被渲染到深度圖,但是它們每像素的

速度也被計算並寫入另一個緩衝區以創建velocity map速度圖。這通過在頂點着
色器中計算前一幀和當前幀之間的每個頂點的位置差來完成。


Velocity 我們只需要2個channel(通道)來存儲速度:紅色是沿着水平軸的速度,沿着垂直軸是綠色的。

這個怪物迅速向玩家(綠色)移動,但是玩家手中的武器幾乎沒有移動(黑色)

黃色區域(紅色和綠色等於1)?它實際上是緩衝區的原始默認顏色,沒有動態網


格沒有觸及過:它是所有的“靜態網格區域”。
  爲什麼DOOM跳過靜態網格的速度計算?因爲靜態像素速度可以從其深度簡單地

推斷出來,而相機的狀態自上一幀起就是新的state(狀態),所以不需要在每個網

格的基礎上進行計算。
the velocity速度圖在稍後應用一些運動模糊將是有用的。

 occlusion Quieries( 遮擋查詢)                                                                                                                     
   
我們想發送儘可能少的幾何渲染到GPU,所以實現這一點的最好方法是剔除玩家視 

野裏面不能直接看到的所有網格。DOOM4中的大部分遮擋查詢都是通過Umbra中間


件()完成的, 但引擎仍然會執行一些GPU遮擋查詢來進一步削減視野外的數據


那麼GPU遮擋查詢背後是怎麼實現的呢?
  首先是將遊戲場景的幾個網格組合成一個包含它們的虛擬框,然後請求GPU根據

當前的深度緩衝區渲染此框。如果沒有一個光柵化像素通過深度測試,這意味着


盒子被完全遮擋,並且渲染時可以安全地省略該盒子中的所有世界對象。
那麼事情是這些遮擋查詢結果是不可用的,你不想阻止GPU管道阻擋一個查詢。通


常,讀取結果被推遲到以下幀,因此有必要使算法有點保守,以避免對象彈出。




Clustered-Forward-Rendering of Opeque Objects
(不透明對象的前向渲染)


  渲染所有不透明的幾何和貼花。照明信息存儲在HDR緩衝區中:

   深度測試函數被設置爲EQUAL避免任何無用的overdraw(過繪製)計算,由於


之前的深度預處理(pre-pass),我們知道每個像素應具有哪個深度值。
當渲染網格時,貼圖也直接應用,它們存儲在紋理圖集中。


  它已經看起來很好,但我們仍然缺少一些透明的材料,如玻璃,或顆粒,還沒
有環境反射。

關於這個遊戲的一趟渲染(pass):它使用一個聚集的前向渲染器,它受到Emil 

Person和Ola Olsson的作品的啓發。

  歷史上,前向渲染的一個缺點是它無法處理大量的燈光,在延遲渲染中更容易

處理。
 (譯者注:前向渲染在單機fps中光源數量可以設定,同時一幁內的怪物數量已


知不是mmoprg玩家人數增多,像中國玩家的羣戰,幾何數據未知。)

那麼cluster(集羣)渲染器是如何運行的呢?

 首先,您將您的視口劃分成Tile(圖塊):DOOM創建一個16 x 8細分。一些渲染器

會停在這裏,並計算每個Tile(圖塊)的燈光列表,這有助於減少照明計算量,但

仍然受到一些邊緣情況的影響。



cluster Rendering(集羣渲染)將從2D到3D進一步擴展,而不是停止在2D視口     
 

細分,它實際上通過沿Z軸創建切片來執行整個相機平截頭體的3D細分。


每個“塊”被稱爲“羣集”,您也可以將其稱爲“平截頭體” 體素或“froxels
”。
右側是一個簡單的4 x 2視口細分的可視化,5個深度切片將平截頭體分爲40個羣集。


在DOOM中,相機平截頭體被分爲3072個羣集(16×8×24個細分),深度片沿着Z軸以對數方式定位。



使用集羣渲染器,一個典型的渲染流程是:


首先,CPU計算影響每個集羣內的照明的項目列表:燈,貼花和立方體... 
爲此,所有這些項目都“體素化”,因此可以測試其影響區域與集羣的交集。數


據作爲索引列表存儲在GPU緩衝區中,以便着色器可以訪問它。每個羣集最多可以

容納256個燈,256個貼花和256個立方米。
然後當GPU呈現像素時:
從像素座標和深度,確定其屬於的集羣
檢索該特定集羣的貼花/燈的列表。它涉及偏移間接和索引計算,如下所示。
代碼循環遍歷集羣的所有貼花/燈光,計算並添加其貢獻。
實際上,像素着色器可以在此通過期間檢索燈光和貼花的列表:

還有探針列表(上圖中未顯示,),可以以完全相同的方式訪問,但在此通行證中
未使用,所以我們稍後再回來。
  在CPU上預先生成每個簇的項目列表的開銷是非常值得考慮的,它可以顯着降低

GPU上的渲染計算複雜度。

 集羣向前渲染最近越來越受到關注:它具有處理比基本轉發更多的亮度的好處,

而比延遲更快,必須從多個G-Buffers寫入/讀取。

但有一些我還沒有提到的:我們剛剛檢查的這個pass(通道)不僅僅是一個寫給
照明緩衝區的前進的一個; 而執行2次也使用MRT產生了2個G-Buffers 


   Normal Map  
                                                                                                                           























Specular Map























法線貼圖以R16G16浮點格式存儲。鏡面圖在R8G8B8A8中,Alpha通道包含平滑因子



所以DOOM實際上巧妙地混合了前進和推遲與混合方法。當執行附加效果(如反射

)時,這些額外的G-Buffers將派上用場。
  最後一件事我省略了:同時也產生了一個160 x 120的反饋緩衝區,用於大型紋
理系統。它包含告訴流式傳輸系統哪些紋理應該流式傳輸mipmap級別的信息。
大型紋理引擎以反應的方式工作:在渲染傳遞報告後,某些紋理缺少引擎加載它們。


GPU Particles(GPU 粒子)

compute shader (計算着色器)被分配到更新粒子仿真:位置,速度和壽命。
它讀取粒子當前狀態以及正常和深度緩衝區(用於碰撞檢測),起到模擬步驟的
作用,並將新狀態存儲到緩衝區中。

     Screen Space Ambient Occlusion(屏幕空間環境遮擋)

SSAO Map          


            

        在此步驟中,現在生成SSAO地圖。


       其目的是使狹窄的接縫,褶皺變暗。
            它也用於應用specular occlusion鏡面遮擋 以避免出現在被遮擋的網格上的明亮


照明上出現僞影。


  在從深度緩衝區,正常和鏡面地圖讀取的像素着色器中,以原始分辨率的一半


計算。
獲得的第一個結果是noise(嘈雜的)。
圖像(左邊)




Screen Space Reflections(屏幕空間反射)
一個像素着色器現在用於生成SSR映射。它僅使用存在於屏幕上的信息的光線追蹤

反射,使得光線在視口的每個像素上反彈,讀取由它們擊中的像素的顏色。


着色器的輸入是深度圖(用於計算像素世界空間位置),法線貼圖(知道如何使
光線反彈),specular鏡面圖(知道反射量)和前一幀渲染(在pre-tonemapping

階段,但後透明度,有一些顏色信息)。先前的幀攝像機配置也提供給像素着色

器,因此可以跟蹤片段位置的變化。

 SSR是一個不錯的,不太貴的技術,可以在現場進行實時動態反射,以保持不變

的成本,真正有助於沉浸和現實主義的感覺。
  但由於它純粹在屏幕空間中工作,缺少“全局”信息,因此它自帶的工件。所

以你可能會在一個場景中看到很好的反射,但是當你開始向下看時,反射的程度

會減少,直到看到你的腳就完全沒有反思。我發現DOOM中的SSR很好地整合在一起

,它們提高了視覺質量,但是除非你真的專注於這些,否則你不會注意到它們消失。

Static Cubemap Reflections(靜態立體圖反射)

之前所有的動態反射趟數目(及其限制)現在都來自使用IBL的靜態反射。
該技術基於預先生成的128 x 128立方米表示地圖不同位置處的環境照明信息,也


稱爲“環境探測”。正如我們以前在截錐體聚類中所看到的光和貼花一樣,探針


也按照與每個聚類相同的方式進行索引。
級別的所有立方體都存儲在一個數組中,其中有幾十個,但這裏是這個場景的5個


主要貢獻者(這個房間內的立方體):


/**************/




一個像素着色器從深度,正常的鏡面緩衝區中讀取立方體影響像素的羣集結構(


立方圖越靠近其影響越強)並生成靜態反射圖:




Blending Maps Together(地圖所有映射混合)


在這個步驟中,計算着色器組合了之前生成的所有映射。
它讀取深度和鏡面地圖,並將前進的照明與:


SSAO信息
當SSR可用於有問題的像素時
當SSR信息丟失時,靜態反射映射數據被用作Fallback(回退)
還計算了一些霧效應







Particle lighting(粒子照明)


我們在這個場景中有一些煙霧粒子,照明實際上是根據精靈計算的。
每個精靈的渲染就像是在世界空間中:從它的位置,一些光列表和它們各自的陰


影貼圖被檢索,並且quad(四邊形)上的照明被計算出來。然後將結果存儲到4k


地圖集的瓦片中,基於距離相機的粒子距離,瓦片可以具有不同的分辨率,質量


設置...圖集具有相同分辨率的精靈的專用區域,這裏是64 x64個精靈:






而這只是以這種低分辨率存儲的照明信息。之後,當實際繪製一個粒子時,使用

全分辨率紋理,並將照明四面體放大並與之混合。
這是DOOM將粒子照明計算與遊戲的實際主渲染分離的位置:無論您在播放的分辨

率(720p,1080p,4k ...),粒子照明總是計算並存儲在這些微小的固定大小的
圖塊中。


Downscale and blur(低檔和模糊,downscale我不知道該怎麼翻譯)

 場景被縮放了幾次,下降到40像素。使用分離的垂直和水平通過,最小的縮小水平模糊。



爲什麼這個模糊如此早?這樣的過程通常在後期處理過程中完成,以從明亮的地方產生綻放效應。

但是,在渲染玻璃折射時,所有這些不同的模糊級別將在下一趟中派上用場。
透明對象
所有透明物體(glass(我翻譯成眼睛,因爲doom4有頭盔嘛),顆粒)都呈現在場景的頂部:




glass(此處翻譯爲玻璃)在DOOM中呈現非常好的特別是磨砂或骯髒的玻璃:貼花僅
用於影響玻璃的某些部分,使其折射或多或少模糊。

  像素着色器計算折射“模糊度”因子,並從模糊鏈中選擇最接近該模糊因子的2
個圖。它從這兩個地圖中讀取,然後在2個值之間線性插值,以逼近折射應具有的
最終模糊顏色。這是由於這個過程,眼鏡可以在基於像素的基礎上以不同的模糊

水平產生良好的折射。

Distortion Map 失真地圖                                                                                                    
  
非常熱的地方可以在圖像中產生熱變形。在這裏,戈爾巢地圖稍微扭曲了形象。


對深度緩衝區進行失真,以創建低分辨率的失真圖。
紅色和綠色通道表示水平和垂直軸的失真量。藍色通道包含要應用的模糊量。


實際效果稍後應用於使用失真圖的後期處理來知道應該移動哪些像素。
雖然在這個場景中,特別是只有一個微妙的失真並不明顯。








                                                                    用戶界面

                                                         UI
 
                                                   UI被渲染到以LDR格式存儲的預乘法alpha模式中的不同渲染目標。
 將所有UI都放入單獨的緩衝區,而不是直接繪製在最終的框架之上,這樣的優點 是遊戲可以一次性在所有UI小部件上應用一些過濾器/後處理,如色差或視覺失真。

在單程中。

渲染不會特別使用任何批處理技術,它會逐個繪製UI項目,大約有120個繪圖調用。
在後面的過程中,UI緩衝區被混合在遊戲圖像之上,以產生最終結果。

Temporal Anti-Aliasing and Motion-Blur

(時間抗鋸齒和運動模糊)

使用速度圖和先前幀的渲染結果應用TAA和運動模糊。
片段可以被重新投影,因此像素着色器知道當前正在處理的像素位於前一幀中。渲染實際上每隔一幀將網格投影稍微移動一半像素:這有助於刪除子像素的別名
僞像。






結果是非常好的:不僅網格邊緣變得光滑,而且鏡像混疊(其中一個亮像素將單
獨彈出一幀)也被照顧。通過像FXAA這樣的後期處理方法,質量遠遠好於可以實
現的質量。

Scene Luminance(場景亮度)

該步驟計算場景的平均luminace(亮度),這是晚些時候提供給tonemapper的參

數之一。


  HDR照明緩衝區在一個循環中被縮減到其分辨率的一半,直到它變爲2×2紋理,

每次迭代計算像素顏色值作爲其較高分辨率圖中其4個父像素的亮度的平均值。
應用亮通濾鏡來調暗場景最黑暗的區域。


  然後,亮通濾波器的結果在一個循環中被縮小,並且在我們之前看到的類似過程
   中模糊。
         層被模糊,高斯模糊分爲垂直和水平遍歷,其中像素着色器計算沿着一個方向的



  加權平均值。    然後將模糊的層組合起來,以創建在原始分辨率的1/4的HDR紋理的綻放。

Final Post-Processing(最終後期處理)

所有這一步都在一個像素着色器中執行:

讀取失真圖數據應用熱失真
在HDR照明緩衝區的頂部添加了綻放紋理
執行如漸暈,污垢/鏡片閃光的效果
通過對2×2亮度圖的中心進行採樣並使用附加的曝光參數來獲取平均亮度,應用


調色板和顏色分級。
Tonemapping:之前
之後
以前下一個1
2
/******************/
tonemapping採用HDR照明緩衝器,其顏色在廣泛的亮度範圍內變化,並將其轉換
爲每個組件(LDR)的8位,因此可以將框架顯示在顯示器上。
  使用基於方程式的A filmic tonemapping operator(電影節拍操作員)
 (x(Ax+BC)+DE) / (x(Ax+B)+DF) - (E/F),它是“ 神祕海域2”色譜圖,也出現
在GTA 5(俠盜獵車手5)中。
請注意,場景的所有普通紅色都來自於顏色校正。


UI and Film Grain (界面和膠片顆粒)
最後,UI被混合在遊戲框架的頂部,同時film-grain(膠片顆粒)被應用。




唷!我們完成了一幁的流程,現在可以將其發送到屏幕的監視器進行顯示,這是
相當多的計算,但所有這些都發生在不到16ms。
 
 DOOM通過巧妙地重新使用以前的幀中計算出的舊數據,從而高性能地產生高質量
的視覺效果。總共有1331個draw call(繪製批次),132個紋理和50個渲染目標被使用。

Bonus Notes (額外備註)
Close-Up on Glass(玻璃上的特寫鏡頭)
玻璃渲染是非常好的,它是通過我們以前看到的相對簡單的步驟實現的:

準備幾層不透明網格渲染的模糊
在Foward(前向模式)下使用貼花/照明/probe(探針)反射,在前面的方向繪製半透
明物品,使用前面處理過各種玻璃折射的模糊值,因此每個像素可以具有自身的
折射值。




景深
在在幁數的分析中沒有真正顯示任何景深,所以讓我們考慮在應用DoF之前和之後
的以下場景:




  並不是所有的遊戲都能正確執行DoF:傳統的方法通常是使用高斯模糊,並根據

像素的深度在一次通過中進行所有的模糊。這種方法簡單而廉價,但是有幾個問題:

而高斯模糊對於boken(綻放)來說是不錯的,創造a bright pixel spread(散景)
是不正確的:你真的需要一個平坦的內核,使一個明亮的像素的光散開在一個圓

盤或六邊形的形狀...高斯不能創造漂亮的散景形狀。
在單次像素着色器中執行DoF可能會導致出血僞像。

DOOM能正確地執行DoF,在我的經驗之中doom4使用的方法能夠產生最好的結果:

創建Far_field 遠場和near-field (近場)圖像:根據其深度和DoF參數完成像素



選擇。


near-fiedl (近處視野)可以產生增強的模糊效果,它會越多流入像素後面越好。
遠場也模糊,但沒有從對焦/近場區域讀取任何像素,因此避免了前景對象錯誤地
滲透到背景中的任何問題。

爲了創建boken blur(散景模糊),DOOM以半分辨率工作,並使用64個紋理抽頭執

行disk -blur(磁盤模糊),
每個樣本都擁有相同的權重,因此亮度真正與高斯模糊不同。
磁盤直徑可以根據像素的CoC值在每像素的基礎上變化。


然後,它進一步擴展了16分針模糊的模糊,但這次它不計算加權平均值,它只是

累積樣本值並保持鄰居抽頭的最高值,因此不僅會擴大第一個模糊它也修復了第
一次通過的小物體(採樣間隙)。最後一部分是McIntosh的工作靈感。

  考慮到獲得的最終磁盤模糊的寬半徑,這種在多次通過中的迭代技術可以產生


非常好的大模糊,同時仍然保持很好的性能,每像素執行的實際紋理抽頭的數量
仍然相當低。

  遠處的圖像和近處的圖像最終通過Alpha(蒙道)混合在原始場景的頂部合成,
以創建最終的景深效果。這個通過在應用運動模糊之前執行。


更多閱讀

如果您想更深入地瞭解idTech 6技術,幸運的是有很多演講和公共材料可供選擇

The devil is in the details: idTech 666: Tiago Sousa和Jean Geffroy的,對於id tech6遊戲引擎的一個更加詳細的描述,有很多的相關技術。
(Siggraph 2016)  如果感興趣的話,請到此處下載  idTech 666             
(魔鬼隱藏在細節之中)

olick的論文,olick-current-and-next-generation-parallelism-in-games.pdf
敘述了體渲染再加上光線投射即使乃是下一代的趨勢,如果你對這篇論文感興趣的話

請到下面地址
下載地址


技術採訪:數字鑄造企業Doom
id軟件技術採訪 DSOGaming

QuakeCon 2016:Doom Uncapped - Part1和Part 2

Doom:VentureBeat的最終面試

圖形學寶典CryEngine 3  Sousa_Graphics_Gems_CryENGINE3.pptx(Siggraph 2013),
許多後處理技術都用於idTech 6。下載地址

寫在後面的話
(譯者注:我並不完全的贊同作者的全部觀點,id tech6畫面的強大,乃是在場景管理,多核心的系統優化,在加上引擎各個部分的優化,id tech6繼承了id tech5的megetexture,渲染乃是幾何,光照,紋理,最強,其他的shader效應,未必就是全部,我相信隨着玩家的硬件的發展,id tech6 體素渲染,支持的幾何,紋理數據增多,畫面絕對越來越強悍,畫面極致乃是在未來的,我拭目以待)






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章