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


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

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




《GPU Gems 2》這本書除了豐富的內容之外,還有兩個特點。
  • 首先,《GPU Gems 2》是虛幻引擎之父Tim Sweeney作序。作爲Epic Games的創始人,Unreal Engine早期主要開發者,Tim也在序中展示了《GPU Gems 2》出版伊始(2005年3月)時開發完成的Unreal Engine 3。UE3可謂是開創了一個時代。隨後包括《新鬼泣》在內的100+款大作(2005年~2015年),都是基於UE3開發。具體列表可見:https://en.wikipedia.org/wiki/List_of_Unreal_Engine_games
  • 然後,《GPU Gems 2》的中文版是龔大@叛逆者2005年開始翻譯的,距今已13年。13年前龔大就已經是圖形學業界一線大牛,實在是讓人佩服不已。

另外,雖然本書出版於2005年,但可以不誇張地說,書中介紹的很多方法技巧trick,哪怕是放到現在,依然非常值得學習和借鑑。
ok,篇幅原因,開場話就不多說了,我們直接開始正題。


本文的GitHub版

 

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

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

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

https://github.com/QianMo/Game-Programmer-Study-Notes



目錄 · 本文核心內容Highlight


本文將進行重點提煉總結的主核心內容有:
  • 一、實現照片級真實感的虛擬植物(Toward Photorealism in Virtual Botany)
  • 二、GPU通用計算:流式編程與存儲體系(General-Purpose Computation on GPU)

本文將進行提煉總結的次核心內容有:
  • 三、使用基於GPU幾何體裁剪圖的地形渲染(Terrain Rendering Using GPU-Based Geometry Clipmaps)
  • 四、幾何體實例化的內幕(Inside Geometry Instancing)
  • 五、分段緩衝(Segment Buffering)
  • 六、用多流來優化資源管理(Optimizing Resource Management with Multistreaming)
  • 七、讓硬件遮擋查詢發揮作用(Hardware Occlusion Queries Made Useful)
  • 八、帶位移映射的細分表面自適應鑲嵌(Adaptive Tessellation of Subdivision Surfaces with Displacement Mapping)
  • 九、使用距離函數的逐像素位移貼圖(Per-Pixel Displacement Mapping with Distance Functions)
  • 十、S.T.A.L.K.E.R.中的延遲着色(Deferred Shading in S.T.A.L.K.E.R.)
  • 十一、動態輻照度環境映射實時計算(Real-Time Computation of Dynamic Irradiance Environment Maps)
  • 十二、近似的雙向紋理函數(Approximate Bidirectional Texture Functions)
  • 十三、基於貼面的紋理映射(Tile-Based Texture Mapping)
  • 十四、動態環境光遮蔽與間接光照(Dynamic Ambient Occlusion and Indirect Lighting)
  • 十五、精確的大氣散射(Accurate Atmospheric Scattering)

I、核心章節提煉篇


