Deferred Decal(延遲貼花)

來源:互聯網
上載者:User

Decal渲染是一個引擎中重要的一部分,記憶中印象最深刻的就是以前CS中的彈痕與爆炸痕迹了。目前來說,Decal的實現方法也比較多,而且感覺還跟遊戲類型有關,比如子彈亂飛的射擊類FPS遊戲中對貼花系統的要求就比較高,因為本來Decal的變化就比較豐富。一般來說貼花渲染主要有兩種實現方法:

  • Texture projection關於投影紋理的原理網上也有很多文章,基本就是需要對地形渲染兩遍,一遍正常渲染,一遍用投影的紋理渲染,然後把這兩個混合的結果融合。顯然,如果情境中的貼花較多,且情境規模複雜的話,這種方法就會比較費。
  • Mesh projection 這種方法應該來說使用比較多,包括早期Source中的Decal等使用的應該就是這種方法,其主要原理就是將Decal處理為附著於其所能貼到的幾何表面上的幾何網格,然後當做polygon list來渲染。當然這些網格也是經過修飾的(比如貼到一個桌子的邊角上時,就需要根據桌角幾何網格的分布來裁剪Decal所對應的網格)。關於該方法這裡有一篇文章介紹得非常好:http://blog.wolfire.com/2009/06/how-to-project-decals/。另外,基於此種方法的改進類型也不少,比如Frosbite引擎中就利用Geometry
    Shader來產生類似該類型的Decal(Shadows
    and Decals in the Frostbite Engine)。

結合最近普遍應用的後處理渲染流程,於是自然而然地也就出現了Deferred Decal,這裡一個最基本的條件就是需要有一個基於延遲渲染的系統才能使用這種方法。關於Deferred decal的實現原理也比較簡單,過程如下:

  1. 在後處理渲染中完成正常的G-Buffer渲染後,即可得到對應的Normal-depth buffer,以及Diffuse Buffer,但是此時仍沒有進行光照計算,這時就需要將Decal給渲染到對應的Diffuse buffer中。為了實現Decal,這裡需要在G-Buffer後再增加一個Pass,並使用Diffse buffer作為Render
    target,並使用Decal shader進行渲染,計算並更新Decal所能夠影響到的那些Pixel的Diffuse。
  2. 為了確定每個Decal所能夠影響到的範圍以便更新相應的Diffuse buffer,一般需要繪製出Decal所對應的一個包圍幾何體,這裡可以是Sphere或Box(例如Volume decal中使用的就是Sphere,CryEnigne中使用的就是Box),當然,如果不計代價還可以使用更複雜的形體。
  3. 最後,關鍵的一步就是計算需要Decal的那些Pixel所對應的Decal uv,這雷根據包圍體的不同方法也不同。Sphere的映射方法比較簡單,可以直接將Pixel的全局座標轉到局部球體座標即可,再根據對應的Volume texture或2D texture再做一次映射,然後訪問紋理即可。如果使用Box的話可能就稍麻煩些,這時需要知道Decal box所對應的一個局部座標系轉化。這個Decal座標系由以下幾個量來確定:Decal所貼的位置,Decal貼到處的Normal,Decal的水平方向,Decal的大小變換;然後由這三個基本量來構靠世界到Decal局部的變換矩陣:
    float3 gDecalScale;float3 gDecalPosition;float3 gDecalNormal;float3 gDecalLRVector;float3 zAxis = normalize(gDecalNormal);float3 xAxis = normalize(gDecalLRVector);float3 yAxis = normalize(cross(xAxis , zAxis));float4x4 decalMatrix = {{xAxis.x , yAxis.x , zAxis.x , 0.0f} ,{xAxis.y , yAxis.y , zAxis.y , 0.0f} ,{xAxis.z , yAxis.z , zAxis.z , 0.0f} ,{-dot(xAxis , gDecalPosition) , -dot(yAxis , gDecalPosition) , -dot(zAxis , gDecalPosition) , 1.0f}};

    這裡的變換矩陣其實也相當於在Decal的位置上放置一個Camera,即從Decal的角度來觀察整個情境~_~

  4. 得到變換矩陣之後即可對Pixel變換,然後在局部座標中計算出對應的Decal UV就可以做相應的Decal紋理讀取了。

比如將下面這個很有追求的Decal貼到Sponza情境中的效果如下

 

Enhanced effect with Bump:

此外,為了增強Decal的渲染效果可以使用帶有Bump的Decal,不過這裡要加入到整個渲染流程中的話可能會稍稍有些麻煩。為了使用Decal的Normal並在此上進行光照著色,就需要把Decal的Bump給附加到G-Buffer中的Normal上,這一步雖然與Decal texture的附加類似,但通常情況下Normal與Depth會在一個Buffer裡邊儲存,而在進行Diffuse的decal pass時由於需要反求像素的世界位置,因而就要使用ND
buffer,這樣就不能在該pass裡完成decal bump normal的合并。不過可以再建立一個跟Diffuse類似的中間Buffer,其只用來儲存渲染Decal時產生的Normal值;然後在當前的Decal pass結束以後,再使用另外一個Pass,使用Normal Depth作為目標RT來合并原始Normal與Decal的Normal。

但是,這其中又涉及到另外一個變換:Decal normal由局部座標到全局座標的變換,這其實是相當於對應於decal space的一次tangent變換,需要對於上述的decalMatrix求逆轉矩陣來做變換,而這一步的代價還是比較費的,因而此功能就需要謹慎使用。

Some Tips:
  • 處理不同類型物體時的操作。在使用Defferd Decal的方法時,這個問題其實最為常見,也最需要解決。其實這裡的不同類型較為廣泛,比如說下述幾何上不屬於同一類物體(見),本來是想只將Decal貼在旗子上,但是其卻也出現在了後面的牆上;另外,還在就是比如地面上的decal,但如是主角走過該處時,decal可能就同樣會出現在角色身上。這個問題一般有兩種解決方案:Stencil testing,Object index。前一種方法使用模板測試來標識不同的物體,相對來說其實現較為方便些,而第於二種方法可能需要改變G-Buffer的內容,在使用上可能還不如第一種方法,雖然其通用性更強。                              
  •  
  • 關於Corner Wrap問題,這種情況的表現就像所示。該情況的產生是由於通常情況下只考慮Decal水平方向上的座標投影變換來計算UV,而並沒有考慮Decal normal方向上的影響。知道原因後這個問題比較容易解決,可以利用法向量的變化來計算Decal垂直方向上的UV分布就可以了。                    
  • Decal texture採樣定址方式需要設定成CLAMP,否則就會出邊重複的情況,視覺上的不正確。另外,也要注意Alpha的混合狀態設定。
  • 關於Camera進行Decal Box或Sphere內部的問題。由Defferred decal的實現原理可知,畫出包圍Decal的Box或Sphere其實是用來標記其所影響的Pixel以便更改diffuse,但這樣就會有一個問題,那就是當Camera進入Box或Sphere內部後可能就會導致在視點處直接看到原始mesh,而不是box的mesh,這樣肯定就不會進行Decal所對應的shader了,於是也就沒法畫上decal。這個問題也好解決,既然想增加對原始Mesh的遮擋,那麼就可以將原始的Box或Sphere細分,即在其內部增加繪製的triangle以增加遮擋的機會,這樣即使Camera進入其內部,仍然可以有內部的子組件來遮擋原始Mesh。不過簡單起見可以只在Box內部再多畫幾個對角線上的triangle就可以應付大多數情況了。
  • 對於Decal數量較多的情況,加入Decal Box或Sphere的執行個體化渲染以及對應Camera的可見度檢測也是很有必要的。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.