前向渲染(Forward Rendering)和延遲渲染(Deferred Rendering)

前向渲染(Forward Rendering)

它的實現最貼合我們的思維邏輯,當我們渲染模型時,只需要關心畫模型然後直接處理光照,讓它自己去做深度測試,最後深度測試過的都顯示在屏幕上。

1、對要渲染的物體進行遍歷渲染出shadowmap

2、再遍歷一遍上面要渲染的物體,根據shadowmap對每一個物體的像素進行光照計算

優點

很明顯,就是簡單,並且可以針對每個物體指定它的材質,因爲每個物體都是獨立渲染的。

缺點

1、由於依賴深度測試,如果物體是亂序的,可能會出現大量的像素光照計算都是浪費的。

2、不能支持光源數量較多的情況。所以我們一般有兩種做法來處理多光源的情況,一種是一遍渲染多個光源,所有光照運算都在一個着色器中進行,因爲一個着色器有指令數量的限制。另一種是多遍渲染多個光源,意思就是每多一盞燈,就多渲染一次模型,所以性能消耗也比較大。

延遲渲染(Deferred Rendering)

它的做法是在第一遍渲染模型的時候,不進行光照計算,直接將位置、法線深度、顏色等存到G-Buffer。很多人第一次接觸G-Buffer這個名詞都是一頭霧水,其實就是創建多張和屏幕一樣大的紋理,然後每張紋理的像素值分別用來存上面提到的這些數據。也就是說一次渲染,需要輸出多張紋理,這跟前向渲染是不同的, 前向渲染只渲染到一張紋理上,這張紋理最終會渲染在屏幕上。而延遲渲染這多張紋理都不是最終結果,可以理解爲只是用幾張貼圖存儲一堆中間數據。

第二遍再根據G-Buffer的數據,進行光照計算,寫入幀緩衝區

優點

處理完G-Buffer之後,其實每盞燈光就可以通過一個Drawcall的消耗去執行光照計算。第一遍處理完的G-Buffer是深度測試過的,不像前向渲染一樣,有那麼多光照計算的浪費。

缺點

1、最終的光照計算方式只能是一種,也就是其他文章提到的只允許一個材質,因爲最終計算的時候只剩下一堆數據,不知道它們分別是誰的,所以只能無差別對待。而前向渲染可以每個模型一種計算方式。

2、不允許使用透明物件,因爲最終G-Buffer只剩一個像素了,無法進行混合。不過可以在第二遍渲染完之後,用前向渲染的方式渲染透明物體。

3、不支持抗鋸齒,意味着不能用MSAA,不過可以用FXAA進行後期處理

4、有些硬件不支持MRT(Multiple Render Targets 多重紋理目標),也就是輸出到多張紋理上實現G-Buffer的功能

5、G-Buffer需要比較大的帶寬,有些硬件沒不具備這個能力

6、由於光照計算本身性能消耗也不低,延遲渲染的光照計算其實等同於在做一次全屏的後處理,後處理其實對手機來說過於昂貴。而如果只有一盞燈的話,其實前向渲染省了這次額外的渲染。所以移動設備上延遲渲染的性能會比前向渲染的性能要差一些

Forward+ Shading

最近刷知乎的時候看到一篇文章結合了前向渲染和延遲渲染的優勢,爲前向渲染無法同時使用多燈光的問題提供瞭解決的方案。https://zhuanlan.zhihu.com/p/85615283

 

題外話

其實一開始接觸光照模型、渲染路徑、PBR啥的總被一些名詞折騰得很懵逼,這裏簡單提一下,標準光照模型和PBR都屬於光照模型,在前向渲染中主要負責像素着色器裏的光照計算,而延遲渲染則負責第二遍對整個G-Buffer進行光照計算。渲染路徑指的是整個渲染流程,先後幹什麼事,例如前向渲染和延遲渲染可以是渲染路徑裏的一個環節,還可以有其他的,例如渲染UI或者清屏之類的

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