介紹

本文介紹了渲染樹的幾個手段,分別是

輪廓裁剪(Silhouette Clipping)增加了樹枝和樹幹外形的細節

陰影貼圖提供了逐樹葉級的真實感自我遮擋

使用雙葉面光照模型和HDR來最佳化光照

半透明覆蓋(alpha to coverage)來抗鋸齒

輪廓裁剪

對於下圖黃框中的內部細節,使用浮雕對映(relief mapping)來處理。對於藍框中的輪廓細節,使用了一種稱為輪廓裁剪的技術,在垂直於視線向量的方向上擠壓物體的輪廓。類似於浮雕對映,這些輪廓對高度圖進行光線追蹤,以決定哪個畫素實際上被輪廓所遮擋。

[GPU Gems3] 4. 次世代SpeedTree渲染

輪廓擠出

根據逐頂點的法向量和視線向量的點積,插值找到三角形邊上點積為0的點。在找到的點利用幾何著色器構造兩個三角形進行擠出。

[GPU Gems3] 4. 次世代SpeedTree渲染

[GPU Gems3] 4. 次世代SpeedTree渲染

[GPU Gems3] 4. 次世代SpeedTree渲染

高度追蹤

擠出後的頂點的基切線和紋理座標不需要變化。為每個頂點計算視線向量。如下圖所示,在畫素Shader中,從點A開始逐步沿著視線向量的反方向移動來改變它的紋理座標,最終到達B點。然後執行浮雕對映中的高度追蹤查詢。當發現交點時,就計算該片元的漫反射光照和陰影,否則該片元進行抗鋸齒或者丟棄。演算法的改進手段有把線性和二分查詢結合(Policarpo2004)或預計算來加速跟蹤(Dummer2006)

[GPU Gems3] 4. 次世代SpeedTree渲染

[GPU Gems3] 4. 次世代SpeedTree渲染

[GPU Gems3] 4. 次世代SpeedTree渲染

輪廓LOD:隨樹離相機距離變遠時,輪廓的寬度逐漸減為0,對遠處的樹不進行輪廓處理。

陰影

SpeedTree中的陰影是離線預計算的,因此存在沒有自遮擋和陰影不真實的問題,有以下解決手段:

[GPU Gems3] 4. 次世代SpeedTree渲染

樹葉自遮擋

此處討論的樹葉情況是樹葉廣告牌,總是朝向相機,使用的方法是陰影對映。當渲染樹葉時,樹葉朝向相機。當渲染陰影貼圖時,它們轉而朝向光源。繞中心點旋轉會出現下圖(a)中只有一半樹葉片接受陰影的情況,為了避免這種情況使用(b)中旋轉後向光源移動的方法。

[GPU Gems3] 4. 次世代SpeedTree渲染

但直接對樹葉平面片投射陰影會使得陰影像延長的條紋。解決方法是在視線方向使用偏移係數來改變陰影的位置,偏移係數儲存在紋理中。使用新的樹葉位置,把被遮擋的畫素投射到光照空間並對陰影進行取樣。

[GPU Gems3] 4. 次世代SpeedTree渲染

Leaf Texture and Accompanying Depth-Offset Texture

[GPU Gems3] 4. 次世代SpeedTree渲染

The Impact of Leaf Offsets with Self-Shadowing

級聯陰影貼圖:將視錐體分割為幾個區域並分別為每個區域將陰影貼圖渲染到不同的紋理。為了減少CPU負擔,不同的級聯使用不同頻率的更新。

樹葉光照

雙邊光照

當樹葉從後面被照亮時,樹葉的主要亮度來自於透射的光,色彩會輕微變黃或變紅。

[GPU Gems3] 4. 次世代SpeedTree渲染

使用的策略是在畫素著色器生成偏黃的樹葉顏色(Diffuse。g * 0。9, Diffuse。g * 1。0, Diffuse。g * 0。2),並根據視線方向和光線方向的夾角μ,在原來顏色和計算的黃色之間插值,μ越接近於π,樹葉顏色越黃,鏡面高光也越小。

[GPU Gems3] 4. 次世代SpeedTree渲染

鏡面高光

首先使用普通的鏡面反射,但遠處的樹會閃閃發光,因此根據距離來減少鏡面反射。其次,為了實現葉片如下圖的反射效果,使用一個粗糙的V型法向量貼圖把樹葉分成兩半。最後,為了避免鏡面反射細節太多造成閃爍,使用粗糙的mipmap層次的貼圖使得反射光更加平滑柔和。

[GPU Gems3] 4. 次世代SpeedTree渲染

半透明覆蓋

半透明覆蓋把畫素著色器輸出的alpha值轉化為應用於MSAA渲染目標的子畫素解析度上的覆蓋掩碼。當MSAA分解被使用時,結果會是一個透明的畫素。使用半透明覆蓋時,可以極大減少方塊狀區域和硬邊緣,尤其是動態時可以減少它們造成的閃爍。

[GPU Gems3] 4. 次世代SpeedTree渲染

The Impact of Alpha to Coverage

為了在LOD之間視線交叉衰減,使用不同alpha測試值的兩個LOD被同時繪製。半透明覆蓋來執行交叉衰減,雖然可能會有透明度的問題,但很難被注意。

[GPU Gems3] 4. 次世代SpeedTree渲染

半透明衰減也可以對生成的輪廓邊進行反鋸齒。為了實現該目的,在輪廓邊上生成一個窄的邊界區域,它使輪廓的不透明度從完全不透明變為透明。在高度追蹤期間,記下對高度圖的最小損失並根據這個值來改變畫素的不透明度。如果視線向量和高度圖相交則alpha為1,如果不相交且最小損失小於螢幕空間的1。5個畫素,則逐漸衰減到0,否則直接為0。

[GPU Gems3] 4. 次世代SpeedTree渲染

[GPU Gems3] 4. 次世代SpeedTree渲染