延遲渲染 Deferred Rendering

2021-09-25 20:17:04 字數 3401 閱讀 2502

在計算機圖形學中,延遲渲染( deferred rendering) ,即延遲著色(deferred shading),是將著色計算延遲到深度測試之後進行處理的一種渲染方法。延遲著色技術的最大的優勢就是將光源的數目和場景中物體的數目在複雜度層面上完全分開,能夠在渲染擁有成百上千光源的場景的同時依然保持很高的幀率,給我們渲染擁有大量光源的場景提供了很多可能性

我們知道,正向渲染(forward rendering),或稱正向著色(forward shading),是渲染物體的一種非常直接的方式,在場景中我們根據所有光源照亮乙個物體,之後再渲染下乙個物體,以此類推。

傳統的正向渲染思路是,先進行著色,再進行深度測試。其的主要缺點就是光照計算跟場景複雜度和光源個數有很大關係。假設有n個物體,m個光源,且每個每個物體受所有光源的影響,那麼複雜度就是o(m*n)

正向渲染簡單直接,也很容易實現,但是同時它對程式效能的影響也很大,因為對每乙個需要渲染的物體,程式都要對每個光源下每乙個需要渲染的片段進行迭代,如果舊的片段完全被一些新的片段覆蓋,最終無需顯示出來,那麼其著色計算花費的時間就完全浪費掉了

可以將延遲渲染( deferred rendering)理解為先將所有物體都先繪製到螢幕空間的緩衝(即g-buffer,geometric buffer,幾何緩衝區)中,再逐光源對該緩衝進行著色的過程,從而避免了因計算被深度測試丟棄的⽚元的著色而產⽣的不必要的開銷。也就是說延遲渲染基本思想是,先執行深度測試,再進行著色計算將本來在物空 間(三維空間)進行光照計算放到了像空間(二維空間)進行處理。

對應於正向渲染o(m*n)的 複雜度,經典的延遲渲染複雜度為o(n+m)

g-buffer,全稱geometric buffer ,譯作幾何緩衝區,它主要用於儲存每個畫素對應的位置(position),法線(normal),漫反射顏色(diffuse color)以及其他有用材質引數。根據這些資訊,就可以在像空間(二維空間)中對每個畫素進行光照處理。

可以將延遲渲染理解為兩個pass的過程:

1、幾何處理階段(geometry pass)。這個階段中,我們獲取物件的各種幾何資訊,並將第二步所需的各種資料儲存(也就是渲染)到多個g-buffer中;

2、光照處理階段(lighting pass)。在這個pass中,我們只需渲染出乙個螢幕大小的二維矩形,使用第一步在g-buffer中儲存的資料對此矩陣的每乙個片段計算場景的光照;光照計算的過程還是和正向渲染以前一樣,只是現在我們需要從對應的g-buffer而不是頂點著色器(和一些uniform變數)那裡獲取輸入變數了。

延遲渲染方法乙個很大的好處就是能保證在g-buffer中的片段和在螢幕上呈現的畫素所包含的片段資訊是一樣的,因為深度測試已經最終將這裡的片段資訊作為最頂層的片段。這樣保證了對於在光照處理階段中處理的每乙個畫素都只處理一次,所以我們能夠省下很多無用的渲染呼叫。除此之外,延遲渲染還允許我們做更多的優化,從而渲染更多的光源。

在幾何處理階段中填充g-buffer非常高效,因為我們直接儲存位置,顏色,法線等物件資訊到幀緩衝中,這個過程幾乎不消耗處理時間。

而在此基礎上使用多渲染目標(multiple render targets, mrt)技術,我們可以在乙個pass之內完成所有渲染工作。

正向渲染

延遲渲染

deferred rendering 的最大的優勢就是將光源的數目和場景中物體的數目在複雜度層面上完全分開。(這句話已經出現過很多次了)

優點:

缺點:

延遲光照的具體的思路是:

1、渲染場景中不透明(opaque )的幾何體。將法線向量n和鏡面擴充套件因子(specular spread factor)m 寫入緩衝區。這個n/m-buffer 緩衝區是乙個類似 g-buffer的緩衝區,但包含的資訊更少,更輕量,適合於單個輸出顏色緩衝區,因此不需要mrt支援。

