【GPU精粹與Shader編程】(五) 《GPU Gems 2》全書核心內容提煉總結 · 下篇

  

                          本文由@淺墨_毛星雲 出品,首發於知乎專欄,轉載請註明出處  

                          文章鏈接: https://zhuanlan.zhihu.com/p/40288273

 

本文核心內容爲《GPU Gems 2》中講到的真實感水體渲染,以及真實感頭髮渲染、通用的折射模擬、改進的Perlin噪聲等次核心內容。

 

前言

之前和同事們討論水體渲染時,大家說到目前業界水體實時渲染效果領先的遊戲引擎,是Cry Engine。Cry Engine中的水體渲染可謂目前水體渲染方案中的集大成者,汲取了圖形業界近幾十年水體渲染各種思路的精華。以下是Cry Engine 中的水體渲染實時畫面:

視頻鏈接:https://www.youtube.com/watch?v=tZthI6M07iM

 

注意這是6年前Cry Engine 3的水體渲染實時畫面,很多人感覺其效果已經達到了近乎真實。

而目前的Cry Engine 5,渲染質量還會更勝一籌。

值得開心的是,Cry Engine已經開源,其水體渲染的具體shader實現代碼可以在Cry Engine源碼中找到,以下是其中核心代碼Water.cfx的傳送門,感興趣的朋友不妨瞭解一下:

https://github.com/CRYTEK/CRYENGINE/blob/26524289c15a660965a447dcb22628643917c820/Engine/Shaders/HWScripts/CryFX/Water.cfx

值得注意的是,本文中提到的一些渲染水體的策略與思路,在Cry Engine 5實現水體渲染中,也有所體現。

OK,下面開始正題。

 

 

目錄 · 本文核心內容Highlight

 

本文將進行重點提煉總結《GPU Gems 2》中的主核心內容有:

  • 一、將頂點紋理位移用於水的真實感渲染(Using Vertex Texture Displacement for
    Realistic Water Rendering)

本文將進行提煉總結《GPU Gems 2》中的次核心內容有:

  • 二、利用像素着色器分支的高效模糊邊緣陰影(Efficient Soft-Edged Shadows Using Pixel Shader Branching)
  • 三、通用的折射模擬(Generic Refraction)
  • 四、快速三階紋理過濾(Fast Third-Order Texture Filtering)
  • 五、高質量反走樣的光柵化(High-Quality Antialiased Rasterization)
  • 六、快速預過濾線條(Fast Prefiltered Lines)
  • 七、Nalu Demo中的頭髮動畫與渲染(Hair Animation and Rendering in the Nalu Demo)
  • 八、使用查找表加速顏色變換(Using Lookup Tables to Accelerate Color Transformations)
  • 九、實現改進的Perlin噪聲(Implementing Improved Perlin Noise)
  • 十、高級高質量過濾(Advanced High-Quality Filtering)
  • 十一、Mipmap層級測定(Mipmap-Level Measurement)

 

 

I、核心章節提煉篇

 

一、將頂點紋理位移用於水的真實感渲染(Using Vertex Texture Displacement for Realistic Water Rendering)

 

【內容概覽】

真實地渲染出水的質感是一個困難的問題,因爲水表面的運動具有高度的視覺複雜性,且水的光影效果也很複雜。而這章中,介紹了爲遊戲《太平洋戰機》開發的對海水的真實感渲染技術。

圖 《太平洋戰機》中的海水渲染

 

【核心要點】

 

1.1 水體渲染模型的分析

Gems2中這篇文章問世期間(2005年),當時最真實的水體渲染實現方法是基於流體動力學和快速傅里葉變換(FFT)[Tessendorf 2001],但遺憾的是這種方法需要大量的計算,不適用於交互應用程序。

大多數遊戲當時使用的是很簡單的水模型,而其中的大多數採用了法線貼圖來生成視覺細節,優點是計算量小,缺點是很多時候不能提供足夠的真實感,並且不能真實重現水面的波浪。

而本文中介紹了一種能達到簡單法線貼圖方法的速度,但渲染質量類似於FFT方法的水面渲染技術。

 

1.2 實現思路概覽

本文的水體渲染主要實現思路是基於法線貼圖計算光照的渲染算法。因爲法線圖在高頻的波浪中能夠真實地產生精細的細節,所以將它用於光照的計算。除此之外,還對水模型的幾何表面做了大振幅低頻波浪的擾動。

 

