Tiled Based流程
1.將屏幕分成小塊,每個小塊爲一個視錐體
2,(depth bounds)在每一個視錐體中,根據ZBuffer得到每個Tile的MinZ和MaxZ,用MinZ到MaxZ這片區域對光做交點測試(使用compute shader)
因此不需要光體積,點光源只需要position和range,spotlight也用球來做剔除bound
3.(light culling)剔除後,每個Tile裏面的光的index寫入list,得到tile個光源index的list
4.之後進行color pass
Depth Bounds
在每個tile的視錐體裏取得maxZ和minZ,需要用到compute shader
每次採樣多個深度比一個要節省時間( Parallel Reduction)
Light Culling
Advancements in Tiled-Based Compute Rendering裏面介紹了兩種剔除方法,一種是視錐體剔除,一種是AABB剔除,AABB剔除結果好一些
短視錐體AABB精度更高
在深度不連續( Depth Discontinuities)也就是minZMaxZ相距太遠導致中間有很多沒有照到物體的光源,一般會出現在物體邊緣部分(最壞情況是物體邊界到farplane),如果計算會浪費,需要被剔除掉,剔除方法文中介紹有2.5D Culling,和halfZ,還有改良halfZ
2.5D Culling
缺點:
先進行上面的lightculling,將視錐體外的光剔除
將minZmaxZ構造的depth bounds分成32份,每份裏進行1+light個 Depth mask & Depth mask
之所以是32份是因爲用一個32bit的Depth mask
首先把物體寫入一個Depth mask,32塊,如果有一塊裏包含物體,就爲1否則爲0
再對每個光寫入Depth mask,與物體的Depth mask進行&操作,這樣就知道光是否照到物體,而且知道照到哪塊物體了,,可以剔除掉中間沒有用的光源了
優化與測試
得出結論改良HalfZ和AABB是最性能最好的
並且可以把塊變小,用16x16與32x32作對比,32x32雖然會增加colornpass消耗,但是會減少culling時間,整體還是比16x16時間短
Tiled Based Deferred Rendering
Tiled Based Deferred Rendering流程
1.生成GBuffer
2.將GBuffer分tile,每個tile用cs計算出depth bound
3.進行light cull,得到light index list
4.color pass,使用GBuffer信息,用該fragment所在tile的light index list進行繪製
TBDR好處
傳統Deferred每一個光照要繪製整個光照體積,光源多了也很消耗,
TBDR通過分塊與光源進行求交測試,不需要像傳統Deferred一樣繪製光體積還要深度測試和stencil pass了
Forward+
Forward+流程
1.ZPrePass(爲了獲取深度進行depth bound,但是ZPrePass也會輔助硬件進行earlyZ)
2.將ZBuffer分tile,每個tile用cs計算出depth bound
3. 進行light cull,得到light index list
4.同forward一樣,。每個物體走FS,用該fragment所在tile的light index list進行繪製
Forward+好處
可以用多個光源,不必再多一個光源就要全部繪製一遍,在光源照不到的部分就不需要繪製
需要ZPrePass來提前生成ZBuffer,比Deferred帶寬要少,
Forward+比傳統Deferred要快
詳細性能分析請看龔大這篇文章
參考:
1. Forward+: Bringing DeferredLighting to the Next Level
2. A 2.5D Culling for Forward+
3. Advancements in Tiled-Based Compute Rendering
----by wolf96 2019/1/1