一、實現照片級真實感的虛擬植物(Toward Photorealism in Virtual Botany

圖 真實感植物渲染 @UE4


【內容概覽】


衆所周知,植物的渲染需要很多的視覺深度和細節才能令人信服。
本章即關於渲染逼真自然場景的技術,描述了對實時遊戲引擎友好的、用於渲染更真實的自然場景的策略。講述了在不需要大量CPU或GPU佔用的前提下渲染出包含大量植物和樹組成的綠色植物場景。
內容安排方面,這章從管理大型戶外環境場景數據這一基礎開始描述。然後,提供一些細節,例如關於如何最大化GPU吞吐量,以便可以看到密集的草叢。接下來擴展這些技術,增加地面雜物和大型植物,如樹,將陰影和環境影響組合進去。
一些真實感植物渲染的效果圖:

圖 真實感植物渲染 @UE4


圖 真實感植物渲染 @UE4

圖 真實感植物渲染 @UE4

【核心內容提煉】


1.1 場景管理(Scene Management)


任何3D遊戲引擎都應該有環境相關渲染技術的管理和組織。
遊戲引擎必須管理其渲染技術,以適合於它們希望看到的環境範圍。以自然場景爲主的遊戲由上千棵樹,灌木和可能上百萬片草葉組成。直接分開渲染會出現數據管理問題,只有解決了這一問題才能以交互的幀率實時渲染。
我們的目標是在一個逼真的室外場景中大範圍地移動遊戲相機,而不需要在任務管理上花費過多的存儲器資源。

1.1.1 種植柵格(The Planting Grid)


場景管理方面,首先是使用了虛擬柵格的思路。
我們在相機周圍建立一個世界空間固定的柵格,來管理每一層的植物和其他自然物體的種植數據。每個柵格單元包含渲染它所在物理空間層的所有數據。特別是,單元數據結構存儲了對應的頂點、索引緩衝區和材質信息來再現需要繪製的內容。
對植物的每個層,建立相機到層的距離,層需要用它來產生視覺效果,這決定了虛擬柵格的大小。相機移動,虛擬柵格也隨之移動。當一個柵格單元不再在虛擬柵格中時,丟棄它,並在需要維護完整柵格結構的地方添加新的單元。在添加每個單元格時,用一種種植算法把渲染所需的數據填充到層。如下圖。


圖 一個虛擬柵格
圖注:每層有一個世界空間對齊的固定大小的柵格。深綠的單元表現爲活動單元。當相機向前移動時,丟棄標記爲X的單元,添加新的單元(顯示爲亮綠色)以維持虛擬柵格的大小,實現過程中有用的改進是使用柵格單元池且循環使用,因爲當一箇舊單元被丟棄時,總會增加一個新單元。

1.1.2 種植策略(Planting Strategy)


對於充滿自然物體的每個單元,需要在地面上選擇要放置物體的適當位置。採用試探的方法根據被放置對象的類型來選擇這些點。通常,需要的密度隨機選點,然後看地面上的對應點是否適合於要種植的東西。而地面多邊形的材質決定了一個層是否適用。
最顯然的方式是在單元體中隨機發射光線,直達地面,每當擊中一個多邊形,檢查它是否適合種植(判斷:草能種在這裏嗎?斜度會不會太大?),如果成功,那麼就得到了一個種植點,繼續這個過程,直到到達合適的密度。
這種方法不能處理重疊地形,且在少數柵格單元中,可能會花費過多的CPU時間。
比較好的方法是,選擇所有與單元相交的多邊形,丟棄所有不合適種植的多邊形,然後掃描並轉換它們來尋找合適的種植點。這與渲染管線中的光柵化一個多邊形類似。

1.1.3 實時優化(Real-Time Optimization)


實時優化種植策略的方法包括,選擇一個柵格單元中的多邊形可以通過使用AABB樹或類似的數據結構來快速完成。而由於相機的連續運動,許多單元可能要突然種植,所以它也可以高效地讓這個任務排隊,使任務在每幀中只佔用相對固定的CPU資源。而通過擴大柵格,可以確保在單元的內容進入視野之前,所有的種植就已完成。

1.2 草地層(The Grass Layer)


實時渲染出無邊的草地需要GPU技術和算法的細心平衡,主要的挑戰是在相對低的計算和渲染開銷下產生高度複雜的視覺外觀。
這章的這一節中介紹了一種和[ Pelzer 2004]“渲染無數波動的草葉”相似的技術,且這章的技術以更低的GPU和CPU負載產生更高質量和更穩定的結果。
圖 真實感草地渲染

首先,需要保證批次的最大化。該技術的目標是如何用相對較少的渲染API調用來繪製出儘可能多的草地,合理的方式是基於公告板。但其實更好的方式是在一次繪製調用中渲染儘可能多的內容(即一次drawcall渲染多個公告板)。
爲實現這個目的,草的每一層(即使用相同紋理和其他參數的所有草)的每個柵格單元由一個頂點和一個索引緩衝區對錶現。如下圖。
圖:繪製每個柵格的單元結構
對種植的每個草叢(或公告板),將其位置寫入頂點緩衝區並更新對應的索引緩衝區。每個公告板需要4個頂點和6個索引。對每個頂點,將位置設置爲已經種植草叢的點。
一旦頂點緩衝區建立併發送到顯存,就可以用單次調用畫出每個柵格單元的植物。
與Pelzer的方法不同的是,這裏使用面向相機的公告板代替每叢3個方形,而且其方法沒有進行屏幕對齊。面向屏幕的公告板在所有的視角下(即便向下看)創建一個固定的深度。而相機越是由上往下看草叢,3個方形叢的方法就越會失效。所以本文提到的方法,更加靈活,適用更多相機角度的情況。

1.2.1 通過溶解模擬Alpha透明(Simulating Alpha Transparency via Dissolve)


在渲染草的時候,想要使用透明來改善視覺混合和在接近虛擬柵格邊界時的淡出。然而,基於Alpha的透明並不理想,因爲它需要排序且速度很慢。雖然可以利用草較爲雜亂的性質最小化一些排序技術,但實際上可以完全忽略這種做法。
爲此,採取溶解效應(dissolve effect),也稱紗門效應(screen-door effect)的方法,代替Alpha混合來模擬透明。首先,用一個噪音紋理調製草紋理的Alpha通道,然後使用Alpha測試從渲染中去除像素,通過從0到1調節Alpha測試數值,紋理表現出溶解的現象。這一過程如下圖所示。
圖 草紋理的構成
(a)漫反射紋理; (b)美工創建的alpha通道; (c)Perlin噪音紋理;(d)Perlin噪音與Alpha相乘的結果。這可以在像素着色器,或固定的Alpha測試值產生淡出。
這項技術的有點是Alpha測試的速度快而且與順序無關。我們不再需要排序,草依然可以在遠處淡出。雖然溶解在正常的情況下看起來不像真實的Alpha透明那麼好,但可以利用自然的分形屬性來完全掩飾任何溶解技術的視覺失真。
而實驗表明,使用Perlin噪音紋理(Perlin 2002)代替隨機的噪音紋理,則溶解效應與環境的適配程度幾乎與Alpha透明一樣好。

1.2.2 變化


爲增加真實感,需引入一些變化。一種方式是使用多種草的圖像,但分批方法限制我們在每個繪製調用中只能用一張紋理。好在可以使用大紋理,把多種草排布在上面,在建立頂點的時候,可以調整UV座標以旋轉紋理的不同子區域(即可以建立一個紋理圖集)。
每個公告板也能帶有顏色信息。如果在種植時也爲每個草叢建立一種顏色,那麼對渲染灰度紋理或在頂點着色器中做細微的顏色偏移非常有用。Perlin噪聲在這裏也可以使用,而且很容易,例如,草可以從健康的顏色過渡到垂死的褐色染色,以獲得寬廣的顏色變化並減少草的重複性。

圖 使用RGB信息來增加草地的真實感 @ GeNa @Unity5
圖 使用RGB信息來增加草地的真實 @ GeNa @Unity5


圖 使用RGB信息來增加草地的真實感 @ GAIA @Unity 5
【注:每顆草的頂點中都包含RGB的信息。在此場景中,顏色值來自Perlin噪聲函數,模擬了比較綠的草,並修補了不太健康的褐色】

1.2.3 光照


光照在草的外觀上扮演了重要的角色。對於公告板草,要確保草和下面的地面一樣受光。而地面自然起伏,並因此獲得了不同角度的光照。我們需要通過減弱草的亮度來模擬這點,因此,需要知道草所在的地面角度,一個簡單方法是在頂點定義中通過另一個向量傳遞這一信息。
在種植的時候,確定正在種植的草的多邊形法線並把它帶入公告板定義中。通過這種方式,頂點着色器就可以進行和草下多邊形一樣的光照計算、從而減弱它的彩色。在多丘陵的地形上,這會導致草和地面一樣也有細微的到光的角度信息變化。
遺憾的是,這種方式導致草有一面一面的着色現象,即使地面的多邊形是幾乎平滑着色(如Gouraud着色)。爲了避免這個問題,在種植處理期間必須平滑地插值通過頂點着色器的法線。
而如果太陽的角度是動態的,可以假設地面法線都大致向上,然後基於此法線和光的角度來計算光照。這樣,就不一定要將地面的多邊形法線帶入頂點的定義和後續計算。這是一個畫質的權衡,但這種方式對於應用程序來說已經完全足夠。

1.2.4 風


當風吹過,草地泛起漣漪,草變得鮮活起來了。
通過每一幀偏移草方形頂部的兩個頂點,可以使方形在風中搖擺。可以使用一個正弦近似的和計算這個偏移,類似計算水表面的波動[Finch 2004]。這個技巧是在頂點定義中帶一個混合權重,草方形的頂部兩個頂點被設爲1,底部兩個頂點爲0,然後把這一數值乘以風的縮放係數,底部的頂點仍然牢牢地依附在地上。
對於另外的變化,可以在種植期間略微隨機變換頂部的兩個頂點權重。這模擬了草的軟硬區別。
在風中搖曳的時候,草葉時常改變其對光的方向,導致它們變亮或變暗,我們可以使用專門的風項來增加光照變化,以模擬這一現象。這極大地改善了風的視覺效果,甚至也能改善遠處草叢的效果,雖然那裏的物理搖擺變形以及變成子像素大小了。
然而,不允許風係數使草方形變形太多,否則產生的形變將會顯得滑稽而不真實。謹記細微是關鍵。

1.3 地面雜物層(The Ground Clutter Layer)


地面不僅只有隨風擺動的草,細枝、小植物、岩石和其他碎片共同組成了具有自然複雜性的效果。其中,一些雜物和草一樣可以當做公告板表現。
而但當我們混入混合各種幾何對象物體時,環境的複雜度也就增加了。
和處理草公告板的方法一樣,對於每個柵格元素,可以把3D網格數據解開到頂點和索引緩衝區中,以使它們可以在單次調用中繪製。我們必須把地面雜物分組爲使用相同的紋理和着色器的層。可以像選擇種植點那樣,應用隨機變換來改變它們的大小和方向,但是變換必須依據網格的特性,例如岩石是可以顛倒過來的,但是灌木顛倒就不行了。對於另外的變化,如同處理草多邊形一樣,可以通過傳遞RGB信息來給物體染色。
另外,用於處理順序無關透明特效的溶解技術在3D網格和公告板上工作起來完全一樣。把perlin噪聲紋理調製到紋理的alpha通道,並使用到相機的衰減距離,然後alpha測試溶解3D網格,類似處理草公告板。

圖 使用地面雜物來增加密集的細節@UE4 @Landscape Auto Material


圖 使用地面雜物來增加密集的細節@UE4

1.4 樹和灌木層(The Tree and Shrub Layers)


樹的樹幹和主要的樹枝應該建模成3D網格。次級樹枝可以用公告板來模擬,以增加視覺的複雜性。因爲樹的枝葉繁茂,所以可以用類似於草的技術,用面向相機的公告板建立樹葉叢。
因爲樹需要在長距離上維護它們的基本體積,但高細節渲染又很昂貴,所以必須使用層次細節(LOD)策略。當樹退到一定距離後,可以使用較大但較少的葉叢公告板。對於較大的公告板,使用帶有較多但較小樹葉的紋理。
而在一個適當的距離之外,最後想要用一個面向相機的公告板表現一顆樹。當樹的輪廓不對稱時,會相對困難。爲了避免這個問題,可以爲公告板產生樹在各種不同角度的圖片,然後根據樹和相機的角度混合它們。


圖 樹的多級LOD與公告板 @UE4


圖 樹的多級LOD與公告板 @UE4
灌木和葉片可作爲另一種類型的樹,和普通的樹使用相同的技術。例如,一個茂盛的灌木可以看做一棵樹幹很小,或者不存在樹幹的樹。此外,我們可以翻轉一棵樹,去掉樹葉,並獲得一個精心製作的暴露的根系,去嫁接上一棵正常的樹。


圖 灌木LOD與billboard @UE4


圖 灌木的渲染 @UE4

1.5 陰影(Shadowing)


因爲傳遞了草和地面雜物的RGB顏色,所以可以爲陰影的區域選擇較暗的顏色。這需要知道植物是否在陰影中。爲了在自然環境中有效,這種陰影只需要非常接近正確的陰影即可。

圖 草在樹產生的陰影中 @UE4


圖 草在樹產生的陰影中 @UE4 @Landscape Auto Material

一種方法是在種植時確定陰影。只需從植物位置向主要光源(太陽)投射一道陰影試探光線(shadow feeler ray),看看是否有相交。如果有,根據周圍場景的環境顏色調整RGB值。記住投射陰影試探光線只考慮是否有相交(不只是最近的),所以其可以比標準的碰撞光線投射高效得多。
軟陰影(Soft shadows),在上下文中叫抗鋸齒陰影(antialiased shadows)其實更合適,可以通過投射一個以上的陰影試探(shadow feeler)來實現。下圖演示了這一方法,通過細微地偏移每道光線的開始位置,在一個給定點上可以進行3~5次光線投射。擊中的部分用來在漫反射太陽光的和場景的環境光之間減弱光照。偏移越寬,陰影就越模糊。
圖 使用光線投射的可見性測試

圖注:從種植點向光源(在這個例子中是方向光)投射陰影試探光線。幾乎發生的任何碰撞都可以表明這個點是在陰影中。爲得到一個模糊陰影,需要投射另外的偏移陰影試探光線,並使用擊中的部分決定多少環境光的顏色。需要注意的是,不要讓陰影試探光線立刻與種植點的地平面相交嗎,否則這次試探就沒有意義了。

這些陰影不是動態的,但是對於移動緩慢的光源來說,可以很快地在間隔中重新計算(如太陽的移動)。一般來說,它們提供了充分的視覺信息,把風景變得更栩栩如生。
當投過樹的大部分時,可以使用樹葉茂密部分的球體或樹幹的圓柱體碰撞。對於樹葉茂密部分,使用一個基於樹葉茂密的隨機函數來確定光線是否相交。雖然這種陰影技術是粗糙的,但和正確的解決方案沒有明顯的差別。
如果種植是作爲離線處理預計算的,那麼可以極大地提高陰影逼真度。一種可能比陰影試探光線方法更好的方法是獲取光照圖(light map)的紋素來確定陰影。如果光照圖不在系統內存中,在實時處理方面可能有困難。

1.6 後處理(Post-Processing)


後處理方面,輝光(glow)和泛光(bloom),以及用高斯(Gaussian)模糊實現自然柔和的效果,都是比較合適進行照片級真實感植物渲染的後處理效果。

圖 使用了多種後處理效果的渲染圖 @UE4

圖 使用了多種後處理效果的渲染圖 @UE4


圖 使用了多種後處理效果的渲染圖 @UE4

1.7 業界領先的植物渲染解決方案SpeedTree


也需要提到的是,SpeedTree是很優秀的樹與灌木層的中間件,是植物渲染方面業界領先的解決方案。自2008年以來的各種一線3A遊戲,如《蝙蝠俠》、《使命召喚》、《神祕海域》系列,包括近期的《彩虹六號》、《孤島驚魂5》、《地平線:黎明》、《絶地求生》、《最終幻想15》等遊戲,都使用了SpeedTree作爲樹木植物相關渲染的解決方案。
電影方面,包括最近的《復仇者聯盟3》、《黑豹》在內的好萊塢大片,以及早一些的《速度與激情8》《魔獸》《星球大戰:原力覺醒》等大片,也都使用了SpeedTree作爲樹木植物相關渲染的解決方案。


圖 SpeedTree · CINEMA的宣傳圖


圖 SpeedTree · GAME的宣傳圖


圖 電影《星球大戰 原力覺醒》中的Speed Tree @https://www.speedtree.com/starwars.php

【核心要點總結】


【場景管理方面】
採用虛擬柵格的思路,實時優化種植的策略是使用AABB樹類似的數據結構來選擇一個柵格單元中的多邊形。

【草地渲染方面】
基於公告板進行渲染,保證渲染批次的最大化、通過溶解模擬Alpha透明。
調整UV座標以旋轉紋理、使用RGB信息等方法來減少重複,增加真實感
草地的光照:多邊形法線並把它帶入公告板定義中,參與光照計算。滑地插值通過頂點着色器的法線,來解決草有一面一面的着色的現象。也可以假設地面法線都大致向上,然後基於此法線和光的角度來計算光照。
草地與風的交互:使用一個正弦近似的和計算這個偏移,類似計算水表面的波動[Finch2004],也可以使用專門的風項來模擬草地因風而出現的光照變化。

【地面雜物層方面】
3D網格結合公告板的渲染、通過溶解模擬Alpha透明。

【陰影方面】
基於陰影試探光線(shadow feeler ray)、基於樹葉茂密的隨機函數來確定光線是否相交、基於光照圖(light map)的紋素來確定陰影。

【樹與灌木層】
樹幹和主要樹枝建模成3D網格,次級樹枝用公告板。LOD。多個角度的公告板混合。

【後處理】
輝光(glow)、泛光(bloom )、高斯(Gaussian)模糊

最後再上幾張渲染圖,都來自虛幻4引擎:






【關鍵詞提煉】

真實感植物渲染(Photorealistic Botany Rendering)
場景管理(Scene Management)


二、GPU通用計算:流式編程與存儲體系(General-Purpose Computation on GPU)


【內容概覽】


本節是原書中第IV部分”Part IV: General-Purpose Computation on GPUS: APrimer”的精華提煉版。

【核心內容提煉】


2.1 流式計算(Stream Computation)


首先,CPU不適合用於許多高性能應用程序的部分原因是其採用了串行編程模型(serialprogramming model),無法在應用程序中利用並行性(parallelism)和通信模式(communication patterns)。而GPU採用了流式編程模型(stream programming model),本節中將講到該模式允許高效計算和通信的方式來構造程序[Kapasi et al.2003],且它是今天GPU編程的基礎。

2.2.1 流式編程模型


在流式編程模型中,所有數據都表現爲流(stream)。我們把流定義爲具有相同數據類型的數據有序集。數據類型可以是簡單的(整數或浮點數流)或複雜的(點或三角形或變換矩陣流)。流可以是任意長度,如果流很長(流中有上百或者更多的元素),那麼流上的操作效率將很高。流上允許的操作包括複製,從中導出子流,用一個單獨的索引流索引入,以及用核在其上執行計算。
核(kernel)操作整個流,獲取一個或多個流作爲輸入併產生一個或多個流作爲輸出。核的定義特徵是它操作多個流上所有元素而不是單個元素。對核最典型的用途是對輸入流的每個元素用函數進行求值(“映射(map)”操作)。例如,變換核可以將一個點組成的流(a stream of points)中的每個元素投影到一個不同的座標系中。其他常見的核操作,包括擴展expansions(爲每個輸入元件產生一個以上的輸出元素),縮減reductions(把一個以下元素合併爲單個輸出元素)以及過濾filters(輸出元素的一個子集)。
核的輸出僅可能是該核輸入的函數,並且在覈之內,對流元素的計算從不依賴於在其他元素上的計算。這些制約有兩個主要好處。首先,當寫核(或編譯)時,核執行所需要的數據完全已知。因此,當他們的輸入元素和中間計算數據儲存在局部或是仔細控制的全局引用時,核可以非常高效。其次,在一個核之內對不同的流元素需要獨立計算,這運行把看起來像串行覈計算的內容映射到數據並行的硬件。
在流式編程模型中,通過把多個核串聯在一起來構建應用程序。例如,在流式編程模型中實現圖形流水線需要寫一個頂點程序核、三角形彙編核、剪切核等,然後把一個核的輸出連接到下一個核的輸入。下圖顯示了整個圖形流水線是怎樣映射到流式模型的。這個模型明確了核之間的通信,利用了圖形流水線固有的核之間的數據局部性。

圖 將圖形流水線映射成流式模型(Stream Model)
【圖形流水線的流式化,把所有數據表達成流(由箭頭表明),所有計算表達成核(由框表明)。圖形流水線中的用戶可以編程和不可編程階段都可以表達成核。】

圖形流水線在幾方面都很好地匹配了流式模型。圖形流水線傳統上被構造爲多個計算階段,由階段之間的數據流連接。這個結構近似於流式編程模型的流和核的抽象。圖形流水線中階段之間的數據流是高度局部化的,一個階段產生的數據立刻被下一個階段所消耗;在流式編程模型中,流在覈之間的穿行也顯現出相似的行爲。而且在流水線的各個階段所調用的計算在不同的圖元之間一般是一致的,使這些階段很容易映射成核。

2.2 GPU存儲器模型


2.2.1 存儲器體系結構


下圖演示了CPU和GPU的存儲器體系結構。GPU的存儲器系統結構。GPU的存取器建立了現代計算機存儲器體系結構的一個分支。GPU與CPU類似,有它自己的cache和寄存器來加速計算中的數據訪問。然而,GPU自己的主存儲器也有它自己的存儲器空間——這意味着在程序運行之間,程序員必須明確地把數據複製入GPU存儲器。這個輸入傳統上是許多應用程序的一個瓶頸,但是新的PCI Express總線標準可能使存儲器在CPU和GPU之間共享在不遠的將來變得更爲可行。

圖 CPU和GPU的存儲器體系結構

2.3.2 GPU與CPU元素類比


這一小節將傳統的CPU計算概念和它們對應的GPU概念上做一些非常簡單的類比總結,以方便更好的理解GPU的概念:
  • 流:GPU紋理 = CPU數組 (Streams: GPU Textures = CPU Arrays)
  • 核:GPU片段程序 = CPU“內循環” (Kernels: GPU Fragment Programs = CPU "Inner Loops")
  • 渲染到紋理 = 反饋 (Render-to-Texture = Feedback)
  • 幾何體光柵化 = 計算的調用 ( Geometry Rasterization = Computation Invocation)
  • 紋理座標 = 計算的域 (Texture Coordinates = Computational Domain)
  • 頂點座標 = 計算的範圍 (Vertex Coordinates = Computational Range)

2.2.3 GPU流類型


與CPU存儲器不同,GPU的存儲器有一些用法的限制,而且只能通過抽象的圖形編程接口來訪問。每個這樣的抽象可以想象成不同的流類型,各個流類型有它自己的訪問規則集。GPU程序員可以看到這樣的3種流類型是頂點流、幀緩衝區流和紋理流。第四種流類型是片段流,在GPU裏產生並非完全消耗,下圖演示了一個現代GPU的流水線,3個用戶可以訪問的流,以及在流水線中它們可以被用到的地點。

圖 現代GPU中的流【GPU程序員可以直接訪問頂點、幀緩衝和紋理。片段流由光柵器產生,並被片段處理器消耗。它們爲片段程序的輸入流,但完全是在GPU內部建立和消耗的,所以對程序員來說是不能直接訪問的。】

1.頂點流(Vertex Streams)

頂點流通過圖形API的頂點緩衝區指定。這些流保存了頂點位置和多種逐頂點屬性。這些屬性傳統上用作紋理座標、顏色、法線等,但它們可以用於頂點程序的任意輸入流數據。
在一開始,頂點程序不允許隨機索引它們的輸入頂點。在《GPU Gems 2》出版的時候,頂點流的更新還只能通過把數據從CPU傳到GPU來完成。GPU不允許寫入頂點流。而當時的的API增強已經使GPU可以對頂點流進行寫入。這是通過“複製到頂點緩衝區”或“渲染到頂點緩衝區”來完成的。其中,在前一種技術,“複製到頂點緩衝區”中,渲染結果將從幀緩衝區被複制到頂點緩衝區;而在後一種技術“渲染到頂點緩衝區”中,渲染結果直接寫入頂點緩衝區。而當時增加的GPU可寫頂點流技術,使GPU首次可以把來自流水線末端的結果,直接接入流水線的起始。

2.片段流(Fragment Streams)

片段流由光柵器產生,並被片段處理器消耗。它們是片段程序的輸入流,但是因爲它們完全是在圖形處理器內部建立和消耗,所以它們對程序員來說是不能直接訪問的。片段流的值包括來自頂點處理器的所有插值輸出:位置、顏色、紋理座標等。因爲有了逐頂點的流屬性,傳統上使用紋理座標的逐片段值現在可以使用任何片段程序需要的流值。
需要注意的是,片段程序不能隨機訪問片段流。因爲允許對片段流隨機訪問,會在片段流之間產生依賴,因此打破了編程模型的數據並行保證。而如果某算法有對片段流進行隨機訪問的要求,這個流必須首先被保存到存儲器,並轉換爲一個紋理流(texture stream)。

3.幀緩衝區流(Frame-Buffer Streams)

幀緩衝區的流由片段處理器寫入。其傳統上被用作容納要顯示到屏幕的像素。然而,流式GPU計算幀緩衝區來容納中間計算階段的結果。除此之外,現代的GPU可以同時寫入多個幀緩衝區表面(即多個RGBA緩衝區)。
片段或頂點程序都不能隨機地訪問幀緩衝區的流。然而,CPU通過圖形API可以直接對其進行讀寫。通過允許渲染pass直接寫入任意一種類型的流,當時的API已經開始模糊幀緩衝區、頂點緩衝區和紋理的區別。

4.紋理流(Texture Streams)

紋理是唯一一種可以被片段程序和Vertex Shader 3.0 GPU頂點程序隨機訪問的GPU存儲器。如果程序員需要隨意地索引入一個頂點、片段或幀緩衝區流,其必須首先將它轉換成一個紋理。紋理可以被CPU或GPU讀取和寫入。GPU通過直接渲染到紋理而非幀緩衝區,或把數據從幀緩衝區複製到紋理存儲器來寫入紋理。
紋理被聲明爲1D、2D或3D流,並分別爲1D、2D或3D地址尋址。一個紋理也可以聲明爲一個立方圖(cubemap),可以被看做6個2D紋理的數組。

2.2.4 GPU核的存儲器訪問


頂點和片段程序是現代GPU的兩架馬車。
頂點程序在頂點流(vertex stream)元素上操作,並將輸出送到光柵器(rasterizer)。
片段程序在片段流(fragment streams)上操作,並把輸出寫入幀緩衝區(frame buffers)。
這些程序的能力由它們能執行的運算操作和它們能訪問的存儲器所定義。GPU核中可用的多種運算操作接近於在CPU上可用的操作,然而有很多的存儲器訪問限制。如同先前描述的,大部分這些限制是爲了保證GPU必須的並行性以維持它們的速度優勢。然而,其他的限制是進化中的GPU體系結構造成的,有不少已經在目前得到解決。
另一個訪問模式是:指針流(pointer streams)[Purcell et al.2002]。指針流源於可以使用任意輸入流作爲紋理讀取地址的能力。下圖演示了指針流是簡單的流,其值是內存地址。如果從紋理讀取指針流,則這種能力稱爲依賴紋理(dependent texturing)。

圖 用紋理實現指針流

II、次核心章節提煉


三、使用基於GPU幾何體裁剪圖的地形渲染(Terrain Rendering Using GPU-Based Geometry Clipmaps)


【章節概覽】


本章描述了一種通過頂點紋理實現的,基於GPU的幾何體裁剪圖(Geometry Clipmaps)技術。通過把地形幾何體當做一組圖像來處理,可以在GPU上執行幾乎所有的計算,因此可以減少CPU的負載。且該技術較爲容易實現。

【核心要點】


幾何裁剪圖(Geometry Clipmap)是Losasso 和 Hoppe在2004年提出的,一種新的用於渲染地形層次細節的數據結構。其將地形幾何體緩存在一組嵌套規則柵格中,而柵格隨着視點的移動而遞增。
需要注意,裁剪圖以非常特別而有限的方式使用頂點紋理:紋素基本上以光柵掃描的順序存取,而且與頂點一一對應。
隨着視點的移動,裁剪圖窗口也會進行移動,並用新的數據更新。爲了保證高效的遞增更新,每層的裁剪圖窗口都以環形方式被訪問,即通過2D環繞尋址(2D Wraparound Addressing)。
文中對此技術在GPU上的實現框架細節進行了詳細的交代。

圖 幾何體裁剪圖的原理。給定一個L層的過濾地形棱錐,幾何體剪切圖在每個分辨率層緩存一個方形的窗口,從這些窗口提取了一組以視點爲中心,具有L個嵌套的“環(ring)”,且最精細的層環是實心的。


圖 使用粗粒度幾何體裁剪圖的地形渲染。(n=31,L=10)。每層環由不同的剪切圖層構成。

【關鍵詞】

地形渲染(Terrain Rendering)
裁剪圖(Clipmap)
幾何裁剪圖(Geometry Clipmap)
環繞尋址(Wraparound Addressing)

四、幾何體實例化的內幕(Inside Geometry Instancing)


【章節概覽】


本章討論了在Direct3D中渲染一個幾何體的許多獨特實例(Instance)的技術細節問題,對幾何體實例(Geometry Instancing)的技術內幕進行了分析。

【核心要點】


使用幾何體實例(Geometry Instancing)的優勢在於可以對渲染性能進行優化(最小化花費在提交渲染批次上的CPU時間)。
想要使用應用程序最小化狀態和紋理變化次數,並在一次Direct3D調用中把統一批次中的同一個三角形渲染多次。這樣就能最小化花費在提交批次上的CPU時間。
這章描述了4種不同的技術來實現Geometry Batch:
  • 靜態批次(Static batching)。最快的實例化幾何體的方法。每個實例一旦轉換到世界空間,則應用它的屬性,然後每一幀把已經轉換的數據發送給GPU。雖然簡單,但靜態批次是最不具靈活性的技術。
  • 動態批次(Dynamic batching)。最慢的實例化幾何體的方法。每個實例在每幀都流向GPU存儲器,已經轉換並應用了屬性。動態批次無縫地支持蒙皮並提供了最靈活的實現。
  • 頂點常量實例(Vertex constants instancing)。每個實例的幾何體有多份副本一次複製到GPU存儲器中的混合實現。然後實例屬性在每一幀通過頂點常量設置,而由於頂點着色器完成幾何體的實例化。
  • 通過幾何體實例化API的批次(Batching with Geometry Instancing API)。使用DirectX等圖形API提供並支持的幾何體實例化,此實現提供了靈活快速的幾何體實例化解決方案。與其他方法不同的是,這不需要在Direct3D頂點流中複製幾何體包。

高效地渲染相同的幾何體(靜態批次、動態批次、頂點常量實例化,通過幾何體實例化API的批次),他們各有優劣,根據應用和渲染的物體類型分別選取。一些建議:
有相同幾何體的許多靜態實例的室內場景,很少或從不移動的實例(比如牆壁或傢俱),採用靜態批次較爲理想。有許多動畫物體實例的一個室外景物,如策略遊戲中有上百個士兵的大戰場,在這種情況下,動態批次或許是最好的解決方案。有許多植被和樹以及許多粒子系統的室外場景,其中有很多經常需要修改的屬性(例如,樹和草隨風搖擺),幾何體實例API可能是最好的解決方案。

圖 在真實場景中將靜態批次和幾何體實例化結合起來。

【關鍵詞】


幾何體實例(Geometry Instancing)
靜態批次(Static batching)
動態批次(Dynamic batching)
頂點常量實例(Vertex constants instancing)
通過幾何體實例化API的批次(Batching with Geometry Instancing API)

五、分段緩衝(Segment Buffering)


【章節概覽】


本章介紹了一項可以明顯減少一個顯示幀中渲染的批次數目的技術——分段緩衝(segmentbuffering),以及其改進。

【核心要點】


分段緩衝(segment buffering)技術彙集了在場景中彼此靠近的多個實例,把它們合併到“超級實例(über-instances)”中,這樣減少了批次的數目,而且提供瞭解決批次瓶頸問題的一個簡單優化的方案。
分段緩衝(segment buffering)技術自動合併相似的實例,同時保持呈現單獨實例的大部分優勢。分段緩衝的主要好處在於非重複的外觀,以及無需重新繪製原始的實例,就像這部分實例從可見集合中被刪除了一樣,所以可以明顯減少一個顯示幀中渲染的批次的數目。而其具體步驟分爲三步,原書中有進一步地說明。
而關於分段緩衝(Segment Buffering)的改進,文章提出了結合自動紋理圖集生成(automatic texture-atlas generation [NVIDIA 2004])的相關思路。

圖 包含同一個物體的多個實例的場景

【關鍵詞】

實例化(instance)
批次(batch)
分段緩衝(segment buffering)
超級實例(über-instances)
自動紋理圖集生成(automatic texture-atlas generation)

六、用多流來優化資源管理(Optimizing Resource Management with Multistreaming)


【章節概覽】


現代實時圖形應用程序最困難的問題之一是必須處理龐大的數據。複雜的場景結合多通道的渲染,渲染起來往往會較爲昂貴。
首先,多流(Multistreaming)技術由微軟在DirectX 8.0中引入。而這章介紹了一種用多流來優化資源管理的解決方案,可以用來處理龐大的數據,且在每個通道中只傳輸當前需要的頂點分量。

【核心要點】


這章介紹了當前的應用程序如何克服由於場景中幾何體數據的增加所引起的問題。文中的討論基於一個使應用程序對數據有更多控制的靈活模型—多流(Multistreaming),
這個方案聯合了兩項強大的技術,已經在名爲Gothic III的引擎中實現:一些頂點緩衝區通過多流聯合,而且所有頂點緩衝區都由一個優化的資源管理器控制。
此方法的好處是:帶寬有時可能受限於系統內存和GPU之間的總線,因爲傳輸了重複或多餘的數據,而現在此方法爲數據有效地控制了帶寬。

圖 頂點流的四種類型
G – 用於幾何體數據的頂點流。包含頂點位置、法線和(多個)頂點顏色。
T – 用於紋理映射數據頂點流。包含紋理座標系和附加數據,如正切空間法線映射的正切向量。
A – 用於動畫數據的頂點流。包含動畫數據,如骨骼權重和相關因素。
I – 用於實例數據的頂點流。 包含頂點流頻率實例數據。
而這四種流的子集結合起來可以處理不同的任務,如下圖。

圖 組合當前需要的流

  • 渲染沒有動畫的網格
可能的流組合: G或者G+T
  • 渲染有動畫的網格
可能的流組合: G+A或者G+T+A
  • 渲染實例的網格(可選包含動畫)
可能的流組合:G+I或G+T+I(可選:G+A+I或G+T+A+I)
  • 渲染純的Z通道(可選有或者沒有實例,可選有或沒有動畫)
可能的流組合 G(可選 :G+A 或 G+I 或 G+A+I)

原文中對上述的思路用DirectX 9.0c進行了實現。

【關鍵詞】

資源管理(Resource Management)
多流(Multistreaming)
頂點流(Vertex stream)

七、讓硬件遮擋查詢發揮作用(Hardware Occlusion Queries Made Useful)

【章節概覽】

這章探究瞭如何最好地應用硬件遮擋查詢(Hardware Occlusion Queries)的思路,介紹了一個簡單但強大的算法,其最小化了調用查詢的次數,而且減少了由查詢結果延遲造成的停滯影響。

【核心要點】

遮擋查詢作爲一個GPU特性,反饋的延遲很高,可以確定一個物體在被渲染之後是否看得見,不像早期的遮擋查詢裁剪技術,Michael等人的算法是像素完美的,即此算法沒有引入渲染走樣,併產生一組最合適的可見物體來渲染,沒有把不必要的負載放到GPU上,而且CPU的開銷最小。
文中介紹的算法可以解決這些問題。 該算法用前一幀的遮擋查詢結果來初始化和調度當前幀的查詢,利用了可見性的空間和時間相關性。這通過把場景存儲在一個層的數據結構來完成(比如k-d樹或八叉樹),以從前到後的順序處理層的節點,渲染某些先前可見的節點來交叉地遮擋查詢。
也就是說,該算法幾乎可以節省任何在CPU和GPU上等待遮擋查詢結果的時間。這是利用時間一致性(temporal coherence)來實現的,假設正在先前幀可見的物體在當前幀仍保持可見。算法使用層結構來在單次測試中裁剪掉大塊被遮擋的區域,減少了遮擋查詢的數量,同事也避免了大部分其他內節點的遮擋測試。

圖 兩個連續幀中層次結構節點的可見性

【關鍵詞】

硬件遮擋查詢(Hardware Occlusion Queries)
時間一致性(temporal coherence)
一致性層裁剪(Coherent Hierarchical Culling)



八、帶位移映射的細分表面自適應鑲嵌(Adaptive Tessellation of Subdivision Surfaces with Displacement Mapping)


【章節概覽】


這章介紹瞭如何使用可選的位移貼圖(Displacement Mapping)執行Catmull-Clark細分曲面(Catmull-Clark Subdivision Surfaces)的視圖相關的自適應鑲嵌(Adaptive Tessellation)。使用GPU進行鑲嵌計算,這可以節省圖形總線帶寬,並且比使用CPU快許多倍。

【核心要點】


文中通過重複細分(repeated subdivision)的方法來實現鑲嵌,通過渲染到2D紋理來實現。細分,平坦度測試(Flatness Test)和最終頂點屬性計算使用片元着色器(也稱像素着色器)完成。該方法假設細分曲面控制網格的頂點數據存儲在紋理貼圖中。中間結果也渲染到紋理貼圖並從紋理貼圖讀取,並且最終的鑲嵌結果(位置,法線等)被渲染到一個頂點數組中,以被渲染圖元(render-primitives)如glDrawElements()函數使用。

圖 對立方體的Catmull-Clark細分


圖 自適應鑲嵌(Adaptive Tessellation) vs. 均勻鑲嵌(Uniform Tessellation)
總之,這章介紹了一個結合使用廣度優先遞歸(breadth-first recursion algorithm)細分算法在GPU上鑲嵌細分表面的方法。文中描述了執行平坦度測試、實現細分和計算極限表面屬性所需的着色器。而且解釋瞭如何修改着色器來添加位移映射的支持,以增加細分表面模型的幾何細節。

【關鍵詞】


Catmull-Clark細分 (Catmull-Clark subdivision)
位移貼圖(Displacement Mapping)
平坦度測試(Flatness Test)
GPU鑲嵌(GPU Tessellation )
自適應鑲嵌(Adaptive Tessellation)

九、使用距離函數的逐像素位移貼圖(Per-Pixel Displacement Mapping with Distance Functions)


【章節概覽】


距離貼圖(distance map)是一種在像素着色器中給對象添加小範圍位移映射的技術。這章中詳細介紹了使用距離函數的逐像素位移貼圖(Per-Pixel Displacement Mapping with Distance Functions)技術。

【核心要點】


這章中提出了距離貼圖(Distance Mapping)/距離函數(Distance Functions)的概念,是一種基於隱式曲面光線追蹤的位移映射快速迭代技術(a fast iterative technique for displacement mapping based on ray tracing of implicit surfaces)。實際表明,距離函數中包含的信息,允許我們在光線遠離表面時前進更大的距離,並保證不會跨得太遠以至於在渲染的幾何體上產生縫隙。實現的結果非常高效:會在很少的迭代次數內收斂。
文中將位移貼圖(Displacement Mapping)作爲光線追蹤問題來處理,首先從基礎表面上的紋理座標開始,然後計算觀察光線與移動表面相交處的紋理座標。爲此,文中預先計算了一個三維距離貼圖,該貼圖給出了空間點和位移表面之間距離的度量。距離貼圖爲我們提供了與光線快速相交所需的所有信息。
最終,算法在保持實時性能的同時顯着增加了場景的感知幾何複雜度。


圖 使用文中所討論的位移貼圖方法渲染出的濾柵

【關鍵詞】


距離貼圖(Distance Mapping)
距離函數(Distance Functions)
位移貼圖(Displacement Mapping)

十、S.T.A.L.K.E.R.中的延遲着色(Deferred Shading in S.T.A.L.K.E.R.)


【章節概覽】


本章是對《S.T.A.L.K.E.R.》中所用渲染器的幾乎兩年的研究和開發的事後剖析。該渲染器完全基於延遲着色(Derred Shading)和100%動態光照,目標是高端GPU,因爲沒有任何一個解決方案可以適合所有需求,所以這章並不是延遲着色的全面指南,但是可以作爲一個很好的參考。

【核心要點】


延遲着色(Deferred Shading),雖然並不適合每個遊戲,但是確是《S.T.A.L.K.E.R》中的優秀渲染架構。它提供了一個渲染引擎,權衡了現代GPU,比傳統的前向着色架構有更低的幾何體處理需求,更低的像素處理需求及更低的CPU開銷。場景管理器也更乾淨更簡單。一旦避開了延遲着色固有的不足,如多材質系統的潛在限制和缺乏反失真功能,產生的架構既靈活又快速,允許區域很廣的效果。

圖 基於延遲着色實現的渲染效果 @2005年


圖 基於延遲着色實現的渲染效果 @2005年


圖 基於延遲着色實現的渲染效果 @2005年

【關鍵詞】


延遲着色(Deferred Shading)
幾何緩衝區(G-buffer)
反走樣(Antialiasing)

十一、動態輻照度環境映射實時計算(Real-Time Computation of Dynamic Irradiance Environment Maps)


【章節概覽】


環境映射(Environment Maps)是常用的基於圖像的渲染技術,用來表現以空間上不變的球面函數。本章描述了一種完全GPU加速的方法,來生成一個環境映射在圖形上特別有趣的類型——輻照度環境映射(Irradiance Environment maps)。

【核心要點】

本技術使應用程序可以在動態環境下(如來自動態關和動態對象的輻射度)快速地模擬複雜的全局光照效果。
輻照度環境映射的渲染非常高效,漫反射只用一次,漫反射+鏡面反射只用兩次。

圖 一個由單個方向光(左)和實時輻照度環境映射(右)照亮的物體


圖 輻照度環境映射(a)一個聖彼得教堂的立方體映射;(b)漫反射結果;(c)鏡面映射結果。
而通過片元着色和浮點紋理,可以把球面調和卷積映射到GPU上變成簡單的兩個通道的操作:第一個pass中把光照換行轉換成它的球面調和表示,另一個pass把它和反射函數進行卷積並把它轉換爲空域。且讓環境映射的每個面有一個獨立的查找表(Lookup Table)。


圖 10-3 將輸出係數映射到一個面的分塊輸入查找表上

【關鍵詞】


環境映射(Environment Maps)
動態輻照度環境映射(Dynamic Irradiance Environment Maps)
球面調和卷積(Spherical Harmonic Convolution )

十二、近似的雙向紋理函數(Approximate Bidirectional Texture Functions)


【章節概覽】


本章介紹的內容關於如何較容易地採集和渲染的真實材質,如布料、羊毛和皮革等的技術。這些材質難以用早先的技術渲染,它們基本來與兼得的紋理映射。本章的目標是在採集上花費少量的努力,在渲染上花費少量的技術,但是仍然達到真實的外觀。

【核心要點】


本章介紹了一種可以只用少量圖像就進行採集和渲染空間變化的複雜材質的方法。這種經驗的方法並不是採集真實的BRDF,而是僅僅展示了細微表面的結構如何引起照明的改變:且BRDF在隨後使用。而使用這項技術的實時渲染可以容易地實現。
本文的方法以Kautz等在2004年的工作爲基礎。根據觀測,在某種情況下,表面的材質可以通過少許圖像採集,產生的結果類似於完整的雙向紋理函數(Bidirectional Texture Functions, BTF)所達到的。用這個近似的BTF渲染總共只需1對一個簡單的着色模型求值,並執行一個對體紋理的查詢即可。渲染在圖形硬件上很容易達到實時的幀速率,並在多種材質上都達到了引人注目的結果。


圖 採集的方法概覽。上圖:裁剪光的方向不同,視點固定正交的圖像,產生一些着色圖。下圖:對於每張圖像,計算平均反射出的輻出度(即平均亮度)。在渲染時,通過一些用戶定義的照明模型計算(如Phong)計算r值,並使用該值根據平均亮度,逐片段地查找進入圖像棧。最後,用光源的亮度縮放這個值。



圖 羊毛毛衣(a)基於完整的BTF完成(b)基於本文方法。
(a)圖是用完整的BTF完成的(6500個圖像,用主元分析(Principle ComponentsAnalysis, PCA)壓縮成16個成分)。右圖是用本章的技術做的。看得出來主要的差別在一些入射角上。

【關鍵詞】


服飾的渲染(Clothing Rendering)
雙向紋理函數(Bidirectional Texture Functions,BTF)

十三、基於貼面的紋理映射(Tile-Based Texture Mapping)


【章節概覽】


這章介紹了一個基於貼面的紋理映射(Tile-Based Texture Mapping)系統,用來從一組貼面生成一個大的虛擬紋理。

【核心要點】


使用紋理貼面(Texture Tiling)可以解決紋理過大來帶的磁盤空間、系統存儲。圖像存儲瓶頸等各種問題。
如下圖,如果有重複的貼面組成的大牆壁或地板,顯然不需要存儲所有的貼面。相反,可以只存儲一個貼面,然後在牆上重複它。對於更復雜的模式,可以把牆壁或地板切成較小的多邊形,並對每個多邊形應用不同的紋理貼片或紋理座標變換。這種方法的有點是在理論上可以達到無限的壓縮率,因爲可以從少量貼面產生出一個任意打的輸出。缺點是,應用程序代碼和數據比較複雜。


圖 基於貼面的紋理。左圖:給定以小組輸入紋理貼圖(左),系統在不需要存儲整個紋理的情況下可以提供大的虛擬紋理圖(右),這種方法支持本地硬件紋理過濾,而且不需要修改應用程序的幾何體或紋理座標。


圖 基於貼圖的紋理映射的概覽。左圖:打包的輸入貼面。右:輸入的虛擬紋理。給定一個紋理請求(s,t),先確定請求的是哪個貼面,然後算法從輸入貼面中獲取相應的紋素。

【關鍵詞】


紋理映射(Texture Mapping)
基於貼面的紋理映射(Tile-Based Texture Mapping)
紋理貼面(Texture Tiling)

十四、動態環境光遮蔽與間接光照(Dynamic Ambient Occlusion and Indirect Lighting)


【章節概覽】


這章在講大家很熟知的環境光遮蔽(Ambient Occlusion , AO)。
文中的描述是,介紹了一種用於計算散射光傳遞的新技術,並演示如何用它來計算運動場景中的全局光照。主要是一種用GPU加速環境光遮蔽計算的技術,並將此算法變成了實時的解決方案。

【核心要點】


這章介紹的這項技術效率很高,可以實現在渲染每幀時即時計算環境光遮蔽和間接光照數據。其並沒有預計算輻射傳遞(Precomputed Radiance Transfer ,PRT)或預計算環境光遮蔽技術存在的限制。

圖 通過環境光遮蔽和間接光照增加真實感
圖注:左邊的場景只用環境光,看起來很平面化。中間的場景用環境光遮蔽加模糊陰影,右邊的場景增加的間接光照,感覺格外真實。
這章的技術通過把多邊形網格看做一些可以發出、傳播或反射光的元素,並且可以互相產生陰影的表面元素集合來工作。此方法效率很高,因爲它不需要計算一個元素到另一個元素的可見性,而是用一種更簡單而且更快的技術——基於近似投影的方法——來處理遮擋的幾何體。

【關鍵詞】


環境光遮蔽(Ambient Occlusion, AO)
間接光照(Indirect Lighting)

十五、精確的大氣散射(Accurate Atmospheric Scattering)


【章節概覽】


生成真實大氣散射的效果一直是計算機圖形學領域的難題。描述大氣的散射方程式非常複雜,以至於可以用整本書去解決這個課題。計算機圖形模型通常使用簡化的方程,這些模型中只有少數可以以交互速率運行。
這章介紹如何實現一個完全運行在GPU上的大氣散射實時算法(原始算法由Nishita等人在1993年提出),並提供了實現此算法的全部CG和GLSL源代碼。

【核心要點】


這章解釋瞭如何在GPU着色器中實現Nishita等人在1993年提出的散射方程,並以可交互的速率運行。這些方程能更加精確地對大氣建模,保證當高度降低的同時密度也呈指數級降低。且可以在不需要犧牲圖像質量同時省略查找表,着色器代碼足夠小而快,可以在一個GPU着色器中實現整個算法。
一個重要的細節是怎樣模擬大氣中一個點的散射(Scattering)。最常見的兩種大氣散射形式是瑞利散射(Rayleigh Scattering)和米氏散射(Mie Scattering)。
瑞利散射(Rayleigh Scattering)是由空氣中的小分子引起的,而且它對波長端的光散射更強(最先是藍色,然後是綠色和紅色)。
米氏散射(Mie Scattering)由空氣中更大一些的粒子引起,這些粒子被稱爲浮塵(aerosols),如灰塵(dust)或污染物(pollution)。
章節構成方面,這章一開始用一定的篇幅進行了散射方程的求解和簡化,最終得到的實現在原本的大氣散射模型上進行了不少簡化,以至於最終的實現可以在對硬件要求不高的前提下,達到交互的速率進行渲染。並且採用了高範圍動態(HDR)渲染,得到了更好的大氣散射效果。

圖 散射Demo的截圖

【關鍵詞】


大氣散射(Atmospheric Scattering)
瑞利散射(Rayleigh Scattering)
米氏散射(Mie Scattering)
高範圍動態渲染(High-Dynamic-Range Rendering)

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


這裏提供了一些,《GPU Gems 2》書本的配套資源,以及源代碼的下載地點。
PS:配套的不少工程中不僅包含完整的源碼,也直接包含經過編譯後的exe執行文件,可以直接運行後查看效果。
  • 也有維護一個名爲 “GPU-Gems-Book-Source-Code”的GitHub倉庫,以備份《GPU Gems》系列書籍相關的珍貴資源,《GPU Gems 2》的隨書CD和源代碼可以在這裏下載到:

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

  • 本文的GitHub版本:

https://github.com/QianMo/Game-Programmer-Study-Notes


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