1.3 水體的表面模擬

水體表面的模型是基於幾張高度圖(Height maps)的疊加,這些高度圖在空間和時間上不斷重複。每張紋理表示一個“諧波(harmonic)”或“倍頻(octave)”頻譜,然後這些紋理被疊加到一起,類似傅里葉分析中的做法。

而這些紋理之所以稱爲高度圖,因爲其中每個值代表了對應點相對於水平面的高度值。高度圖對於美術同學來說創建非常容易,與創建和渲染灰度圖一樣簡單。利用高度圖,水的動畫參數規約成一些獨立的波,美術同學只要繪出它們的形狀就可以很容易地控制水的動畫。高度圖也對頂點紋理有用:因爲可以很容易地對頂點進行豎直方向的位移。

圖18-2 一張用於水面位移的高度圖

通過用不同的空間和時間範圍來結合若干高度圖,可以得到視覺上非常複雜的動畫:

係數A和B以及求和的項數是由經驗決定的,以求達到美學角度上最好的結果,同時減少重複圖案的痕跡。在《太平洋戰機》中,疊加4張高度圖用於計算光照,其中最大範圍的兩張用於位移貼圖。這對模擬動態的海洋表面來說已經足夠了,可選範圍爲10cm到40km(10釐米到40千米)之高。

 

1.4 實現細節概述

可以把所有需要實現的計算分爲兩部分:

  • 幾何位移計算
  • 光照計算

因爲水面細分得很精細,所以可以只在片段程序級實現光照計算,而把位移映射的工作移交給頂點級,以減輕片段的負擔。需要注意,如果在頂點級實現光照計算可能產生明顯的走樣,尤其是遠處的物體。

 

1.5 對高度圖採樣

文中的實現是在每個頂點上對高度圖進行採樣,並且在頂點程序中計算應該取的位移值。爲了計算採樣,使用了一箇中心在相機位置的徑向柵格(radial grid)。這個柵格的細分特點是離視點越近則提供越多的細節,如下圖所示

下面的方程表示了徑向柵格上的頂點位置的計算方法:

其中,i=[0..N - 1], j = [0..M - 1]。選擇a0,a1,使

使用這種方法,可以得到根據距離細分的柵格,也體現了一個簡單的層次細節LOD策略。其他方案,如ROAM或SOAR地形渲染算法,也可以用於此處,但是它們需要在CPU上進行大量計算,會減弱使用頂點紋理的優勢。而我們也可以嘗試在GPU中渲染自適應鑲嵌柵格的高度域。

下面的代碼列出了着色器的實現細節,用一個徑向柵格對單張高度圖進行採樣。

float4 main(float4 position : POSITION,
uniform sampler2D tex0,
uniform float4x4 ModelViewProj,
uniform float4 DMParameters, // displacement map parameters
uniform float4 VOfs) : POSITION
{
    // Read vertex packed as (cos(), sin(), j)
    float4 INP = position;

    // Transform to radial grid vertex
    INP.xy = INP.xy * (pow(INP.z, 4) * VOfs.z);

    // Find displacement map texture coordinates
    // VOfs.xy, DMParameters.x - Height texture offset and scale
    float2 t = (INP.xy + VOfs.xy) * DMParameters.x;

    // Fetch displacement value from texture (lod 0)
    float vDisp = tex2D(tex0, t).x;

    // Scale fetched value from 0..1:
    // DMParameters.y - water level
    // DMParameters.z - wavy amplitude
    INP.z = DMParameters.y + (vDisp - 0.5) * DMParameters.z;

    // Displace current position with water height
    // and project it

    return mul(ModelViewProj, INP);
}

 

1.6 提高渲染質量與優化性能的一些方案

 

1.6.1 爲雙線性過濾打包高度值

訪問頂點紋理的代價十分昂貴,在舊的GeForce 6系列的硬件上,一個頂點紋理的訪問會在頂點程序中產生明顯的延遲。所以比較合適的策略是把頂點程序中訪問紋理的次數降到最低。另一方面,過濾紋理值非常必要,否則圖像質量就會顯著降低。

爲了減小插值時紋理訪問的次數,可以用一種特別的方法創建紋理,這樣使每個紋理包含了一次雙線性紋理查找必需的所有數據。因爲高度圖本質上是單通道的紋理,可以把四個高度值打包到一張四通道紋理的一個紋素內,以實現優化。

 

