游戲渲染技術(shù):前向渲染 vs 延遲渲染 vs Forward+渲染(一)

在這篇文章中,會分析和對比三種渲染算法:

  1. 前向渲染(Forward Rendering)
  2. 延遲著色(Deferred Shading)
  3. Forward+(基于Tile的前后渲染)

1. 介紹

前向渲染

前向渲染是通過在場景中光柵化每個幾何對象來工作的,在著色過程中,通過迭代每個燈光來決定該幾何對象如何被照亮,這意味著每個幾何對象都需要考慮場景中的所有燈光。當(dāng)然,我們也可以通過舍棄被遮擋的或在相機的視椎體內(nèi)不可見的幾何對象來進行優(yōu)化,我們也可以通過舍棄不在相機視椎體的內(nèi)的燈光來進一步優(yōu)化。如果燈光的范圍是已知的,我們可以在進行場景幾何體的渲染之執(zhí)行光椎的剔除。對象剔除和光椎剔除只能為前向渲染提供有限的優(yōu)化,并且燈光剔除通常在前向渲染中是不可行的。減少場景中影響場景對象的燈光數(shù)量更為常見,例如,有些圖形引擎每個像素執(zhí)行兩到三個的光照,以及每個頂點執(zhí)行三到四個的光照。在傳統(tǒng)的由OpenGL和DirectX提供的固定渲染管線中,場景中激活的動態(tài)燈光數(shù)量被限制到8個,即使是現(xiàn)代的圖形硬件,在可以感知的幀率問題發(fā)生之前,前向渲染管線中動態(tài)場景燈光也被限制到100個。

延遲著色 (Deferred shading)

另一方面,延遲著色通過將所有的(無光照)場景對象光柵化到一系列的2D紋理緩沖區(qū),該紋理緩沖區(qū)存儲了后續(xù)的光照pass中需要的幾何信息,2D紋理緩沖區(qū)中存儲的信息包括:

  • 屏幕空間深度
  • surface的法線
  • diffuse顏色
  • 高光(specular)顏色和高光因子(specular power)


    G-Buffer-1024x576.jpg
  • 圖1,這些紋理構(gòu)成了G-Buffer: Diffuse(左上),高光(右上),法線(左下)和深度(右下),高光因子存儲在高光紋理(右上)的alpha通道。

這些2D紋理緩沖區(qū)的組合也稱為幾何緩存區(qū)或G-Buffer[1]。

如果后續(xù)執(zhí)行光照需要也可以將其它信息存儲到紋理緩沖區(qū),但如果每個像素點32個bit,在1080P上至少需要8.29M的紋理內(nèi)存。

G-Buffer被生成后,幾何信息可以在光照pass中用來計算光照信息,在光照pass中每個光源都被當(dāng)作一個幾何對象被執(zhí)行,每個與燈光所表示的幾何體相交的像素都使用期望的光照方程進行著色。

相比于前向渲染,延遲渲染的優(yōu)勢是昂貴的光照計算只對每個光源及其覆蓋的像素計算一次。使用現(xiàn)代硬件只渲染不透明物體時,延遲渲染技術(shù)可以在1080P分辨率下處理2500個動態(tài)場景燈光,而不會有幀率問題的發(fā)生。

延遲渲染的一個劣勢是只有不透明物體可以被光柵化到G-Buffer,原因是多個半透明對象可以覆蓋同一個屏幕像素,而G-Buffer中每個像素只可以存儲一個值。在光照Pass中,深度值,表面法線,diffuse顏色和高光色被當(dāng)前的屏幕像素所采樣來進行光照,因為每個G-Buffer只能采樣一個值,透明物體不能光照pass中被支持。為了繞過這個問題,透明幾何體必須使用標準的前向渲染技術(shù)進行渲染,可以限制場景中透明物體的數(shù)量或動態(tài)光源的數(shù)量。只包含不透明物體的場景可以處理大約2000個動態(tài)光源而不會發(fā)生幀率問題。

延遲渲染的另一個劣勢是只能在光照pass中模擬一個光照模型,這是因為在渲染燈光幾何體時只能綁定一個像素著色器(pixel shader)。當(dāng)使用ubershader(把所有的計算都放到一個shader)時,這通常不會是一個問題。然而,如果你的渲染管線在多個像素著色器中使用不同的光照模型,通過切換渲染管線來執(zhí)行延遲渲染是會有問題的。

Forward+

Forward+[2][3],也稱為基于Tile的前向渲染,是結(jié)合了前向渲染和基于tile燈光剔除來減少著色過程中燈光數(shù)量的一種渲染技術(shù),F(xiàn)orward+主要包含兩個階段:

  • 燈光剔除(Light culling)
  • 前向渲染


    Forward--1024x288.jpg
  • 圖2,F(xiàn)orword+光照,默認光照(左),光照熱力圖(右)。熱力圖中的顏色表示影響當(dāng)前tile的燈光數(shù)量。黑色表示無燈光,藍色表示包含1-10個燈光,綠色表示包含20-30個燈光。

Forward+渲染的第一個pass是使用一個在屏幕空間統(tǒng)一大小的格子將燈光劃分到一個個的tile列表。

第二個pass是使用標準的前向渲染來對每個物體進行著色,與遍歷場景的每個動態(tài)燈光不同,當(dāng)前像素的屏幕空間位置用來查找在先前Pass計算的當(dāng)前所在格子的燈光列表。相比于標準的前向渲染,燈光剔除可以帶來明顯的性能提升,因為它大大減少了像素正確光照所需要迭代的冗余燈光數(shù)量。不透明物體和透明物體都可以使用相似的行為進行處理,而不會有明顯的性能損失,并且多材質(zhì)和多光照模型是Forward+原生支持的。

