《GPU Pro 1》:全書內容提煉總結
本文是【GPU精粹與Shader程式設計】系列的第八篇文章。文章全文共兩萬餘字,盤點、提煉和總結了《GPU Pro 1》全書總計22章的核心內容。
題圖來自《荒野大鏢客:救贖2》。
全文內容目錄
如上所示,本文將對《GPU Pro 1》全書中游戲開發與渲染相關,相對更具含金量的5個部分,共22章的內容進行提煉與總結,詳細列舉如下:
- Part I. 遊戲渲染技術剖析 Game Postmortems
- 一、《孢子(Spore)》中的風格化渲染 | Stylized Rendering in Spore
- 二、《狂野西部:生死同盟》中的渲染技術 | Rendering Techniques in Call of Juarez: Bound in Blood
- 三、《正當防衛2》中的大世界製作經驗與教訓 | Making it Large, Beautiful, Fast, and Consistent: Lessons Learned
- 四、《礦工戰爭》中的可破壞體積地形 | Destructible Volumetric Terrain
- Part II. 渲染技術 Rendering Techniques
- 五、基於高度混合的四叉樹位移貼圖 | Quadtree Displacement Mapping with Height Blending
- 六、使用幾何著色器的NPR效果 | NPR Effects Using the Geometry Shader
- 七、後處理Alpha混合 | Alpha Blending as a Post-Process
- 八、虛擬紋理對映簡介 | Virtual Texture Mapping 101
- Part III. 全域性光照 Global Illumination
- 九、基於間接光照快速,基於模板的多解析度潑濺 Fast, Stencil-Based Multiresolution Splatting for Indirect Illumination
- 十、螢幕空間定向環境光遮蔽 Screen-Space Directional Occlusion (SSDO)
- 十一、基於幾何替代物技術的實時多級光線追蹤 | Real-Time Multi-Bounce Ray-Tracing with Geometry Impostors
- Part IV. 影象空間 Image Space
- 十二、GPU上各項異性的Kuwahara濾波 | Anisotropic Kuwahara Filtering on the GPU
- 十三、基於後處理的邊緣抗鋸齒 | Edge Anti-aliasing by Post-Processing
- 十四、基於Floyd-Steinberg 半色調的環境對映 | Environment Mapping with Floyd-Steinberg Halftoning
- 十五、用於粒狀遮擋剔除的分層項緩衝 | Hierarchical Item Buffers for Granular Occlusion Culling
- 十六、後期製作中的真實景深 | Realistic Depth of Field in Postproduction
- 十七、實時螢幕空間的雲層光照 | Real-Time Screen Space Cloud Lighting
- 十八、螢幕空間次表面散射 | Screen-Space Subsurface Scattering
- Part V. 陰影 Shadows
- 十九、快速傳統陰影濾波 | Fast Conventional Shadow Filtering
- 二十、混合最小/最大基於平面的陰影貼圖 | Hybrid Min/Max Plane-Based Shadow Maps
- 二十一、基於四面體對映實現全向光陰影對映 | Shadow Mapping for Omnidirectional Light Using Tetrahedron Mapping
- 二十二、螢幕空間軟陰影 | Screen Space Soft Shadows
《GPU Pro 1》其書
《GPU Pro 1》全稱為《GPU Pro : Advanced Rendering Techniques》,其作為GPU Pro系列的開山之作,出版於2010年,匯聚了當代業界前沿的圖形學技術。全書共10個部分,41章。
一個有趣的細節是,《GPU Pro 1》是GPU Pro系列7本書中,頁數最多的一本,共712頁。

