Deferred Decal 延遲貼花

2021-06-09 01:08:12 字數 2649 閱讀 7947

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

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

在後處理渲染中完成正常的g-buffer渲染後,即可得到對應的normal-depth buffer,以及diffuse buffer,但是此時仍沒有進行光照計算,這時就需要將decal給渲染到對應的diffuse buffer中。為了實現decal,

這裡需要在g-buffer後再增加乙個pass,並使用diffse buffer作為render target,並使用decal shader進行渲染,計算並更新decal所能夠影響到的那些pixel的diffuse。

為了確定每個decal所能夠影響到的範圍以便更新相應的diffuse buffer,一般需要繪製出decal所對應的乙個包圍幾何體,這裡可以是sphere或box(例如volume decal中使用的就是sphere,cryenigne中使用的就是box),當然,如果不計代價還可以使用更複雜的形體。

最後,關鍵的一步就是計算需要decal的那些pixel所對應的decal uv,這裡根據包圍體的不同方法也不同。sphere的對映方法比較簡單,可以直接將pixel的世界座標轉到區域性球體座標即可,再根據對應的volume texture或2d texture再做一次對映,然後訪問紋理即可。如果使用box的話可能就稍麻煩些,這時需要知道decal box所對應的乙個區域性座標系轉化。這個decal座標系由以下幾個量來確定:decal所貼的位置,decal貼到處的normal,decal的水平方向,decal的大小變換;然後由這三個基本量來構靠世界到decal區域性的變換矩陣:

[cpp]view plain

copy

print?

float3 gdecalscale;  

float3 gdecalposition;  

float3 gdecalnormal;  

float3 gdecallrvector;  

float3 zaxis = normalize(gdecalnormal);  

float3 xaxis = normalize(gdecallrvector);  

float3 yaxis = normalize(cross(xaxis , zaxis));  

float4x4 decalmatrix =   

,  ,  

,  };  

float3 gdecalscale;

float3 gdecalposition;

float3 gdecalnormal;

float3 gdecallrvector;

float3 zaxis = normalize(gdecalnormal);

float3 xaxis = normalize(gdecallrvector);

float3 yaxis = normalize(cross(xaxis , zaxis));

float4x4 decalmatrix =

, ,

, };

這裡的變換矩陣其實也相當於在decal的位置上放置乙個camera,即從decal的角度來觀察整個場景~_~

得到變換矩陣之後即可對pixel變換,然後在區域性座標中計算出對應的decal uv就可以做相應的decal紋理讀取了。

比如將下面這個很有追求的decal貼到sponza場景中的效果如下

此外,為了增強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:

常規延遲和內嵌延遲

常規延遲和內嵌延遲 sun 403 延遲時序控制 在 中使用關鍵字 和延遲的時間,就可以通過延遲來進行時序控制。延遲的時間可以是數字 變數或者表示式。延遲時序控制又分為兩種 常規延遲和內嵌延遲。常規延遲在賦值語句的左邊,系統執行到這一行 時,系統先進行延遲,延遲完成後,再計算表示式,並將結果賦值給左...

python的延遲函式 python 延遲繫結

def multipliers n funcs for i in range n def f x return x i return funcs g0,g1,g2,g3 mutipliters 4 print g0 10 30 print g1 10 30 print g1 10 30 print ...

HTTPS延遲也可以延遲頁面載入時間

自從上了2015年拉斯維加斯黑帽大會的熱點話題,全球資訊保安企業和網際網路巨頭都在不遺餘力地推廣 安全訪問協議https,例如google提高https 的搜尋權重,以及在瀏覽器中對非https 標註安全警示資訊,免費的https證書服務也迅速流行,這些措施大大加速了https在全球的普及,但是ht...