2、渲染光照。計算漫反射和鏡面著色方程,並將結果寫入不同的漫反射和鏡面反射累積緩衝區。這個過程可以在乙個單獨的pass中完成(使用mrt),或者用兩個單獨的pass。環境光照明可以在這個階段使用乙個 full-screen pass進行計算。

3、對場景中的不透明幾何體進行第二次渲染。從紋理中讀取漫反射和鏡面反射值,對前面步驟中漫反射和鏡面反射累積緩衝區的值進行調製,並將最終結果寫入最終的顏色緩衝區。若在上一階段沒有處理環境光照明,則在此階段應用環境光照明。

4、使用非延遲著色方法渲染半透明幾何體。

實驗資料表明tbdr在大量光源存在的情況下明顯優於上文提到的light pre-pass。

我們知道,延遲渲染的瓶頸在於讀寫 g-buffer,在大量光源下,具體瓶頸將位於每個光源對 g-buffer的讀取及與顏色緩衝區(color buffer)混合。這裡的問題是,每個光源,即使它們的影響範圍在螢幕空間上有重疉,因為每個光源是在不同的繪製中進行,所以會重複讀取g-buffer中相同位置的資料,計算後以相加混合方式寫入顏色緩衝。光源越多,記憶體頻寬用量越大。

而分塊延遲渲染的主要思想則是把螢幕分拆成細小的柵格,例如每 32 × 32 象素作為乙個分塊(tile)。然後,計算每個分塊會受到哪些光源影響,把那些光源的索引儲存在分塊的光源列表裡。最後,逐個分塊進行著色,對每畫素讀取 g-buffer 和光源列表及相關的光源資訊。因此,g-buffer的資料只會被讀取1次且僅1次,寫入 color buffer也是1次且僅1次,大幅降低記憶體頻寬用量。不過,這種方法需要計算光源會影響哪些分塊,這個計算又稱為光源剔除(light culling),可以在 cpu 或 gpu(通常以 compute shader 實現)中進行。用gpu計算的好處是,gpu 計算這類工作比 cpu 更快,也減少 cpu/gpu 資料傳輸。而且,可以計算每個分塊的深度範圍(depth range),作更有效的剔除。

也就是說,tbdr 主要思想就是將螢幕分成乙個個小塊 tile。然後根據這些 depth 求得每個 tile 的 bounding box。對每個 tile 的 bounding box 和 light 進行求交,這樣就得到了對該 tile 有作用 的 light 的序列。最後根據得到的序列計算所在 tile 的光照效果。

對比 deferred rendering,之前是對每個光源求取其作用區域 light volume,然後決定其作用的的 pixel,也就是說每個光源要求取一次。而使用 tbdr,只要遍歷每個 pixel,讓其所屬 tile 與光線求交,來計算作用其上的 light,並利用 g-buffer 進行 shading。一方面這樣做減少 了所需考慮的光源個數,另一方面與傳統的 deferred rendering 相比,減少了訪問的頻寬。

shader 延遲渲染

正向渲染 forward rendering 或稱正向著色 forward shading 是渲染物體的一種非常直接的方式,在場景中我們根據所有光源照亮乙個物體,之後再渲染下乙個物體,以此 類推。傳統的正向渲染思路是,先進行著色,再進行深度測試。其的主要缺點就是光照計算跟場景 複雜度和光源個數有很大...

延遲渲染路徑

此頁面將詳細介紹延遲渲染路徑。參見 wikipedia 延遲渲染以獲取介紹性的技術概述。當使用延遲渲染時,在單個gameobject物體上起作用的燈光的數量就沒有限制。所有的燈光都是逐畫素計算的,這意味著它們都能正確地與法線貼圖互動。除此之外,所有的燈光都能擁有剪影和陰影。延遲渲染的乙個優勢就是處理...

Unity 前向渲染與延遲渲染

只要在攝像機設定下就可以了 由於我設定了9盞燈光,而unity buildin只支援4盞,所以顯示的燈光是錯誤的 由上圖可見 unity前向渲染的順序是 先做深度圖,我猜是為了做深度剔除,深度測試,避免重複繪製,然後在renderloop裡對每個物體進行光照法線計算 天空盒透明物體 後效貌似延遲渲染...