Non-interleaved Deferred Shading of Interleaved Sample Patterns 論文解析

交錯採樣

    本文是一篇光照計算加速的文章,是一篇非常經典而且非常常用的一篇文章。本文想解決的問題就是在計算VPL光照影響的時候,隨着VPL數量增加會導致計算時間明顯的增加。本文是在延遲着色的基礎上進行優化的。 

    本文的核心思想是將Gbuffer中的紋理進行分塊重組,然後產生很多低分辨率的小場景(由於Gbuffer中包含了整個場景的位置,法線,顏色和深度,因此可以通過Gbuffer中的內容重建整個場景),這些小場景如(b)所示,每個低分辨率場景之間非常像,因此就把我們需要計算的VPL平均的分給每個小場景,然後每個小場景獨自進行一部分光照計算,計算完成之後再將這些小場景合成一個大場景即可。

   實現步驟:(a) 計算Gbuffer->(b) 分塊(分成多個低分辨率小場景)->(c) 單獨計算光照->(d) 組合(將計算完之後的小場景合併爲一個大場景)->(e) 邊緣檢測(爲了後面高斯模糊使用)->(f) 高斯模糊(後面會講原因)->(g) 融合(講紋理和光照結果進行相乘,如果在計算光照就把紋理帶上,那麼高斯模糊會講紋理也一併模糊了)。

   文章的思路是很清晰的,不過每一步都還是有些問題的。

分塊(Block Splitting)

   本文最大的難點就是要想清楚這篇文章是如何進行分塊和重組的。比如我們要進行4*4的分塊,也就是把大場景分成4*4=16個小場景,一行4個,一列也4個。

   分塊本質如上圖所示,他的意思就是我們從頭到尾的按照4*4像素的進行遍歷,對於每一塊4*4像素裏面的每個像素,依次利用一個公式講他們按順序放入上圖右邊的塊中。如上圖所示,對於第一個4*4的小塊,將第一個像素,放入第一塊,第二個像素放入第二塊....第16個像素放入第16塊。直接遍歷到圖片末尾,就可以將圖片中的像素全部均勻的分配到16個小塊中了,也就組成了16個小場景,這16個小場景本身是完全不同的,他是把大場景中的像素進行了一個重新組合而已,還是以前的像素。並不是16個完全相同的場景。分塊公式如下:

其中width,height爲小塊的寬度和長度,numX,numY是分塊的數量,x,y是原始像素的位置。

計算光照

    計算光照就和普通計算一樣,不過需要的是將所有的VPL均勻的分給每一塊即可(可以通過自己當前處理的像素位置來計算當前是第幾塊場景,然後計算VPL的起點和終點即可)。但最最重要的一點是,需要將最後計算的結果乘以你分塊的數量。大家可以這樣想上面的分塊的時候對於4*4像素要按順序分到16塊中,對於一個光源而言,原本這16個像素都要進行對這個光源的光照計算的,但是由於分塊了,那麼這個光源只會在一塊中進行光照計算,那麼剩下15個像素就不能計算這個光照了,所以亮度就暗了16倍,因此要乘以塊數纔行。有人可能會問,那麼這個結果不就不準確了嗎。是的這樣處理之後結果會非常不準確,因此這個方法我們多用於間接光照(間接光照對場景的光照貢獻不高,就算是不準確也很難發現)。光源開始結束索引如下:

其中width,height爲小塊的寬度和長度,numX是分塊X方向的數量,x,y是像素的位置,num爲分塊總數量,N爲光源總數量。

組合

    組合就是分塊的逆過程。只需要把分塊的像素再按照原來的樣子復原即可。公式如下

邊緣檢測

    邊緣檢測是爲了在進行高斯模糊的時候如果是遇到了邊緣則停止模糊,這樣會讓邊緣更。任意一種邊緣檢測算法都可以,文中的邊緣檢測算法太老了,大家可以自己找新的邊緣檢測算法。我採用的是判讀當前像素的向量和深度與周圍的像素之間進行比較,設定向量閥和深度閥,然後在動態調節這兩個參數以達到好的效果。

高斯模糊

   有人可能會問爲什麼要進行高斯模糊呢?因爲本文的思路是讓一個像素去計算代替周圍一塊來計算光照,如此一來所有的光照影響都集中到一個像素中,但是實際應該是周圍的像素都應該去計算光照的,所以我們採用高斯模糊的方法把這個光照的影響分一點到周圍像素去,讓效果看起來更加逼真。

融合

因爲我們進行了高斯模糊,所以,如果在計算光照的時候把紋理帶上了,那在高斯模糊的時候紋理也會被模糊了,就會看起來怪怪的,因此我們在計算光照的時候不帶上紋理,最後計算完之後再進行融合即可。

 

代碼地址:https://github.com/AngelMonica126/GraphicAlgorithm/tree/master/TestCase_002_A

 

 

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