1.6.2 使用分支避免不需要的工作

即使使用了優化的紋理過濾,渲染水體時,訪問紋理的次數仍然很高,這會嚴重影響性能。一種方法是減少渲染的頂點數,但是這將全面地降低視覺上的細節並且增加失真度。

需要渲染的水體含有大量的幾何數據,但其中有些三角面完全在屏幕之外。對這樣的三角形,頂點程序仍然要進行處理,這其實是一種浪費。如果能跳過在相機視野之外三角形的相關計算,就可以在每個頂點上節約大量的工作。

以下的僞代碼表達了這個方法的實現:

float4 ClipPos = mul(ModelViewProj, INP);
float3 b0 = abs(ClipPos.xyz) < (ClipPos.www * C0 + C1);
if (all(b0))
{
    // Vertex belongs to visible triangle,
    // Perform texture sampling and displace vertex accordingly
}

在上面的代碼中,使用了裁剪空間的頂點位置來確定當前的頂點是否位於視野之中,然後只對需要的頂點進行復雜運算即可。

 

1.6.3 使用渲染到紋理策略(Render-to-Texture)

仍然可以使用上文提到的,用一張浮點紋理來壓縮存儲高度紋理的方法,先將其作爲單獨的pass來執行,以提高運行速度。而在頂點着色器裏面實現多次昂貴的插值操作就變得沒有太多必要。另外,可以用一個更緊湊的16位浮點紋理格式來存儲原始的高度圖。也可以存儲一系列高度圖序列幀作爲三維紋理的切片,以使動畫更加流暢。

經過上述優化,我們的渲染循環變成了如下兩個pass:

(1)通過使用將單個四邊形渲染爲32位浮點紋理的特殊像素着色器,來組合高度貼圖。而此紋理中的各個紋素映射到徑向柵格的各個頂點。

(2)使用生成的高度貼圖作爲頂點紋理來平移徑向柵格頂點。

 

1.6.4 處理波浪的背面

大量的光照計算是在像素着色器中實現的。其假設了水面是水平的,而這個假設在某些情況下可能導致視覺效果的走樣。

在下圖所示的情況下,我們看到了波浪的背面,它在平面上是能被看見的,但是因爲幾何位移的關係它會背向觀察者,所以在現實世界中並不應該出現。而這樣的錯誤會在波浪的頂部產生奇怪的過亮區域。

圖 渲染走樣的產生

圖注:波浪(綠色)的背面也可能被渲染出來,儘管它並不應該出現。調整計算光照的法線將大大減少這種錯誤。

爲了儘量減少這種錯誤,可以將計算光照時使用的法線稍微做調整,將他們朝向觀察者方向“傾斜”一些,這樣他們會更接近於波浪的正向面。

 

1.7 渲染局部擾動的策略

有時渲染渲染因爲浮起物或者掉入水中的物體引起的波浪局部的起伏。這對遊戲來說尤爲重要,因爲遊戲需要產生類似於爆炸,船的行進痕跡等效果。因爲很難繼承物理上正確的方法將其用於這個基於高度圖的水面模型中來,所以這裏只根據經驗討論一些簡單的方法。

 

1.7.1 解析型形變模型(Analytical Deformation Model)

造成局部波浪起伏最簡單的方法是把頂點的位移值做成一個解析上的擾動,把擾動和頂點着色器中計算好的頂點位置結合起來。

實現局部波浪起伏最簡單的方法是通過將頂點位移與頂點着色器中計算的頂點位置相結合,來解析地擾動位移的頂點位置。對爆炸而言,可以用下面的公式:

其中,r是水平面上該點到爆炸中心的距離,b是一個常數,I_0,ω和k的值根據一個給定的爆炸及其參數決定。

在渲染時,可以使用和普通水體渲染時相同的徑向柵格,尤其是在爆炸點。

 

1.7.2 動態位移貼圖(Dynamic Displacement Mapping)

另一個選擇是將所有的局部創建的位移量直接渲染到頂點紋理,本質上是和GPU通用編程(GPGPU)類似的方法。這樣,在第一個pass中生成頂點紋理,而在後續pass中,用此紋理來進行實際的水體渲染。另一個好處是,通過在像素着色器中過濾基礎高度圖和累加倍頻程(octaves),可以把一些工作從頂點着色器轉移到像素着色器中。