因為Forward+是與標準前向渲染共同工作的,因此Forward+可以集成到最初使用前向渲染進行構(gòu)建的圖形引擎中。Forward+沒有使用B—Buffer,也沒有延遲渲染的限制,不透明物體和透明物體都可以使用Forward+進行渲染。使用現(xiàn)代圖形硬件,可以在高清畫質(zhì)(1080P)下渲染包含5000-6000個動態(tài)燈光的場景。

定義

在本文中,為了方便理解,定義一些術(shù)語是很重要的,如果你對這個基本的術(shù)語很熟悉,可以直接跳過該部分。

Scene

Scene(場景)是指一個可被渲染的嵌套的層級對象。例如,所有可被渲染的靜態(tài)對象會組合成一個場景,每個獨立的可渲染對象稱為Node(場景結(jié)點),每個場景結(jié)點指向一個可渲染對象(如mesh),整個場景可以被一個場景的頂級結(jié)點引用,稱為root node(根結(jié)點)。因為根結(jié)點也是一個場景結(jié)點,因此場景可以嵌套地創(chuàng)建更復(fù)雜的包含動態(tài)或靜態(tài)對象的場景樹。

Pass

一個Pass是指一個操作,用來執(zhí)行渲染技術(shù)的其中一步。例如,不透明(opaque)Pass是迭代場景中的所有對象,并只渲染場景中的不透明對象透明(transparent)Pass是迭代場景中的所有對象,并只渲染場景中的透明對象。一個Pass也可以用來進行更加通常的操作,如拷貝GPU資源或調(diào)配一個計算著色器(compute shader)。

Technique

Technique是多個Pass的組合,多個Pass必須按一定的順序進行執(zhí)行來實現(xiàn)一個渲染算法。

Pipeline State

管線狀態(tài)(Pipeline State)是指在對象被渲染之前渲染管線的配置,一個Pipeline State對象封裝了以下的渲染狀態(tài):

  • Shader: 頂點shader(vertex shder),細分shader(tessellation shader),幾何shader(geometry shader)和像素shader(pixel shader。
  • 光柵化狀態(tài)(Rasterizer state): 多邊形填充模式(fill mode),裁剪模式(culling model),scissor, viewport
  • 融合狀態(tài)(blend state)
  • depth/stencil state
  • render target

其中,dx12等不同的渲染API都會引入一些不同的管線狀態(tài)。

前向渲染

前向渲染是一個通常只有兩個pass的渲染技術(shù):

  • 不透明Pass
  • 透明Pass

不透明Pass會渲染所有的不透明對象,理想情況下,場景應(yīng)當(dāng)被從前向后進行排序以減少overdraw。在不透明Pass中不會執(zhí)行融合(blending)。

透明Pass會渲染所有的透明對象,理想情況下,為了能正確blend,場景應(yīng)當(dāng)從后向前進行排序(相對于相機),在該pass下,alpha blend需要被開啟,使用得半透明材質(zhì)能與已經(jīng)渲染到render target的像素進行正確的blend。

在前向渲染中,所有的燈光與其它的著色指令一起在pixel shader中被執(zhí)行。

延遲渲染

延遲渲染是一個包含三個主要Pass的渲染技術(shù):

  • 幾何Pass
  • 光照Pass
  • 透明Pass

第一個Pass是與前向渲染的不透明Pass相似的幾何Pass,只有不透明對象在該Pass中被渲染,不同的是幾何Pass不執(zhí)行任何的光照計算,但只輸出幾何和材質(zhì)數(shù)據(jù)到前面介紹的G-Buffer中。

在光照Pass中,表示燈光的幾何體(geometric volume)和G-Buffer中的材質(zhì)信息被用來計算光柵化的像素光照。

最后一個Pass是透明Pass,該Pass與前向渲染的中透明Pass是完全相同的。因為延遲渲染不支持透明材質(zhì),因此透明物體需要在一個使用標準前向渲染的獨立的Pass中被渲染。

Forward+

Forward+(也被稱為基于tile的前向渲染)是包含三個主要pass的渲染技術(shù):

  • 燈光剔除Pass
  • 不透明Pass
  • 透明Pass

前面介紹中有提到,燈光剔除Pass需要將動態(tài)燈光分類到屏幕空間的tile中,一個燈光索引列表用來指示哪些燈光索引(從全局燈光列表)覆蓋了屏幕tile。在該pass中,兩個燈光索引列表會被生成:

  • 不透明燈光索引列表
  • 透明燈光索引列表

不透明燈光索引列表被用來渲染不明秀幾何體,透明燈光索引列表用來渲染透明幾何體。

不透明Pass和透明Pass與標準前向渲染是相同的,與遍歷場景中所有的動態(tài)燈光不同,F(xiàn)oward+渲染只會遍歷當(dāng)前片元(像素)所在屏幕空間的tile的燈光。

A light refers to one of the following types of lights:

燈光

燈光是指下面幾種燈光的一種:

  • 點光源
  • 聚光燈(Spot light)
  • 方向光

本文中所描述的渲染技術(shù)都支持了這三種燈光類型,但沒有支持區(qū)域光。點光源和聚光燈被模擬成從一個點向外發(fā)射,方向光被認為是從無限遠處的一點發(fā)射光線,任何地方都具有相同的方向。點光源和聚光燈都有一個有限的范圍,超過這個范圍強度會下降到0,光強度的下降稱為衰減(attenuation)。點光源被描述成一個球,聚光燈作為一個圓椎體,方向光是全屏幕的四方形(quad)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容