在這篇文章中单芜,會(huì)分析和對(duì)比三種渲染算法:
- 前向渲染(Forward Rendering)
- 延遲著色(Deferred Shading)
- Forward+(基于Tile的前后渲染)
1. 介紹
前向渲染
前向渲染是通過(guò)在場(chǎng)景中光柵化每個(gè)幾何對(duì)象來(lái)工作的殃饿,在著色過(guò)程中张惹,通過(guò)迭代每個(gè)燈光來(lái)決定該幾何對(duì)象如何被照亮,這意味著每個(gè)幾何對(duì)象都需要考慮場(chǎng)景中的所有燈光蝇更。當(dāng)然沪编,我們也可以通過(guò)舍棄被遮擋的或在相機(jī)的視椎體內(nèi)不可見(jiàn)的幾何對(duì)象來(lái)進(jìn)行優(yōu)化呼盆,我們也可以通過(guò)舍棄不在相機(jī)視椎體的內(nèi)的燈光來(lái)進(jìn)一步優(yōu)化。如果燈光的范圍是已知的漾抬,我們可以在進(jìn)行場(chǎng)景幾何體的渲染之執(zhí)行光椎的剔除宿亡。對(duì)象剔除和光椎剔除只能為前向渲染提供有限的優(yōu)化常遂,并且燈光剔除通常在前向渲染中是不可行的纳令。減少場(chǎng)景中影響場(chǎng)景對(duì)象的燈光數(shù)量更為常見(jiàn),例如克胳,有些圖形引擎每個(gè)像素執(zhí)行兩到三個(gè)的光照平绩,以及每個(gè)頂點(diǎn)執(zhí)行三到四個(gè)的光照。在傳統(tǒng)的由OpenGL和DirectX提供的固定渲染管線中漠另,場(chǎng)景中激活的動(dòng)態(tài)燈光數(shù)量被限制到8個(gè)捏雌,即使是現(xiàn)代的圖形硬件,在可以感知的幀率問(wèn)題發(fā)生之前笆搓,前向渲染管線中動(dòng)態(tài)場(chǎng)景燈光也被限制到100個(gè)性湿。
延遲著色 (Deferred shading)
另一方面,延遲著色通過(guò)將所有的(無(wú)光照)場(chǎng)景對(duì)象光柵化到一系列的2D紋理緩沖區(qū)满败,該紋理緩沖區(qū)存儲(chǔ)了后續(xù)的光照pass中需要的幾何信息肤频,2D紋理緩沖區(qū)中存儲(chǔ)的信息包括:
- 屏幕空間深度
- surface的法線
- diffuse顏色
-
高光(specular)顏色和高光因子(specular power)
- 圖1,這些紋理構(gòu)成了G-Buffer: Diffuse(左上)算墨,高光(右上)宵荒,法線(左下)和深度(右下),高光因子存儲(chǔ)在高光紋理(右上)的alpha通道净嘀。
這些2D紋理緩沖區(qū)的組合也稱(chēng)為幾何緩存區(qū)或G-Buffer[1]报咳。
如果后續(xù)執(zhí)行光照需要也可以將其它信息存儲(chǔ)到紋理緩沖區(qū),但如果每個(gè)像素點(diǎn)32個(gè)bit挖藏,在1080P上至少需要8.29M的紋理內(nèi)存暑刃。
G-Buffer被生成后,幾何信息可以在光照pass中用來(lái)計(jì)算光照信息膜眠,在光照pass中每個(gè)光源都被當(dāng)作一個(gè)幾何對(duì)象被執(zhí)行稍走,每個(gè)與燈光所表示的幾何體相交的像素都使用期望的光照方程進(jìn)行著色。
相比于前向渲染柴底,延遲渲染的優(yōu)勢(shì)是昂貴的光照計(jì)算只對(duì)每個(gè)光源及其覆蓋的像素計(jì)算一次婿脸。使用現(xiàn)代硬件只渲染不透明物體時(shí),延遲渲染技術(shù)可以在1080P分辨率下處理2500個(gè)動(dòng)態(tài)場(chǎng)景燈光柄驻,而不會(huì)有幀率問(wèn)題的發(fā)生狐树。
延遲渲染的一個(gè)劣勢(shì)是只有不透明物體可以被光柵化到G-Buffer,原因是多個(gè)半透明對(duì)象可以覆蓋同一個(gè)屏幕像素鸿脓,而G-Buffer中每個(gè)像素只可以存儲(chǔ)一個(gè)值抑钟。在光照Pass中涯曲,深度值,表面法線在塔,diffuse顏色和高光色被當(dāng)前的屏幕像素所采樣來(lái)進(jìn)行光照幻件,因?yàn)槊總€(gè)G-Buffer只能采樣一個(gè)值,透明物體不能光照pass中被支持蛔溃。為了繞過(guò)這個(gè)問(wèn)題绰沥,透明幾何體必須使用標(biāo)準(zhǔn)的前向渲染技術(shù)進(jìn)行渲染,可以限制場(chǎng)景中透明物體的數(shù)量或動(dòng)態(tài)光源的數(shù)量贺待。只包含不透明物體的場(chǎng)景可以處理大約2000個(gè)動(dòng)態(tài)光源而不會(huì)發(fā)生幀率問(wèn)題徽曲。
延遲渲染的另一個(gè)劣勢(shì)是只能在光照pass中模擬一個(gè)光照模型,這是因?yàn)樵阡秩緹艄鈳缀误w時(shí)只能綁定一個(gè)像素著色器(pixel shader)麸塞。當(dāng)使用ubershader(把所有的計(jì)算都放到一個(gè)shader)時(shí)秃臣,這通常不會(huì)是一個(gè)問(wèn)題。然而哪工,如果你的渲染管線在多個(gè)像素著色器中使用不同的光照模型奥此,通過(guò)切換渲染管線來(lái)執(zhí)行延遲渲染是會(huì)有問(wèn)題的。
Forward+
Forward+[2][3]雁比,也稱(chēng)為基于Tile的前向渲染稚虎,是結(jié)合了前向渲染和基于tile燈光剔除來(lái)減少著色過(guò)程中燈光數(shù)量的一種渲染技術(shù),F(xiàn)orward+主要包含兩個(gè)階段:
- 燈光剔除(Light culling)
-
前向渲染
- 圖2章贞,F(xiàn)orword+光照祥绞,默認(rèn)光照(左),光照熱力圖(右)鸭限。熱力圖中的顏色表示影響當(dāng)前tile的燈光數(shù)量蜕径。黑色表示無(wú)燈光,藍(lán)色表示包含1-10個(gè)燈光败京,綠色表示包含20-30個(gè)燈光兜喻。
Forward+渲染的第一個(gè)pass是使用一個(gè)在屏幕空間統(tǒng)一大小的格子將燈光劃分到一個(gè)個(gè)的tile列表。
第二個(gè)pass是使用標(biāo)準(zhǔn)的前向渲染來(lái)對(duì)每個(gè)物體進(jìn)行著色赡麦,與遍歷場(chǎng)景的每個(gè)動(dòng)態(tài)燈光不同朴皆,當(dāng)前像素的屏幕空間位置用來(lái)查找在先前Pass計(jì)算的當(dāng)前所在格子的燈光列表。相比于標(biāo)準(zhǔn)的前向渲染泛粹,燈光剔除可以帶來(lái)明顯的性能提升遂铡,因?yàn)樗蟠鬁p少了像素正確光照所需要迭代的冗余燈光數(shù)量。不透明物體和透明物體都可以使用相似的行為進(jìn)行處理晶姊,而不會(huì)有明顯的性能損失扒接,并且多材質(zhì)和多光照模型是Forward+原生支持的。
因?yàn)镕orward+是與標(biāo)準(zhǔn)前向渲染共同工作的,因此Forward+可以集成到最初使用前向渲染進(jìn)行構(gòu)建的圖形引擎中钾怔。Forward+沒(méi)有使用B—Buffer碱呼,也沒(méi)有延遲渲染的限制,不透明物體和透明物體都可以使用Forward+進(jìn)行渲染宗侦。使用現(xiàn)代圖形硬件愚臀,可以在高清畫(huà)質(zhì)(1080P)下渲染包含5000-6000個(gè)動(dòng)態(tài)燈光的場(chǎng)景。
定義
在本文中矾利,為了方便理解姑裂,定義一些術(shù)語(yǔ)是很重要的,如果你對(duì)這個(gè)基本的術(shù)語(yǔ)很熟悉梦皮,可以直接跳過(guò)該部分炭分。
Scene
Scene(場(chǎng)景)是指一個(gè)可被渲染的嵌套的層級(jí)對(duì)象桃焕。例如剑肯,所有可被渲染的靜態(tài)對(duì)象會(huì)組合成一個(gè)場(chǎng)景,每個(gè)獨(dú)立的可渲染對(duì)象稱(chēng)為Node(場(chǎng)景結(jié)點(diǎn))观堂,每個(gè)場(chǎng)景結(jié)點(diǎn)指向一個(gè)可渲染對(duì)象(如mesh)让网,整個(gè)場(chǎng)景可以被一個(gè)場(chǎng)景的頂級(jí)結(jié)點(diǎn)引用,稱(chēng)為root node(根結(jié)點(diǎn))师痕。因?yàn)楦Y(jié)點(diǎn)也是一個(gè)場(chǎng)景結(jié)點(diǎn)溃睹,因此場(chǎng)景可以嵌套地創(chuàng)建更復(fù)雜的包含動(dòng)態(tài)或靜態(tài)對(duì)象的場(chǎng)景樹(shù)。
Pass
一個(gè)Pass是指一個(gè)操作胰坟,用來(lái)執(zhí)行渲染技術(shù)的其中一步因篇。例如,不透明(opaque)Pass是迭代場(chǎng)景中的所有對(duì)象笔横,并只渲染場(chǎng)景中的不透明對(duì)象竞滓。透明(transparent)Pass是迭代場(chǎng)景中的所有對(duì)象,并只渲染場(chǎng)景中的透明對(duì)象吹缔。一個(gè)Pass也可以用來(lái)進(jìn)行更加通常的操作商佑,如拷貝GPU資源或調(diào)配一個(gè)計(jì)算著色器(compute shader)。
Technique
Technique是多個(gè)Pass的組合厢塘,多個(gè)Pass必須按一定的順序進(jìn)行執(zhí)行來(lái)實(shí)現(xiàn)一個(gè)渲染算法茶没。
Pipeline State
管線狀態(tài)(Pipeline State)是指在對(duì)象被渲染之前渲染管線的配置,一個(gè)Pipeline State對(duì)象封裝了以下的渲染狀態(tài):
- Shader: 頂點(diǎn)shader(vertex shder)晚碾,細(xì)分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都會(huì)引入一些不同的管線狀態(tài)涣易。
前向渲染
前向渲染是一個(gè)通常只有兩個(gè)pass的渲染技術(shù):
- 不透明Pass
- 透明Pass
不透明Pass會(huì)渲染所有的不透明對(duì)象画机,理想情況下,場(chǎng)景應(yīng)當(dāng)被從前向后進(jìn)行排序以減少overdraw新症。在不透明Pass中不會(huì)執(zhí)行融合(blending)步氏。
透明Pass會(huì)渲染所有的透明對(duì)象,理想情況下徒爹,為了能正確blend荚醒,場(chǎng)景應(yīng)當(dāng)從后向前進(jìn)行排序(相對(duì)于相機(jī)),在該pass下隆嗅,alpha blend需要被開(kāi)啟界阁,使用得半透明材質(zhì)能與已經(jīng)渲染到render target的像素進(jìn)行正確的blend。
在前向渲染中胖喳,所有的燈光與其它的著色指令一起在pixel shader中被執(zhí)行泡躯。
延遲渲染
延遲渲染是一個(gè)包含三個(gè)主要Pass的渲染技術(shù):
- 幾何Pass
- 光照Pass
- 透明Pass
第一個(gè)Pass是與前向渲染的不透明Pass相似的幾何Pass,只有不透明對(duì)象在該P(yáng)ass中被渲染丽焊,不同的是幾何Pass不執(zhí)行任何的光照計(jì)算较剃,但只輸出幾何和材質(zhì)數(shù)據(jù)到前面介紹的G-Buffer中。
在光照Pass中技健,表示燈光的幾何體(geometric volume)和G-Buffer中的材質(zhì)信息被用來(lái)計(jì)算光柵化的像素光照写穴。
最后一個(gè)Pass是透明Pass,該P(yáng)ass與前向渲染的中透明Pass是完全相同的雌贱。因?yàn)檠舆t渲染不支持透明材質(zhì)啊送,因此透明物體需要在一個(gè)使用標(biāo)準(zhǔn)前向渲染的獨(dú)立的Pass中被渲染。
Forward+
Forward+(也被稱(chēng)為基于tile的前向渲染)是包含三個(gè)主要pass的渲染技術(shù):
- 燈光剔除Pass
- 不透明Pass
- 透明Pass
前面介紹中有提到欣孤,燈光剔除Pass需要將動(dòng)態(tài)燈光分類(lèi)到屏幕空間的tile中馋没,一個(gè)燈光索引列表用來(lái)指示哪些燈光索引(從全局燈光列表)覆蓋了屏幕tile。在該pass中导街,兩個(gè)燈光索引列表會(huì)被生成:
- 不透明燈光索引列表
- 透明燈光索引列表
不透明燈光索引列表被用來(lái)渲染不明秀幾何體披泪,透明燈光索引列表用來(lái)渲染透明幾何體。
不透明Pass和透明Pass與標(biāo)準(zhǔn)前向渲染是相同的搬瑰,與遍歷場(chǎng)景中所有的動(dòng)態(tài)燈光不同款票,F(xiàn)oward+渲染只會(huì)遍歷當(dāng)前片元(像素)所在屏幕空間的tile的燈光。
A light refers to one of the following types of lights:
燈光
燈光是指下面幾種燈光的一種:
- 點(diǎn)光源
- 聚光燈(Spot light)
- 方向光
本文中所描述的渲染技術(shù)都支持了這三種燈光類(lèi)型泽论,但沒(méi)有支持區(qū)域光艾少。點(diǎn)光源和聚光燈被模擬成從一個(gè)點(diǎn)向外發(fā)射,方向光被認(rèn)為是從無(wú)限遠(yuǎn)處的一點(diǎn)發(fā)射光線翼悴,任何地方都具有相同的方向渺蒿。點(diǎn)光源和聚光燈都有一個(gè)有限的范圍,超過(guò)這個(gè)范圍強(qiáng)度會(huì)下降到0充岛,光強(qiáng)度的下降稱(chēng)為衰減(attenuation)怜森。點(diǎn)光源被描述成一個(gè)球嫌佑,聚光燈作為一個(gè)圓椎體,方向光是全屏幕的四方形(quad)。