圖 《GPU Pro 1》封面
《GPU Pro 1》書本配套原始碼
類似之前的GPU Gems系列的原始碼收藏GitHub Repo( ofollow,noindex"> https:// github.com/QianMo/GPU-G ems-Book-Source-Code ),我也維護了的一個名為“GPU-Pro-Books-Source-Code”的GitHub倉庫,以備份GPU Pro系列珍貴的資源,也方便直接在GitHub Web端檢視業界大牛們寫的程式碼,連結如下:
QianMo/GPU-Pro-Books-Source-Code說明 : 本文中的Shader程式碼和部分章節因字數限制被省略
本文完整全文為2萬餘字,包含大量核心演算法的Shader原始碼。因為知乎專欄字數限制的緣故,全部的實現程式碼和部分章節,在本文需要省略,不然文章編輯時就會有紅字提示超出多少字,且無法點發布。PS.一開始本文匯入時候,居然提示超出3萬字......
如果對這部分內容感興趣,請移步至 QianMo/Game-Programmer-Study-Notes 閱讀無刪減的GitHub版,不便之處,敬請諒解。
Part I. 遊戲渲染技術剖析 Game Postmortems
一、《孢子(Spore)》中的風格化渲染 | Stylized Rendering in Spore
《孢子(Spore)》是一款非常有創意的遊戲。在遊戲《孢子(Spore)》中,使用了可程式設計過濾鏈系統(scriptable filter chain system)在執行時對幀進行處理,以實現遊戲整體獨特的風格化渲染。(注,在本文中,filter按語境,譯為濾波或者過濾)。

圖 《孢子》封面圖

圖 《孢子》中的風格化渲染
過濾器鏈(filter chain)可以看作一系列按順序應用的引數化的影象處理(image processing)著色器,即後處理鏈。《孢子》中的每一幀都使用此係統進行處理和合成。 除了《孢子》標準的藝術導向的視覺風格外,開發人員還建立了一組特有的濾波器,為遊戲產生截然不同的視覺風格。而在這章中,作者講到了一些在開發《孢子》時生成的視覺樣式,並分享了關於《孢子》過濾器鏈系統的設計和實現的細節。
諸如模糊(blur),邊緣檢測(edge detection)等影象處理技術的GPU實現在影象處理領域較為常見。《孢子》的開發目標是構建一個具有此類過濾器的調色系統,美術師可以利用這些過濾器來創作不同的視覺樣式。 下圖顯示了該系統在渲染管線中如何進行放置。

圖 過濾器鏈系統總覽

圖 《孢子》中以油畫方式進行渲染的飛機
下圖顯示了《孢子》中細胞階段的過濾器鏈如何使用由渲染管線的其他階段生成的多個輸入紋理,並形成最終的合成幀。

圖 《孢子》中細胞階段遊戲流體環境的複雜過濾器鏈
1.1 後處理過濾鏈系統的實現要點
過濾鏈系統實現的方面,分為兩個要點:
- 動態引數(Dynamic parameters)
- 自定義過濾器(Custom filters)
1.1.1 動態引數(Dynamic parameters)
《孢子》中的動態環境需要呼叫按幀變化引數。所以,遊戲中添加了可以通過任何過濾器訪問的每幀更新的全域性引數。例如,使用相機高度和當日時間作為行星大氣過濾器的變化引數,如下圖。
而在其他情況下,遊戲需要在給定過濾器的兩組不同引數值之間平滑插值。例如,每當天氣系統開始下雨時,全域性著色過濾器的顏色就會轉換為陰天的灰色。在系統中也添加了支援遊戲控制插值的引數,也添加了可以平滑改變濾波器強度的衰減器(fader)。

圖 按當日時間驅動的顏色過濾器。這種經過彩色壓縮的輸出會進行模糊並以bloom的方式新增到場景中
1.1.2 自定義過濾器(Custom filters)
過濾鏈系統的一個重要補充是自定義過濾器,可以將其著色器指定為引數。這意味著程式員可以通過向現有構建新增新著色器來輕鬆新增新的影象技術。此外,程式設計師可以通過將多個過濾器摺疊到一個實現相同視覺效果的自定義過濾器中來優化藝術家生成的過濾器鏈。
1.2 五種屏幕後處理Shader的實現思路
接著,介紹五種《孢子》中比較有意思的後處理效果。PS. 這五種效果都可以在本文的GitHub版上找到實現原始碼: QianMo/Game-Programmer-Study-Notes
1.2.1 油畫後處理效果 Oil Paint Filter
對於油畫過濾器(Oil Paint Filter),首先渲染畫筆描邊的法線貼圖,用於對傳入的場景進行扭曲。 然後使用相同的法線貼圖結合三個光源照亮影象空間中的筆觸(Brush stroke)。 而筆觸可以通過帶狀的粒子特效驅動,使過濾效果變得動態,並且在時間上更加連貫。

圖 《孢子》中的油畫後處理效果
1.2.2 水彩畫後處理效果 Watercolor Filter
對於水彩畫過濾器(watercolor filter)。首先,使用傳入場景的簡易Sobel邊緣檢測版本與原始場景相乘。 然後使用平滑濾波器(smoothing filter)的四個pass對結果進行平滑,且該平滑濾波器從四周的taps中找到每個pass的最亮值。 接著,基於邊緣檢測的輪廓新增一些在平滑過程中丟失的精確度。 具體核心程式碼如下,而offset和scales是可調的引數,允許我們改變繪製塗抹筆觸的大小。

圖 《孢子》中的水彩後處理效果
1.2.3 8位後處理效果 8-Bit Filter

圖 8-Bit Filter
要建立一個8位濾波器(8-Bit Filter),可以使用畫素著色器中的round函式,並通過點取樣繪製到遊戲解析度大小1/4的低解析度緩衝區中。 這是一個非常簡單的效果,使遊戲看起來像一箇舊式8位遊戲。
1.2.4 黑色電影后處理效果 Film Noir Filter
在建立黑色電影后處理效果時,首先將傳入的場景轉換為黑白。 然後進行縮放和偏移。新增一些噪聲,雨水顆粒效果是很好的畫龍點睛。

圖 《孢子》中黑色電影后處理效果
1.2.5 舊電影后處理效果 Old Film Filter
對於舊電影后處理效果,可以採用簡單的棕褐色著色與銳化濾波器(sharpen filter)相結合。 且可以使用粒子效果進行劃痕和漸暈的處理。

圖 舊電影后處理效果
關於《孢子》更多的風格化渲染的教程,可以在這裡找到:
http://www. spore.com/comm/tutorial s
二、《狂野西部:生死同盟》中的渲染技術 | Rendering Techniques in Call of Juarez: Bound in Blood
《狂野西部:生死同盟》(Call of Juarez: Bound in Blood)是由Techland公司開發,育碧發行,並於2009年夏季在PS3,Xbox360和PC上釋出的遊戲。

圖《狂野西部:生死同盟》封面

圖《GPU Pro 1》的封面,即是採用的《狂野西部:生死同盟》的圖片

圖 《狂野西部:生死同盟》遊戲截圖
《狂野西部:生死同盟》基於ChromeEngine 4,遊戲中大量用到了延遲著色(deferred shading)技術。
眾所周知,延遲著色 [Hargreaves 04]是一種在螢幕空間使用儲存了諸如漫反射顏色,法向量或深度值等畫素資訊的中間緩衝區(G-buffer)的技術。
G-buffer是一組螢幕大小的渲染目標(MRT),可以使用現代圖形硬體在單個pass中生成,可以顯著降低渲染負載。然後使用G-buffer作為著色演算法的輸入(例如光照方程),而無需瀏覽原始幾何體(此階段計算所需的所有信息,如三維世界空間中的畫素的位置,可以從G-buffer中提取)。以這種方式,演算法僅對可見畫素進行操作,這極大地降低了照明計算的複雜性。

圖 《狂野西部:生死同盟》中的MRT配置
延遲著色方法的主要優點是對渲染管線的簡化,節省複雜著色器資源和計算的開銷,以及能對複雜光照(如動態光源)進行簡約而健壯的管理。
延遲著色技術在與後處理渲染效果的結合方面可以獲得不錯的化學反應。在《狂野西部:生死同盟》中,延遲渲染與諸如螢幕空間環境光遮蔽(SSAO),運動模糊(motion-blur),色調對映(tone mapping)以及用於改善最終影象質量的邊緣抗鋸齒(edge anti-aliasing)等後處理效果都可以很好的結合使用。

圖 擁有動態光源和環境光遮蔽的室內場景
這章中還展示了不少《狂野西部:生死同盟》中自然現象效果的渲染方法,如雨滴,體積地面霧,light shafts,真實感天空和雲彩,水面渲染,降雨效果,以及體積光的渲染技巧。以及色調對映相關的技術。

圖 場景色調對映,在陰影區域和光照區域之間轉換
三、《正當防衛2》中的大世界製作經驗與教訓 | Making it Large, Beautiful, Fast,and Consistent: Lessons Learned
《正當防衛2(Just Cause 2)》是Avalanche Studios為PC,Xbox 360和PLAYSTATION 3開發的沙盒遊戲。遊戲的主要風格是大世界,主要視覺特徵是具有巨大渲染範圍的巨型景觀,森林、城市、沙漠、叢林各種環境不同的氣候,以及晝夜迴圈技術。

圖 《正當防衛2》封面
對於多動態光源的渲染,《正當防衛2》沒有使用延遲渲染,而是提出了一種稱作光源索引(Light indexing)的方案,該方案可以使用前向渲染渲染大量動態光源,而無需多個pass,或增加draw calls。
3.1 光照索引 Light indexing
光照索引(Light indexing)技術的核心思路是:通過RGBA8格式128 x 128的索引紋理將光照資訊提供給著色器。
將該紋理對映到攝像機位置周圍的XZ平面中,並進行點取樣。 每個紋素都對映在一個4m x 4m的區域,並持有四個該正方形相關的光源索引。這意味著我們覆蓋了512m × 512m的區域,且動態光源處於活動狀態。
活動光源儲存在單獨的列表中,可以是著色器常量,也可以是一維紋理,具體取決於平臺。雖然使用8位通道可以索引多達256個光源,但我們將其限制為64個,以便將光源資訊擬合到著色器常量中。每個光源都有兩個恆定的暫存器,儲存位置(position),倒數平方半徑(reciprocal squared radius)和顏色(color)這三個引數。

表 光源常量
此外,還有一個額外的“禁用(disabled)”光源槽位,其所有這些都設定為零。那麼總暫存器計數會達到130。當使用一維紋理時,禁用的光源用邊框顏色(border color)編碼替代。 位置和倒數平方半徑以RGBA16F格式儲存,顏色以RGBA8格式儲存。為了保持精度,位置儲存在相對於紋理中心的區域性空間中。
光源索引紋理在CPU上由全域性光源列表生成。一開始,其位置被放置在使得紋理區域被充分利用的位置,最終以儘可能小的空間,放置在攝像機之後。
在啟用並落入索引紋理區域內的光源中,根據優先順序,螢幕上的近似大小以及其他因素來選擇最相關的光源。每個光源都插入其所覆蓋的紋素的可用通道中。如果紋理畫素被四個以上的光源覆蓋,則需要丟棄此光源。
如果在插入時紋理畫素已滿,程式將根據圖塊中的最大衰減係數檢查入射光源是否應替換任何現有的光源,以減少掉光源的視覺誤差。這些誤差可能導致圖塊邊框周圍的光照不連續性。通常這些誤差很小,但當四處移動時可能非常明顯。而為了避免這個問題,可以將索引紋理對齊到紋素大小的座標中。在實踐中,光源的丟棄非常少見,通常很難發現。

圖 軸對齊世界空間中的光照索引。 放置紋理使得儘可能多的區域在視錐體內。 圖示的4m x 4m區域由兩個由R和G通道索引的光源相交。 未使用的插槽表示禁用的光源。
3.2 陰影系統 Shadowing System
陰影方面,《正當防衛2》中採用級聯陰影對映(cascaded shadow mapping)。並對高效能PC提供軟陰影(Soft shadows)選項。雖然在任何情況下都不是物理上的準確,但演算法確實會產生真正的軟陰影,而不僅僅是在許多遊戲中使用的恆定半徑模糊陰影。

圖 《正當防衛2》中的軟陰影。注意樹底部的銳利陰影逐漸變得柔和,以及注意,樹葉投下了非常柔和的陰影。
此軟陰影演算法的步驟如下:
1、在陰影貼圖中搜索遮擋物的鄰域。
2、投射陰影的樣本計為遮擋物。
3、將遮擋物中的中心樣本的平均深度差用作第二個pass中的取樣半徑,並且在該半徑內取多個標準PCF樣本並取平均值。
4、為了隱藏有限數量的樣本失真,取樣圖案以從螢幕位置產生的偽隨機角度進行旋轉。
3.3 環境光遮蔽 Ambient Occlusion
對於環境遮擋(AO),使用了三種不同的技術:
- 美術師生成的AO(artist-generated AO)
- 遮擋體(Occlusion Volumes)
- SSAO [Kajalin 09]
其中,美術師生成的環境光遮蔽用於靜態模型,由材質屬性紋理中的AO通道組成。此外,美術師有時會在關鍵點放置環境遮擋幾何。對於動態物件,使用遮擋體(OcclusionVolumes)在底層幾何體上投射遮擋陰影,主要是角色和車輛下的地面。而SSAO是PC版本的可選設定,裡面使用了一種從深度緩衝匯出切線空間的方案。
四、《礦工戰爭》中的可破壞體積地形 | Destructible Volumetric Terrain
知乎專欄字數限制的緣故,加入這章的內容後文章字數已超上限,所以請移步至 https://github.com/QianMo/Game-Programmer-Study-Notes 閱讀。不便之處,敬請諒解。
Part II. 渲染技術 Rendering Techniques
五、基於高度混合的四叉樹位移貼圖 | Quadtree Displacement Mapping with Height Blending
這章中,介紹了當前表面渲染(surface rendering)技術的概述和相關比較,主要涉及在如下幾種方法:
- Relief Mapping | 浮雕貼圖
- Cone step mapping (CSM) | 錐步對映
- Relaxed cone step mapping (RCSM) | 寬鬆錐步對映
- Parallax Occlusion Mapping(POM) | 視差遮蔽貼圖
- Quadtree Displacement Mapping(QDM)| 四叉樹位移貼圖
內容方面,文章圍繞表面渲染技術,分別介紹了光線追蹤與表面渲染、四叉樹位移對映(Quadtree Displacement Mapping)、自陰影(Self-Shadowing)、環境光遮蔽(Ambient Occlusion)、表面混合(Surface Blending)幾個部分。為了獲得最高的質量/效能/記憶體使用率,文章建議在特定情況下使用視差對映,軟陰影,環境遮擋和表面混合方法的組合。
此外,文中還提出了具有高度混合的四叉樹位移貼圖。對於使用複雜,高解析度高度場的超高質量表面,該方法明顯會更高效。此外,使用引入的四叉樹結構提出了高效的表面混合,軟陰影,環境遮擋和自動LOD方案的解決方案。在實踐中,此技術傾向於以較少的迭代和紋理樣本產生更高質量的結果。

圖 Parallax Occlusion Mapping(POM) 視差遮蔽貼圖和Quadtree Displacement Mapping(QDM)四叉樹位移貼圖和的渲染質量比較。其中,左圖為POM;右圖為QDM。深度尺寸分別為:1.0,1.5,5.0。可以發現,在深度尺寸1.5以上時,使用POM(左圖)會看到失真。


圖 表面混合質量比較。上圖:浮雕貼圖(Relief Mapping),下圖:帶高度混合的視差遮蔽貼圖(POM with height blending)
六、使用幾何著色器的NPR效果 | NPR Effects Using the Geometry Shader
本章的內容關於非真實感渲染(Non-photorrealistic rendering ,NPR)。在這章中,介紹了一組利用GPU幾何著色器流水線階段實現的技術。
具體來說,文章展示瞭如何利用幾何著色器來在單通道中渲染物件及其輪廓,並對鉛筆素描效果進行了模擬。
單通道方法通常使用某種預計算來將鄰接資訊儲存到頂點中[Card and Mitchell 02],或者使用幾何著色器 [Doss 08],因為可能涉及到查詢鄰接資訊。這些演算法在單個渲染過程中生成輪廓,但物件本身仍需要第一個幾何通道。
6.1 輪廓渲染(Silhouette Rendering)
輪廓渲染是大多數NPR效果的基本元素,因為它在物體形狀的理解中起著重要作用。在本節中,提出了一種在單個渲染過程中檢測,生成和紋理化模型的新方法。
輪廓渲染(Silhouette rendering)技術中, 兩大類演算法需要實時提取輪廓:
- 基於陰影體積的方法(shadow volume-based approaches)
- 非真實感渲染(non-photorealistic rendering)
而從文獻中,可以提取兩種不同的方法:
- 物件空間演算法(object-space algorithms)
- 影象空間演算法(image-space algorithms)
但是,大多數現代演算法都在影象空間(image space)或混合空間(hybrid space)中工作。本章中主要介紹基於GPU的演算法。GPU輔助演算法可以使用多個渲染通道或單個渲染通道來計算輪廓。
為了一步完成整個輪廓渲染的過程,將會使用到幾何著色器(geometry shader)。因為幾何著色階段允許三角形操作,能獲取相鄰三角形的資訊,以及為幾何體生成新的三角形。
輪廓渲染過程在流水線的不同階段執行以下步驟:
- 頂點著色器(Vertex shader)。 頂點以通常的方式轉換到相機空間。
- 幾何著色器(Geometry shader)。 在該階段中,通過使用當前三角形及其鄰接的資訊來檢測屬於輪廓的邊緣,並生成相應的幾何體。
- 畫素著色器(Pixel shader)。 對於每個柵格化片段,生成其紋理座標,並根據從紋理獲得的顏色對畫素進行著色。

圖 管線概述:頂點著色器(左)變換傳入幾何體的頂點座標;第二步(幾何著色器)為物件的輪廓生成新幾何體。最後,畫素著色器生成正確的紋理座標。

圖 輪廓渲染演算法的執行效果圖,輪廓剪影的實時生成和紋理化
實現Shader原始碼可見:
QianMo/GPU-Pro-Books-Source-Code6.2 鉛筆素描渲染(Pencil Rendering)
基於Lee等人[Lee et al. 06]鉛筆渲染思路可以概括如下。
首先,計算每個頂點處的最小曲率(curvature)。然後,三角形和其曲率值作為每個頂點的紋理座標傳入管線。為了對三角形的內部進行著色,頂點處的曲率用於在螢幕空間中旋轉鉛筆紋理。該鉛筆紋理會在螢幕空間中進行三次旋轉,每個曲率一次,旋轉後的結果進行混合結合。不同色調的多個紋理,儲存在紋理陣列中,同時進行使用。最終,根據光照情況在其中選擇出正確的一個。

圖 管線概述:頂點著色器將頂點轉換為螢幕空間;幾何著色器將三角形的頂點曲率分配給三個頂點。最後,畫素著色器生成三個曲率的紋理座標並計算最終顏色。
可以通過以下方式使用GPU管線實現此演算法:
- 頂點著色器(Vertex shader)。 頂點轉換為螢幕座標。頂點曲率也被變換,只有x和y分量作為二維向量傳遞。
- 幾何著色器(Geometry shader)。 將曲率值作為紋理座標分配給每個頂點。
- 畫素著色器(Pixel shader)。 計算最終顏色。
最終的渲染效果:

圖 鉛筆渲染效果圖
實現Shader原始碼可見:
Pencil.fx" target="_blank" rel="nofollow,noindex">QianMo/GPU-Pro-Books-Source-Code七、後處理Alpha混合 | Alpha Blending as a Post-Process
在這篇文章中提出了一種新的Alpha混合技術,螢幕空間Alpha遮罩( Screen-Space Alpha Mask ,簡稱SSAM)。該技術首次運用於賽車遊戲《Pure》中。《Pure》發行於2008年夏天,登陸平臺為Xbox360,PS3和PC。

圖 《Pure》中的場景(tone mapping & bloom效果)
在《Pure》的開發過程中,明顯地需要大量的alpha混合(alpha blending)操作。但是眾所周知,傳統的計算機圖形學的難題之一,就是正確地進行alpha混合操作,並且往往在效能和視覺質量之間,經常很難權衡。
實際上,由於不願意承擔效能上的風險,一些遊戲會完全去避免使用alpha混合。有關alpha混合渲染所帶來的問題的全面介紹,可以參考[Thibieroz 08],以及[Porter and Duff 84]。
在這篇文章中,提出了一種新穎的(跨平臺)解決方案,用於樹葉的alpha混合,這種解決方案可以提高各種alpha測試級渲染的質量,為它們提供真正的alpha混合效果。
文中設計的解決方案——螢幕空間Alpha遮罩(Screen-Space Alpha Mask ,簡稱SSAM),是一種採用渲染技術實現的多通道方法,如下圖。無需任何深度排序或幾何分割。
在《Pure》中使用的SSAM技術對環境的整體視覺質量有著深遠的影響。效果呈現出柔和自然的外觀,無需犧牲畫面中的任何細節。

圖 SSAM的技術思路圖示
此解決方案可以產生與alpha混合相同的結果,同時使用alpha測試技術正確解決每個畫素的內部重疊(和深度交集)。
文中使用全屏幕後處理高效地執行延遲alpha混合(deferred alpha blending),類似於將幀混合操作設定為ADD的幀緩衝混合;源和目標引數分別設定為SRCALPHA和INVSRCALPHA。
混合輸入被渲染成三個單獨的渲染目標(render targets),然後繫結到紋理取樣器(texture samplers),由最終的組合後處理畫素著色器引用。
在記憶體資源方面,至少需要三個螢幕解析度的渲染目標,其中的兩個至少具有三個顏色的通道(rtOpaque & rtFoliage),而另一個至少有兩個通道(rtMask)和一個深度緩衝區(rtDepth) 。
下面列舉一些SSAM的優點和缺點。
SSAM的優點:
- 樹葉邊緣與周圍環境平滑融合。
- 使用alpha測試技術,在每畫素的基礎上對內部重疊和相互穿透的圖元進行排序。
- 該效果使用簡單,低成本的渲染技術實現,不需要任何幾何排序或拆分(只需要原始排程順序的一致性)。
- 無論場景複雜度和overdraw如何,最終的混合操作都是以線性成本(每畫素一次)來執行運算。
- 該效果與能渲染管線中的其他alpha混合階段(如粒子等)完美整合。
- 與其他優化(如將光照移到頂點著色器)以及優化每個通道的著色器等方法結合使用時,總體效能可能會高於基於MSAA(MultiSampling Anti-Aliasing,多重取樣抗鋸齒)的技術。
SSAM的缺點:
- 需要額外的渲染Pass的開銷。
- 記憶體要求更高,因為需要儲存三張影象。
- 該技術不能用於對大量半透明,玻璃狀的表面進行排序(或橫跨大部分螢幕的模糊alpha梯度),可能會產生失真。
八、虛擬紋理對映簡介 | Virtual Texture Mapping 101
在這篇文章主要探討了如何實現一個功能完備的虛擬紋理對映(Virtual Texture Mapping,VTM)系統。
首先,虛擬紋理對映(VTM)是一種將紋理所需的圖形記憶體量減少到僅取決於螢幕解析度的技術:對於給定的視點,我們只將紋理的可見部分保留在圖形儲存器中適當的MIP對映級別上,如下圖。

圖 使用單個的虛擬紋理渲染出獨特的紋理地形
早期的紋理管理方案是針對單個大紋理設計的[Tanner et al. 98],文章發表期間的VTM系統則更加靈活,模仿了作業系統的虛擬記憶體管理的思路:將紋理分成小的圖塊(tiles),或者頁(pages)[Kraus and Ertl 02, Lefebvre et al.04]。這些會根據渲染當前視點的需要自動快取並載入到GPU上。但是,有必要將對缺失資料的訪問重定向(redirect)到後備紋理。這可以防止渲染中出現“空洞”(載入請求完成前的阻塞和等待的情況)。
文中的實現的靈感來源於GDC上Sean Barrett[Barret 08]的演講。如下圖所示,在每幀開始,先確定哪些圖塊(tiles)可見,接著識別出其中沒有快取且沒有磁碟請求的圖塊。在圖塊上傳到GPU上的圖塊快取之後,更新一個間接紋理(indrection texture,)或者頁表(page table)。最終,渲染場景,對間接紋理執行初始查詢,以確定在圖塊快取中取樣的位置。

圖 渲染圖塊ID,然後識別並更新最近可見的圖塊到圖塊快取中(圖中的紅色),並可能會覆蓋不再可見的圖塊(圖中的藍色)。更新間接紋理並渲染紋理化表面(texturized surfaces)
間接紋理(indirection texture)是完整虛擬紋理的縮小版本,其中每個紋素都指向圖塊快取(tile cache)中的圖塊。在文中的示例中,圖塊快取只是GPU上的一個大紋理,包含小的,相同解析度的正方形圖塊。
這意味著來自不同mip map級別的圖塊(tiles)會覆蓋虛擬紋理的不同大小區域,但會大大簡化圖塊快取的管理。
Part III、全域性光照 Global Illumination
九、基於間接光照的快速,基於模板的多解析度潑濺 Fast, Stencil-Based Multiresolution Splatting for Indirect Illumination
本章介紹了互動式即時輻射度(radiosity)解決方案的改進,該解決方案通過使用多解析度潑濺(multiresolution splats)技術,顯著降低了填充率(fill rate),並展示了其使用模板緩衝(stencil buffer)的一種高效實現。與最原始的多解析度潑濺[Nichols and Wyman 09]不同的是,此實現不通過幾何著色器執行放大,因此能保持在GPU快速路徑(GPU fast path)上。相反,這章利用了GPU的分層模板剔除(hierarchical stencil culling)和Z剔除(z culling)功能,以在合適的解析度下高效地進行光照的渲染。

圖 多解析度光照潑濺開始於直接光照的渲染(左圖)。每個VPL產生一個全螢幕的圖示,允許每個VPL為每個畫素提供光線。每個VPL產生一個全屏的潑濺,允許每個VPL為每個畫素提供光線。但根據本地照明變化的速度,這些圖層會以多種解析度呈現。偽彩色全屏潑濺(中圖)顯示了不同解析度的區域,這些區域被渲染為不同的buffer(右圖)

圖 多解析度片的迭代求精從統一的粗影象取樣開始(例如,162個取樣)。處理粗粒度片元,識別需要進一步求精的片元並建立四個更精細的解析度片元。進一步的操作會進一步細化片元直到達到某個閾值,例如最大精度級別或超過指定的片元數量。

圖 前一幅圖中的,多解析度潑濺可以進行平行計算而不是迭代計算(左圖)。右圖中的多解析度buffer中的片元,都為並行處理。
十、螢幕空間定向環境光遮蔽 Screen-Space Directional Occlusion (SSDO)
環境光遮蔽(AO)是全域性光照的一種近似,由於其良好的視覺質量和簡單的實現[Landis 02],其常常用於電影和遊戲中。環境光遮蔽的基本思想是預先計算網格表面幾個位置的平均可見性值。然後這些值在執行時與圖形硬體提供的未遮擋光照相乘。
環境光遮蔽的一個缺點是它僅適用於靜態場景。如果為每個頂點或紋理元素預先計算了可見性值,則在網格變形時這些值將無效。
動態場景的一些初步想法有[Bunnell 06]和[Hoberock and Jia07]通過用層次圓盤(hierarchy of discs)近似幾何體的思路。處理動態場景的最簡單方法是根據幀緩衝區中的資訊計算環境光遮蔽,即所謂的螢幕空間環境光遮蔽(SSAO)。這裡深度緩衝區用於在執行時計算平均可見度值而不是預先計算。這章內容發表期間的GPU算力已足以實時計算SSAO。此外,該方法不需要場景的任何特殊幾何的表現,因為僅使用到幀緩衝器中的資訊來計算遮蔽值。甚至不需要使用由多邊形組成的三維模型,因為我們可以從產生深度緩衝區的任何渲染計算遮擋。

圖 螢幕空間環境光遮蔽(SSAO):對於幀緩衝器中的每個畫素,檢查一組相鄰畫素,並將一個極小的球狀物體放置在相應的三維位置。為每個球體計算遮蔽值,並將所有這些值累積到一個環境遮蔽值中。最後,該值乘以來自所有方向的未被遮蔽的光照。
環境光遮蔽通常顯示空腔暗化(darkening of cavities)和接觸陰影(contact shadows),但忽略入射光的所有方向資訊。發生這種情況是因為只有幾何體用於計算環境光遮蔽,而忽略了實際光照。典型的問題情況如下圖所示:在方向變化的入射光的情況下,環境光遮蔽將顯示錯誤的顏色。因此,該章將SSAO擴充套件到稱之為螢幕空間定向遮擋(SSDO)的更真實光照技術。
由於迴圈遍歷片段程式中的許多相鄰畫素,因此可以為每個畫素計算單獨的可見性值,而不是將所有資訊摺疊為單個AO值。因此,基本思想是使用來自每個方向的入射光的可見性資訊,並僅從可見方向照射,從而產生定向的光照。
為對SSDO的資料做進一步描述,假設有一個深度幀緩衝區,其中包含每畫素的位置,法線和反射率值。

圖 環境光遮蔽的典型問題示例。由於紅色光源被遮擋而綠色光源照亮了點P,我們希望在這裡看到一個綠色的陰影。但環境遮擋首先計算來自所有方向的光照,因此點P最初為黃色,然後通過某個平均遮擋值進行縮放,從而產生了不正確的棕色。
本章提出的SSDO演算法具體可以總結如下:
- 首先,在畫素的三維點周圍放置一個半球,該半球沿著表面法線定向。該半球的半徑r_max是使用者引數,其用於決定搜尋阻擋物的本地鄰域的大小。
- 然後,將一些三維取樣點均勻分佈在半球內部。同樣,取樣點數N是用於時間質量平衡的使用者引數。
- 接著,測試每個取樣方向的光照是否被阻擋或可見。因此,我們將每個取樣點反投影到深度幀緩衝區。在畫素位置,可以讀取表面上的三維位置,並將每個點移動到表面上。如果取樣點朝向觀察者移動,則它最初位於表面下方並且被分類為被遮擋。如果它遠離觀察者,它最初在表面上方並且被分類為可見。
在下圖的示例中,點A,B和D在表面下方並被分類為遮擋物。只有樣本C可見,因為它在表面上方。因此,僅從方向C計算光照。

圖 SSDO螢幕空間定向環境光遮蔽。左圖:為了計算點P處的方向遮擋,在半球中建立一些均勻分佈的取樣點,並將它們反投影到深度幀緩衝區中。(最初)在表面下方的每個點被視為遮擋物。 右圖:僅從可見點計算光照。在這裡,假設每個取樣方向的立體角,並使用模糊環境貼圖傳入光亮度。

圖 螢幕空間定向環境光遮蔽(Screen-Space Directional Occlusion,SSDO)效果圖
十一、基於幾何替代物技術的實時多級光線追蹤 | Real-Time Multi-Bounce Ray-Tracing with Geometry Impostors
在實時應用中渲染反射和折射物體或它們的焦散(caustics)是一個具有挑戰性的問題。其需要非區域性著色,這對於光柵化渲染管線來說比較複雜,其中片段著色器只能使用區域性插值頂點資料和紋理來查詢曲面點的顏色。
物體的反射、折射和其焦散效果通常需要光線跟蹤進行渲染,但光線跟蹤通常不具備與光柵化渲染相同的效能。
而通常,使用基於紋理的特殊tricks可以將光線跟蹤效果加入到實時場景中。這些技術通常假設場景中只有一個反射或折射物體,並且僅考慮一次或兩次反射光就足夠了。在這章中,遵循了類似的實踐原理,但是除去這些限制,以便能夠渲染布滿玻璃碎片的完整棋盤,甚至折射物體浸沒在動畫液體中等場景。
這章中擴充套件了先前基於環境距離替代物技術(environment distance impostors)的近似光線追蹤技術,以便在當時硬體條件的限制下,實時渲染具有多個反射和折射物體的場景。
有兩個關鍵的思路。
首先,文章改為使用距離替代物(distance impostor)方法,不將內部光線(internal rays)與封閉的環境幾何體相交,而是將外部光線(external rays)與物體相交。另外,這章展示瞭如何高效地追蹤二次反射和折射光線,還研究了可以適應相同的任務的其他型別的幾何替代物技術 – 如幾何影象(geometry images)[Carr et al. 06]和高度場(height fields)[Oliveira et al. 00, Policarpo et al. 05]。
第二個思路是靜態和動態物件的分離。經典的距離替代物(distance impostors)技術可以用於靜態環境,只需要在每一幀中更新移動物件的環境替代物(environment impostors)。通過搜尋幾何替代物(geometry impostors)可以找到穿過移動物體的光路。

圖(a)環境距離替代物技術(environment distance impostor)(b)具有搜尋投影前兩步策略的物體距離替代物(Object distance impostor)

圖 左:整個測試場景。 右:使用高度圖替代物進行雙折射。
這章中擴充套件了先前基於環境距離替代物技術(environment distance impostors)的近似光線追蹤技術,以便在當時硬體條件的限制下,實時渲染具有多個反射和折射物體的場景。
當然,隨著技術的發展,2018年已經有了RTX技術,實時光線追蹤已經不在話下。以下便是一個能展現實時光線追蹤魅力的NVIDIA RTX Demo:

Part IV. 影象空間 Image Space
十二、 GPU上的各項異性的Kuwahara濾波 | Anisotropic Kuwahara Filtering on the GPU
這章中介紹一種各向異性的Kuwahara濾波器[Kyprianidis et al. 09]。各向異性的Kuwahara濾波器是Kuwahara濾波器的一種廣義上的變體,通過調整濾波器的形狀,比例和方向以適應輸入的區域性結構,從而避免了失真。由於這種適應性,定向影象特徵被更好地儲存和強調,得到了整體更清晰的邊緣和更具特色的繪畫效果。

圖 原始影象(左),對各向異性的Kuwahara濾波輸出(右)。沿著區域性特徵方向產生繪畫般的增強效果,同時保留形狀邊界。
12.1 Kuwahara濾波器(Kuwahara Filtering)
Kuwahara濾波器背後的一般思想是將濾波器核心分成四個重疊一個畫素的矩形子區域。濾波器的響應由具有最小方差的子區域的平均值來定義。

圖 Kuwahara濾波器將濾波器核心分成四個矩形子區域。然後過濾器響應由具有最小方差的子區域的平均值來定義

圖 Kuwahara濾波器的輸出效果圖
12.2 廣義Kuwahara濾波器(Generalized Kuwahara Filtering)
而廣義Kuwahara濾波器,為了克服不穩定次區域選擇過程的侷限性,定義了一個新的標準。結果被定義為次區域平均值的加權總和,而不是選擇一個單獨的次區域。權重是根據子區域的差異來定義的。 這導致區域邊界更平滑並且失真更少。為了進一步改善這一點,矩形子區域被扇區上的平滑權重函式所取代:

圖 廣義的Kuwahara濾波器使用定義在光碟扇區上的加權函式。濾波過濾器響應被定義為區域性平均值的加權總和,其中對具有低標準偏差的那些平均值賦予更多的權重。

圖 廣義Kuwahara濾波器的輸出效果圖
12.3 各向異性Kuwahara濾波器(Anisotropic Kuwahara Filtering)
廣義的Kuwahara濾波器未能捕獲定向特徵並會導致叢集的失真。而各向異性的Kuwahara濾波器通過使濾波器適應輸入的區域性結構來解決這些問題。在均勻區域中,濾波器的形狀應該是一個圓形,而在各向異性區域中,濾波器應該變成一個橢圓形,其長軸與影象特徵的主方向一致。

圖 各向異性Kuwahara濾波器圖示
十三、基於後處理的邊緣抗鋸齒 | Edge Anti-aliasing by Post-Processing
知乎專欄字數限制的緣故,加入這章的內容後文章字數已超上限,請移步至 https://github.com/QianMo/Game-Programmer-Study-Notes 閱讀。不便之處,敬請諒解。
十四、基於Floyd-Steinberg半色調的環境對映 | Environment Mapping with Floyd-Steinberg Halftoning
這章中提出了一種使用GPU計算重要性取樣的演算法。該演算法巧妙地應用了經典的半色調技術,可用於加速高質量環境對映照明中的重要性取樣步驟。
這章想傳達的最重要的資訊是半色調(halftoning)演算法和重要性取樣(importance sampling)是等價的,因此我們可以在重要性取樣中使用半色調演算法。文中研究了Floyd-Steinberg半色調方法在環境對映中的應用,並得出結論認為,該方法可以比隨機抽樣更好地對樣本進行分配,所以,對的樣本計算的積分也會更準確。

圖 左圖為隨機取樣加權環境貼圖(Sampling weighted environment maps);右圖為弗洛伊德 - 斯坦伯格取樣半色調環境對映(Floyd-Steinberg halftoning)

圖 光源取樣結果。隨機取樣基於Floyd-Steinberg半色調對映通過方向光源對兔子模型的漫反射和鏡面光照。
十五、用於粒狀遮擋剔除的分層項緩衝 | Hierarchical Item Buffers for Granular Occlusion Culling
知乎專欄字數限制的緣故,加入這章的內容後文章字數已超上限,請移步至 https://github.com/QianMo/Game-Programmer-Study-Notes 閱讀。不便之處,敬請諒解。
十六、後期製作中的真實景深 | Realistic Depth of Field in Postproduction
景深(Depth of field,DOF)是一種典型的攝影效果,其結果是根據攝像機與攝像機的距離而產生不同的聚焦區域。
這章中,提出了一種互動式GPU加速的景深實現方案,其擴充套件了現有方法的能力,具有自動邊緣改進和基於物理的引數。散焦效應通常由模糊半徑控制,但也可以由物理特性驅動。此技術支援在影象和序列上使用灰度深度圖影象和引數,如焦距,f-stop,subject magnitude,相機距離,以及影象的實際深度。
另外,景深實現中額外的邊緣質量改進會產生更逼真和可信的影象。而區域性鄰域混合演算法的缺點是二次計算能力,但這其實可以通過GPU進行補償。

圖 景深效果圖

圖 模擬曝光的光圈孔徑形狀示例
十七、實時螢幕空間的雲層光照 | Real-Time Screen Space Cloud Lighting
在創造逼真的虛擬環境時,雲是一個重要的視覺元素。實時渲染美麗的雲可能非常具有挑戰性,因為雲在保持互動式幀率的同時會呈現出難以計算的多重散射(multiple scattering)。
目前的問題是,大多數遊戲都無法承擔精確計算物理上正確的雲層光照的計算成本。
本章介紹了一種可以實時渲染真實感的雲層的非常簡單的螢幕空間技術。這種技術已經在PS3上實現,並用於遊戲《大航海時代Online》(Uncharted Waters Online)中。這項技術並不關注嚴格的物理準確性,而是依靠重新建立雲層的經驗外觀。另外需要注意的是,此技術適用於地面場景,玩家可以在地面上觀看,並且只能從遠處觀看雲層。
光照是創造美麗和真實感雲彩最重要的方面之一。當太陽光穿過雲層時,被雲層中的粒子吸收,散射和反射。下圖展示了一個典型的戶外場景。

圖 一個典型的戶外場景。 最靠近太陽的雲顯示出最大的散射並且看起來最亮
如圖所示,從圖中所示的檢視看雲層時,最靠近太陽的雲顯得最亮。這種現象是由於太陽的光線到達雲層的後方,然後通過多次散射,在雲的前部(最靠近觀察者)重新出現。這一觀察結果是這章所介紹技術的關鍵部分。為了再現這種視覺提示,螢幕空間中的簡單點模糊或方向模糊足以模仿通過雲層的光散射。
17.1 實現方案
這章的雲層渲染技術可以分為三個pass執行:
- 首先,渲染雲密度(cloud density)為離屏渲染目標(RT),且雲密度是可以由藝術家繪製的標量值。
- 其次,對密度貼圖(density map)進行模糊處理。
- 最終,使用模糊的密度貼圖來渲染具有散射外觀的雲層。

圖 基於這章技術實現的demo截圖
在demo中,雲層被渲染為一個統一的網格。 雲層紋理在每個通道中包含四個密度紋理。每個通道代表不同的雲層,根據第一個通道中的天氣在畫素著色器中混合。並且也通過滾動紋理座標UV來實現動畫。
總之,這章提出了一種實時渲染的真實感天空的技術。由於雲的形狀與光源分離,程式化雲的生成和程式化動畫都可以支援。
需要注意的是,此方法忽略了大氣的某些物理特性,以建立更高效的技術。例如,不考慮大氣的密度,但這個屬性對於創造逼真的日落和日出是必要的。也忽略了進入雲層的光的顏色。在日落或日出的場景中,只有靠近太陽的區域應該明亮而鮮豔地點亮。有必要採取更基於物理的方法來模擬太陽和雲之間的散射,以獲得更自然的結果。
十八、螢幕空間次表面散射 | Screen-Space Subsurface Scattering
同樣是知乎專欄字數限制的緣故,加入這章的內容後文章字數已超上限,請移步至 https://github.com/QianMo/Game-Programmer-Study-Notes 閱讀。不便之處,敬請諒解。
Part V. 陰影 Shadows
同樣,“第五部分 陰影 Shadows”的四章內容,也因為字數超上限的緣故,無法在這裡放進來。這邊是一個快捷的傳送門:
QianMo/Game-Programmer-Study-Notes
本文的GitHub版
假如你仔細閱讀這篇文章到這裡,你會發現不止一處的原文因為知乎專欄字數限制的原因被省略,而且這還沒有算上很多核心演算法的Shader實現程式碼。
如果對這些內容感興趣,建議閱讀沒有因為字數限制原因被刪減的完全版。
【本文的GitHub版本傳送門】:
QianMo/Game-Programmer-Study-NotesThe End.
下次更新,《GPU Pro 2》全書核心內容提煉總結,再見。
With best wishes.