爲了計算位移量,既可以採用前面提到的解析型模型,也可以用自動控制單元(cellular-automata)的方法,將局部位移進行逐幀衍變。也可以考慮風的效果,對紋理沿着適當的方向進行模糊。

圖 用位移貼圖渲染的水錶面(左)和不用位移圖渲染的水錶面(右)對比

 

1.7.3 泡沫的生成(Foam Generation)

在波浪足夠強時,可以通過製造泡沫來加強真實感。最簡單的方法是把一個預先創建的泡沫紋理在高於某一高度H0的頂點上進行混合。泡沫紋理的透明度根據以下公式進行計算:

其中,H_max是泡沫最大時的高度,H_0是基準高度,H是當前高度。

泡沫紋理可以做成動畫來表示泡沫的產生和消失的進化過程。這個動畫序列既可以由美術同學製作,也可以由程序生成。

 

 

【核心要點總結】

 

本文的水體渲染實現思路是基於法線貼圖計算光照的渲染算法,水體表面的模型爲基於幾張高度圖(Height maps)的疊加。在每個頂點上對高度圖進行採樣,並且在頂點程序中計算應該取的位移值。計算採樣方面,使用了一箇中心在相機位置的徑向柵格(radial grid),以及結合了一些優化的策略。

 

1.提高渲染質量與優化性能的方案

1)爲雙線性過濾打包高度值:因爲高度圖本質上是單通道的紋理,可以把四個高度值打包到一張四通道紋理的一個紋素內,以實現優化。

2)使用分支避免不需要的工作:使用裁剪空間的頂點位置來確定當前的頂點是否位於視野之中,然後只對需要的頂點進行復雜運算即可。

3)使用渲染到紋理策略(Render-to-Texture)

4)處理波浪背面:將計算光照時使用的法線稍微做調整,將他們朝向觀察者方向“傾斜”一些,這樣他們會更接近於波浪的正向面。

 

2.渲染局部擾動的策略

1)解析型形變模型(Analytical Deformation Model)

2.動態位移貼圖(Dynamic Displacement Mapping)

3.泡沫的生成:預先創建的泡沫紋理在高於某一高度H0的頂點上進行混合,其中泡沫紋理的透明度根據公式進行計算。

 

【配套源代碼】

這篇文章公開了其詳細的實現源碼,具體可以在這裏找到:

https://github.com/QianMo/GPU-Gems-Book-Source-Code/tree/master/GPU-Gems-2-CD-Content/Shading_Lighting_and_Shadows/Ch_18_Using_Vertex_Texture_Displacement_for_Realistic_Water_Rendering

其中shader代碼位於fpWaterDM.cg,vpWaterDM.cg兩個文件中。其中也提供了可運行的demo exe,其運行效果如下:

 

 

 

【關鍵詞】

水渲染(Water Rendering)

頂點紋理位移(Vertex Texture Displacement)

高度貼圖(Height Mapping)

雙線性過濾(Bilinear Filtering)

 

 

II、次核心章節提煉篇

 

二、利用像素着色器分支的高效模糊邊緣陰影(Efficient Soft-Edged Shadows Using Pixel Shader Branching)

【章節概覽】

在計算機圖形學中,渲染真實的陰影一直是難題之一,尤其是軟陰影(soft shadow)的渲染。且陰影是一種非常重要的視覺信息,它們有助於確立場景中物體的空間相對關係。

這章介紹了一種通過片段着色器中的PCF技術達到的實時渲染模糊(軟)邊界陰影的快速方法。

 

【核心要點】

文中首先講到陰影渲染技術中最常見的兩種流派模板陰影/陰影體(Stencil Shadow / Shadow volume)和陰影貼圖(Shadow Map)。

兩種方法都各有其優缺點。且提到了這兩種方法都不能直接用於“超出框”的模糊邊界陰影。

隨後這章介紹了一種以交互速率渲染模糊陰影的方法,其能高質量地模擬真實的模糊陰影。該方法使用了百分比鄰近過濾(Percentage-Loser Filtering, PCF)技術,在片段着色器中不斷對陰影圖自適應地多次採樣。這章自適應的採樣方法與採樣方法與採樣數固定的方法相比,能在保證高性能的同時提高畫面質量。

