Hierarchical Z-Buffer Visibility (Hi-Z)

可見性算法的目的是丟棄隱藏面,

對於GPU可以節省CPU傳入頂點信息的帶寬&頂點ALU&Fragment ALU的消耗,

對於CPU可以減少DC(物件被剔除了)

有三種方式可以實現可見性算法

1.object-space coherence:

物件級別的剔除,粒度最大

傳統Ray casting剔除就是這種方法

2.image-space coherence

屏幕空間像素級別剔除,粒度最小

傳統ZBuffer剔除就是這種方法(Zbuffer的缺點包括不支持半透明剔除,因爲半透明不寫入深度。並且需要ZPrePass,會增加DC)

3.temporal coherence

是利用上一幀的可見性信息,來加速這一幀的可見性運算

Greene93論文中的提出方法利用了上面三種方式

 

object-space coherence

利用八叉樹空間細分 octree spatial subdivision ray tracing來做到object-space coherence剔除

將物件放入八叉樹中,在視椎體中進行相交測試,如果相交,我們再把物件primitive細分,然後遞歸進行相交測試,把通過測試的primitive提交DrawCall

 

image-space coherence

利用Z pyramid Z金字塔來做到image-space coherence剔除

實現方法:

首先ZPrePass畫出一張ZBuffer原始分辨率的,再對這張Zbuffer進行降採樣來構建Mip Chain,但是不能利用GL默認的生成MipChain方法,每小一個級別相當於4個像素變一個像素,我們需要選擇四個像素中Z最遠的像素

作爲當前mip級別的像素,

個人理解:構建一套mipchain,相當於對屏幕劃分不同大小的Tile,

先選取最粗級別的mipmap,也就相當於最大的Tile

先將polygon的每個頂點選取最近的頂點(Greene93中的方法2)與該Tile像素作比較,就相當於polygon最近的頂點與這個tile中最遠的像素作比較,如果polygon最近的頂點都比整個tile中最遠的深度還要遠,就說明整個Polygon都是隱藏的,都在別人後面

如果在前面,就換上一級別粒度更小的進行測試,直到原始Zbuffer(mip0)

 

爲什麼要生成mipmap不直接用原始ZBuffer比較呢?

因爲有大量Polygon連最粗級別mip都不會通過,而且粗級別mip分辨率低,要比原始分辨率省(帶寬?)

 

Greene93中的方法2就是將每個polygon中最近頂點與Z比較

Greene93中的方法1是需要算出每個polygon在每個mip級別也就是一個Tile的大小中的最近深度(也就是一個像素的大小)進行比較,

方法2比方法1粒度更細,剔除精度更高,但是算出每個polygon在每個mip級別一像素範圍中的最近深度也很昂貴,需要按需選擇

 

該方法一般用compute shader將polygon信息傳入Buffer,得出運算結果後返回可見的Polygon給CPU,在進行DC提交

如果用GPU Driven可以直接用於GPU剔除

 

The overhead of generating the HiZ mip chain and dispatching the culling process is the real bottleneck though, there’s little difference between 900 bounds and 10,000 bounds.

https://www.nickdarnell.com/hierarchical-z-buffer-occlusion-culling/

該方法最昂貴的地方在於降採樣mipmap(需要採樣作比較),和剔除的部分

 

temporal coherence

文中維護了上一幀的visible octree node列表用於這一幀的可見性算法

好處:

If there is sufficient frame-to-frame

coherence, most of the visible geometry will already be rendered,so the Z-pyramid test will be much more effective than when we start from scratch.

 

實現

所以文中方法的一套流程就是

1.進行octree spatial subdivision ray tracing,並利用上一幀visible octree node結果加速次運算,粗粒度的先剔除物件與部分polygon

2.然後用Z pyramid進行細粒度的剔除,cs返回一個可見polygon的buffer

3.CPU提交DC

 

缺點

兩種方法都有消耗多的地方

octree spatial subdivision 

需要花費CPU時間進行細分與相交測試

 

Z pyramid 

需要ZprePass 增加一倍DC

降採樣增加帶寬,增加GPU ALU消耗

需要ReadBack Zbuffer,“Z Query”,使CPU等待GPU計算結果,並且增加TileMemory->SystemMemory讀迴帶寬開銷,,但是如果使用 GPU Driven,在GPU中剔除&提交DC,就不會有這個問題

如果遮擋關係不是那麼複雜,如果不能剔除很多東西,使用這種方法權衡利弊

參考:

  1. Hierarchical Z-Buffer Visibility(Siggraph 1993)

  2. https://www.nickdarnell.com/hierarchical-z-buffer-occlusion-culling/

------wolf96  2019/9/15

 

 

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