Forward Render
傳統(tǒng)的渲染方式,你提供給顯卡形狀Mesh,它將其打散成一堆節(jié)點(diǎn),接著經(jīng)過(guò)一系列的變換和分割成為Fregment或者像素,在呈現(xiàn)在屏幕之前已經(jīng)完成了所有的渲染處理。
這是相當(dāng)線性的,每一個(gè)形狀都會(huì)在生成完整圖像之前經(jīng)過(guò)流水線的每一個(gè)階段。
Deferred Rendering
中文稱為延遲渲染,渲染的工作被放在最后,直到所有的形狀到都完成了前面的工作,一旦所有需要的緩沖建好,就直接被讀進(jìn)一種著色算法中,合并在一起從而得出最后的結(jié)果。 這樣,著色一個(gè)場(chǎng)景所需的計(jì)算和內(nèi)存的帶寬被減少到了這些可見(jiàn)的部分中,從而降低了著色深度的復(fù)雜性。
***G Buffer *- 指Geometry Buffer,亦即“物體緩沖”。區(qū)別于普通的僅將顏色渲染到紋理中,G-Buffer指包含顏色、法線、世界空間坐標(biāo)的緩沖區(qū),亦即指包含顏色、法線、世界空間坐標(biāo)的紋理。由于G-Buffer需要的向量長(zhǎng)度超出通常紋理能包含的向量的長(zhǎng)度,通常在游戲開(kāi)發(fā)中,使用多渲染目標(biāo)技術(shù)來(lái)生成G-Buffer,即在一次繪制中將顏色、法線、世界空間坐標(biāo)分別渲染到三張浮點(diǎn)紋理中。
常見(jiàn)的做法是將顏色,深度和法線分別渲染到不同的buffer里面,在最后計(jì)算光照的時(shí)候的通過(guò)這三個(gè)buffer和光源的信息計(jì)算出最終pixel的顏色。
Color, Depth, and Normal buffer
Final lighting (shading) result generated using the three buffers
比較
在一個(gè)標(biāo)準(zhǔn)的Forward Rendering 的渲染管線里,對(duì)于每個(gè)光源,必須計(jì)算場(chǎng)景中每個(gè)頂點(diǎn)的光照(使用Vertex shading)。假設(shè)場(chǎng)景中有100個(gè)物體,每個(gè)物體有1000個(gè)頂點(diǎn),那就差不多有100000個(gè)多邊形,顯卡處理這個(gè)量集的定點(diǎn)數(shù)是很隨意的,但是當(dāng)把這些多邊形發(fā)送到fregment shader中進(jìn)行處理, 在這里的光照計(jì)算會(huì)消耗大量的性能。
開(kāi)發(fā)者總是試圖將更多的光照計(jì)算放到Vertex Shader而不是放到fregment shader,這樣能夠節(jié)省很多性能。每一塊可見(jiàn)的片段都會(huì)進(jìn)行昂貴的光照的計(jì)算,不管它是不是被其他的片段遮擋,度過(guò)屏幕的像素是1024 * 768,那么將有將近800000個(gè)像素需要渲染,那么渲染的每一幀在都可能在在fregment shader 中進(jìn)行數(shù)百萬(wàn)次,甚至那些經(jīng)過(guò)深度測(cè)試已經(jīng)被遮擋的像素也要被計(jì)算,這樣將會(huì)造成很大的性能浪費(fèi)。
更可怕的是,當(dāng)你在場(chǎng)景中再加上一盞燈的時(shí)候,那么fragment shader又要為這個(gè)光源再重新計(jì)算一遍,想像一下一條滿是燈光的街道...
Forward Rendering渲染的復(fù)雜度可以用O(num_geometry_fragments * num_lights)來(lái)表示,可以看出復(fù)雜度和集合體的面數(shù)還有光源的數(shù)量正相關(guān)。
一些引擎通過(guò)一些算法進(jìn)行了優(yōu)化,比如太遠(yuǎn)處的光源不參與計(jì)算,合并光源,或者使用light map(只能是靜態(tài)),但是i如果想要實(shí)現(xiàn)動(dòng)態(tài)多光源,那就需要一個(gè)更好的解決方案。
Deferred Rendering 就是一個(gè)很好的解決方案。它能夠很好的減少渲染物體的數(shù)量,也就是渲染片段的數(shù)量,在進(jìn)行光照計(jì)算的時(shí)候用的是屏幕上的像素?cái)?shù)量,而不是所有片段像素的總和。它的光照渲染的時(shí)間復(fù)雜度可以用O(screen_resolution * num_lights)來(lái)表示,他和場(chǎng)景中物體的數(shù)量是無(wú)關(guān)的,只和光源數(shù)量有關(guān)。
如何抉擇
簡(jiǎn)單的回答是,如果你使用的是很多動(dòng)態(tài)光源,那么就使用Deferred Rendering,但是它也有一些缺點(diǎn):
1.需要比較新的顯卡,支持多目標(biāo)渲染;
2.需要很大的顯卡帶寬,用來(lái)傳遞Buffer;
3.不用處理透明的對(duì)象(除非把Forward rendering 和 Deferred rendering結(jié)合起來(lái));
4.沒(méi)法用傳統(tǒng)的抗鋸齒方法, 比如MSAA,但是屏幕空間的FXAA是適用的;
5.只能使用一種材質(zhì),但是有一種解決方法是Deferred Lighting;
6.陰影的數(shù)量還是和光源的數(shù)量有關(guān)。
如果游戲中沒(méi)有很多的光源并且需要兼容老的設(shè)備,那么最好選擇Forward Rendering,然后采用靜態(tài)的Light map,效果也很不錯(cuò)。
參考
Forward Rendering vs. Deferred Rendering - http://gamedevelopment.tutsplus.com/articles/forward-rendering-vs-deferred-rendering--gamedev-12342
Deferred shading - http://en.wikipedia.org/wiki/Deferred_shading#Deferred_lighting
Deferred Shading Rendering Path - http://docs.unity3d.com/Manual/RenderTech-DeferredShading.html
Forward Rendering Path - Detailshttp://docs.unity3d.com/Manual/RenderTech-ForwardRendering.html