圖 基於文中方法實時渲染出的模糊邊緣陰影

【關鍵詞】

軟陰影(Soft Shadows)

模糊邊緣陰影(Soft-Edged Shadows)

模板陰影/陰影體(Stencil Shadow /Shadow volume)

陰影貼圖(Shadow Map)

百分比鄰近過濾(Percentage-Loser Filtering, PCF)

 

三、通用的折射模擬(Generic Refraction)

【章節概覽】

本章介紹了一種折射的實現方案,思路是對場景中非折射的物體生成一幅圖像,把該圖像當做紋理,然後對查找該紋理的座標進行擾動來達到模擬折射的目的。這種技術效率很高,而且很多情況下都有效。

【核心要點】

折射(Refraction)是當光從一種媒介穿到另一種折射率不同的媒介(如從空氣到水,從空氣到玻璃等)時產生的彎曲現象。

要模擬折射有很多種方法:其中一些方法是先預計算環境映射,然後在運行時使用;而其他方法是直接在運行時計算環境映射。這些技術的缺點是耗費大量的紋理存儲空間並損失運行效率,尤其是當場景中有很多折射表面時,需要不同的環境映射。

而目前的水折射模擬技術的另一個問題是他們需要渲染兩遍:第一個pass通過水麪上的幾何信息來生成折射圖,另一個pass渲染水面。這種方案的性能很低,尤其對複雜的場景而言。

本章介紹了一種簡單的技術來克服這些問題。從介紹基本想法開始,把現有的後臺緩存當做一個折射貼圖來用,並且通過對紋理座標進行位移來模擬折射的效果。最基本的實現可能導致走樣,因此文中討論瞭如何將幾何圖形從折射圖貼圖中標註出來。最後演示了一些用該方法渲染真實的水和玻璃的通用技術。

圖 彩色玻璃的渲染步驟(a)折射 (b)環境凹凸映射 (c)最終的合成

這章給出的模擬折射的方法,雖然不是基於物理的,但是能得到質量很好的結果,且速度非常快。

但此方法的缺陷是,當應用到不同顏色的折射表面上時,在表面重疊的地方會得到不正確的結果。只要折射表面的顏色相近,結果看上去就是正確的。一個正確的解決方案就是,對摺射網格從後到前進行排序,然後每次渲染一個折射網格時都更新一次折射圖。或者用另一個不夠準確的方案,對摺射網格從後到前進行排序,在用alpha混合來渲染它們。

【關鍵詞】

折射(Refraction)

水的渲染(Water Rendering)

玻璃的渲染(Glass Rendering)

 

 

四、快速三階紋理過濾(Fast Third-Order Texture Filtering)

 

【章節概覽】

 

對可編程圖形硬件可以在使用片段着色器上使用通用的卷積過濾器來實現高質量的紋理過濾,如立方(cubic)過濾器[Bjorke 2004]。這些方法通常有許多缺點:它們需要進行多次紋理採樣,而且無法對mipmap的紋理進行反失真處理。

而在本章中,介紹了一種能有效減少三階紋理過濾需要輸入的紋理數量的方法,使用了1D、2D及3D空間中的三次B樣條(B-spline)曲線的卷積核和它的一階、二階導數來解決這些過濾問題。

 

【核心要點】

高階紋理過濾的主要性能瓶頸是需要大量的紋理採樣作爲輸入。通常是通過對輸入紋理進行重複最近鄰近(Repeated Nearest-Neighbor)採樣實現。爲了減少採樣的次數,基於線性採樣來建立過濾器,這種方法能大量減少紋理採樣的次數,尤其是2D和3D過濾。特別是能通過8次三線性紋理採樣來完成一個需要64次累加操作的三立方(tricubic,也譯作三重三次)過濾器。

圖 三次B樣條(Cubic B-Spline)和其導數

(a)f_1和過濾器權重w_i(x)的卷積
(b)三次樣條曲線的一階導數;(c)三次樣條曲線的二階導數

 

總而言之,本章介紹了一個能有效減少高階紋理過濾需要的對輸入紋理進行採樣的次數。而前提是假設一個線性採樣操作和一個最鄰近採樣一樣快(至少不慢太多)。對三階過濾器核(如三次B樣條)曲線過濾器進行了優化,讓它只需要非常少的線性紋理採樣次數。

而事實上,片元着色器裏的代碼更像一個手工寫的線性插值程序,而不是一個立方過濾器。

 

【關鍵詞】

紋理過濾(Texture Filtering)

高階過濾(Higher-Order Filtering)

B樣條過濾( B-Spline Filtering)

三次B樣條(Cubic B-Spline)

快速遞歸三次卷積(Fast Recursive Cubic Convolution)

 

 

五、高質量反走樣的光柵化(High-Quality Antialiased Rasterization)

 

【章節概覽】

這章介紹了一種分塊的超採樣(supersampling)技術,使用任意寬度和高採樣率的自定義過濾器,可以用來渲染任意分辨率的圖像,以實現高質量的反走樣光柵化。

 

【核心要點】

如上所言,文中介紹了一種分塊的超採樣(supersampling)技術,描述瞭如何把一個圖像分成塊(tiles,也稱爲buckers),用高分辨率渲染每一塊,然後降採樣(downsample,即收縮)每一塊以達到最終分辨率,在即使構造的片元程序中使用分離式的降採樣。文中也介紹瞭如何在圖像分塊之間進行正確的重疊和延伸的細節問題。文中提供的代碼可以很輕易地集成到現有的渲染系統中,而不需要對現有的代碼進行大的改動。

圖 將圖像分解成tiles

對於最終圖像的每一個分塊,總體算法如下:

(1)把圖像塊渲染到一個大的離屏緩衝區中,調整投影矩陣,以現有的渲染代碼把3D幾何體用高採樣率的分辨率渲染出來。

(2)把高分辨率的圖像塊用一個分離式的過濾器核進行降採樣,通過使用實時生成的片元程序在屏幕上渲染兩個全屏的四邊形來實現。

(3)把低分辨率的圖像塊累加到最終圖像中,或通過把圖像塊的數據讀回到CPU中,或使用另外一個片元程序把圖像塊加入到最終圖像中。

 

【關鍵詞】

反走樣光柵化(Antialiased Rasterization)

分塊超採樣(tiled supersampling)

降採樣(downsample)

 

 

六、快速預過濾線條(Fast Prefiltered Lines)

 

【章節概覽】

這章介紹了一種簡單有效的繪製反走樣(抗鋸齒)的線條的方法。

 

【核心要點】

本章提到的預過濾(Prefiltered)方法最早由McNamara, McCormack, 和 Jouppi在2000年提出,其有諸多優點。首先該方法能使對稱的過濾器在運行時提供固定的開銷;其次,和一般硬件支持的過濾器不同,本方法不僅僅對只處於像素內的點進行採樣,它能支持更大範圍的過濾器,反走樣的結果是硬件無關的,這保證了在不同GPU上能得到相同的反走樣結果。

圖 比較細線和粗線的反走樣效果

總之,通過對從中心到邊界不同距離處,把直線和過濾器的卷積結果進行卷積,並將結果存儲在一個查找表中來預過濾線條。

該方法允許相同的運行時開銷開使用任意的對稱過濾器。而且,該算法只需要很少的CPU和GPU運算、帶寬及存儲空間開銷。這些特性使這種算法對大部分的實時渲染程序都有實用價值,如繪製圍欄、電線以及遊戲中其他細長的物體。

 

【關鍵詞】

預過濾線條(Prefiltered Lines)

反走樣/抗鋸齒(Antialiasing )

線條的反走樣(Antialiasing Lines)

 

 

七、Nalu Demo中的頭髮動畫與渲染(Hair Animation and Rendering in the Nalu Demo)

 

【章節概覽】

這章講到了NVIDIA公司的Nalu Demo中的頭髮動畫和渲染技術。

圖 Nalu的頭髮

 

【核心要點】

NVIDIA的Nalu demo中,要達到的目標是渲染在水中飄動的金色長髮。這章將介紹用於實時達到這個目標所用的技術。這種技術包含一個模擬頭髮運動系統,一個計算頭髮自陰影的陰影生成算法,還有一個通過每一串頭髮來模擬光線散射的發射模型。把這些結合起來,就能實時創建出極其真實的頭髮渲染效果。

在Nalu頭髮的後臺着色處理中,有一個在每幀裏生成頭髮幾何和控制動感與碰撞的系統。基本上分成兩部分:幾何生成器和動感/碰撞的計算。

這些頭髮是由4095條用直線圖元來渲染的獨立髮絲組成。僅僅在渲染頭髮上就使用了123000個頂點。讓所有這些頂點通過動力學和碰撞檢測就將慢得無法接受,因此使用受控髮絲(control hair):儘管需要渲染成千次,但Nalu的髮型能通過一組每組幾百根髮絲來描述和控制。所有開銷大的動態計算都運用於這些受控髮絲。

頭髮的實時反射模型方面,選用了Marschner反射模型(2003)。而在渲染頭髮的陰影方面,採用了一種針對渲染頭髮陰影設計的近似陰影——非透明陰影圖(Opacity shadow maps)(Kim and Neumann 2001)。

圖 基於Marschner反射模型的頭髮渲染

圖 Marschner反射模型的查找紋理(Lookup Textures)

 

【關鍵詞】

頭髮渲染(Hair Rendering)

頭髮動畫(Hair Animation)

Marschner反射模型(Marschner Reflectance Model)

非透明陰影圖(Opacity Shadow Maps)

 

八、使用查找表加速顏色變換(Using Lookup Tables to Accelerate Color Transformations)

 

【章節概覽】

這章中,介紹了一種利用三維查找表的算法來實時處理高分辨率圖像的方法。

 

【核心要點】

在函數的計算開銷很大,但是把計算結果緩存起來的開銷比較小時,用查找表(Lookup
Table,簡稱LUT)優化這種函數的計算是一種非常好的方法。通過預先把一些常見輸入的對應結果計算出來,花費不多的查找操作就能代替開銷較大的運行時計算。如果查找比開頭開始計算結果(或者有不斷重複的相同輸入)要快,那麼使用查找表就能提高程序性能。

這章中,介紹了一種利用三維查找表的算法來實時處理高分辨率圖像的方法。這種方法有非常出色的性能,它與執行顏色操作的數量無關,與顏色操作的複雜度也無關,即能獨立於顏色運算的數量和顏色變換的複雜度。涉及到的主要實現有,把查找表映射到GPU、着色器的實現、系統集成以及把三維查找表擴展到高動態範圍圖像等步驟。

圖 一個三維的查找表

 

圖 顏色校正流水線的比較。左圖爲傳統的顏色校正流水線,通過發送低分辨率的圖像來用作硬件加速的基礎。右圖爲基於三維查找表的加速流水線。

 

【關鍵詞】

查找表(Lookup Table, LUT)

顏色變換(Color Transformations)

 

 

九、實現改進的Perlin噪聲(Implementing Improved Perlin Noise)

 

【章節概覽】

這章上接《GPU Gems 1》中奧斯卡得主大牛Ken Perlin撰寫的第五章[Perlin
2004],《GPU Gems 1》中Ken Perlin的章節討論了該如何使用3D紋理實現過程噪聲的快速近似,在這裏描述一個改進噪聲算法的GPU實現,其也完全符合用CPU進行實現。

 

【核心要點】

Perlin算法由兩個主要階段組成。

第一階段在3D空間的每個整數(x,y,z)位置產生一個可重複的僞隨機值。這可以以多種方式思想,但是Perlin的算法是使用一個散列函數。散列函數基於一個包含以隨機順序0~255的整數排列的表(這張表可以在實現之間進行標準化,以便它們產生相同結果)。首先,這張表是基於位置的x座標索引,然後將y座標添加到表中該位置的值中,並使用結果再次在表中查一次表。然後爲z座標重複一次此過程。對z座標重複此過程後,結果爲每個可能的(x,y,z)位置的僞隨機整數。

在算法中的第二階段,將上述僞隨機整數用於索引入一個3D梯度向量的表中。在“改良的”算法中,只用8個不同的梯度。這個梯度和噪聲空間中的小數位置求點積可以得到一個標量值。最後的值通過空間中相鄰8個點的噪聲值插值獲得。

Perlin改良的噪聲算法是將CPU實現的排列表和梯度表存儲在數組中。由於像素着色器當時不支持索引入常量存儲器中,所以將這些表存儲在紋理中,並使用紋理查找來訪問它們。紋理尋址設爲環繞(或重複)模式,因此不必考慮擴充表以避免索引越過數組結尾,如同在CPU實現中一樣。

本章介紹了對像素着色器中的程序化噪聲的實現。程序化噪聲是豐富渲染外觀一個重要的部分,而且它可以用於凹凸貼圖和其他效果。

圖 基於過程凹凸貼圖的pixel着色器噪聲

 

【關鍵詞】

Perlin噪聲(Improved Perlin Noise)

改進的Perlin噪聲(Improved Perlin Noise)

 

十、高級高質量過濾(Advanced High-Quality Filtering)

 

【章節概覽】

這章提供了一個基於GPU紋理過濾的實現細節和解決方案,其中重點放在紋理插值和反走樣問題。

 

【核心要點】

本章闡述了一系列用於渲染紋理表面的高質量紋理過濾方法。這些技術可以用來執行許多常見的圖像任務,如縮放、扭曲、銳化等。除此之外,用這些方法渲染簡單的帶紋理的3D場景時,還可以提供比圖形硬件上的標準過濾器更好的渲染效果。

這章提到的技術是爲質量最優的渲染而設計的,對高幀率的實時交互的程序和遊戲來說依然顯得昂貴,它更適合哪些渲染質量比速度更重要的程序,如醫療和科學圖像、照片和電影編輯、圖片合成、視頻格式轉換、專業3D渲染等。它也能用於遊戲中與分辨率無關的紋理準備(預處理)當中。

另外,文中還介紹了一種適合用於增強重建圖像的銳化過濾方法——衝擊過濾衝擊過濾(Shock Filtering),其能把紋理插值平滑地變換成陡峭的變換。

圖 衝擊過濾(Shock Filtering)方法

 

【關鍵詞】

GPU紋理過濾(GPU-based texture-filter)

紋理插值( texture interpolation)

反走樣/抗鋸齒(antialiasing )

衝擊過濾(Shock Filtering)

 

十一、Mipmap層級測定(Mipmap-Level Measurement)

 

【章節概覽】

這章講到了使用“僞着色”(false-colored)的mipmap來代替原來的多級紋理進行場景渲染的方法。這樣的mipmap每層都有不同的比對色。且這章展示瞭如何用GPU來自動化僞着色的整個過程。

 

【核心要點】

僞着色(false-colored)的mipmap,結合基於GPU的方法,可以高效地運用在遊戲引擎中,可見的mip層次將被動態地反饋入引擎的紋理管理程序以減少內存消耗量。而所節省的內存可以用來增加別處的紋理分辨率,改進場景的華麗程度。Climax在Leviathan引擎中對地形場景使用了這項技術,使紋理空間節約了80%的內存,並沒有任何可察覺的視覺質量損失。

圖 對地形場景應用僞着色mipmap方法

圖(a)地形場景適用Climax的Leviathan引擎渲染(b)通過下圖“定標紋理”,將原紋理替換成僞着色的mipmap後的效果。可以看到最高的層(黃顏色)幾乎不可見。

圖 定標紋理

 

【關鍵詞】

紋理管理(texture management)

僞着色(false-colored)

Mipmap層級(Mipmap-Level)

 


本文的GitHub版
 

不少朋友們喜歡看GitHub版本的文章,我也很喜歡。

首先,MarkDown可以很方便地插入快捷導航目錄,能進行瞬間跳轉到指定子章節。其次,GitHub版本的文章中沒有單篇文章的字數限制,少了很多篇幅方面的桎梏。而且因爲Git的便利性,版本管理的優勢,最新的勘誤和修訂,以及新文章的更新,第一時間會在GitHub的Repo中進行。

【本文的GitHub版本傳送門】:

https://github.com/QianMo/Game-Programmer-Study-Notes/tree/master/Content/%E3%80%8AGPU%20Gems%202%E3%80%8B%E5%85%A8%E4%B9%A6%E6%8F%90%E7%82%BC%E6%80%BB%E7%BB%93/Part2

 

附錄:配套資源與源代碼下載

這裏提供了一些,《GPU Gems 2》書本的配套資源以及源代碼的下載地點。

PS:配套的不少工程中不僅包含完整的源碼,也直接包含經過編譯後的exe執行文件,可以直接運行後查看效果。

《GPU Gems 2》全文的Web版本:

https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_inside_front_cover.html

也有維護一個名爲“GPU-Gems-Book-Source-Code”的GitHub倉庫,以備份《GPU Gems》系列書籍相關的珍貴資源,《GPU Gems 2》的隨書CD和源代碼可以在這裏下載到:

https://github.com/QianMo/GPU-Gems-Book-Source-Code

以上。

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