對數深度緩衝

2022-04-29 13:51:06 字數 1598 閱讀 4103

在超大型場景下,遠*裁剪*面一半要很遠的距離,使用普通的深度緩衝經常會因為誤差,造成一些很難看的鋸齒,本來不相交的圖元相互穿透,z-fighting等現象。

普通的z/w深度緩衝,深度值不是線性的。在*處,深度比較精確,所使用的深度區間也比較大。在遠處,僅會使用很小一部分深度區間,誤差就會變得很大,產生難看的現象。

例如,在*裁剪*面為10,遠裁剪*面為10000時:

zz/w深度

90.09009

0.900901

490.4905

0.980981

990.991

0.990991

10000

1.0可見*處的所用到的區間大,90以內的就用了0-0.9,越遠越小,精度越低。

一種辦法就是將深度轉化為線性的,在d3d中用shader自己算乙個深度。

由於z最終會被除以w,所以,可以在vs中,完成worldviewproj之後,先對z上乘以w,等最後被除以w的時候,就相當於什麼事情也沒有發生。

當然,也要除以遠裁剪*面距離。使深度值對映到0-1之間。也可以通過修改投影矩陣來完成。

線性的深度分布,會使遠處和*處的精度一樣。即傳說中的w緩衝。在超大場景下,遠處就沒有那麼多鋸齒了。但是,這樣有時候,*處的精度就會不足。

還有一種辦法就是在vs中用對數計算深度。

公式z = log(c*z + 1) / log(c*far + 1) * w

其中,c是常量,不同的值,會影響深度的精度。

在z處的解析度為

log(c*far + 1) /  (2^n * c/(c*z+1))

一下是乙個參考的精度表,使用24位深度緩衝,遠裁剪*面10000km110

1001k

10k100k

1m10m

c=11.9e-6

1.1e-5

9.7e-5

0.001

0.01

0.096

0.96

9.6c=0.001

0.0005

0.0005

0.0006

0.001

0.006

0.055

0.549

5.49

使用對數深度問題是深度是被線性插值的,而不是對數。所以網格必須足夠精確……或者直接在ps中算深度,不是很費效能,如果可以接受的話……

這種辦法效果非常好,做真實比例的星球系統沒啥問題。

使用這些非標準的深度,雖然效果好,但也是有壞處的。

首先,普通z/w深度,在螢幕空間是線性的,如圖所示:

這是使用ddx和ddy對z/w深度求的導數圖。

由顏色相同可以看出,深度是線性的(在螢幕空間)。原始為無損png,可以用畫圖顏料桶測試顏色是否相同。

對線性深度使用相同辦法,效果如圖。

可見是非線性的。

這對於一些基於螢幕空間深度的post effect來說不利。例如ssao,hdao,景深等。

深度緩衝區

深度緩衝區是direct3d用來儲存繪製到螢幕上每乙個畫素點的深度資訊的 塊記憶體緩衝區。它為每個畫素儲存乙個深度值 z值 這個深度值是從攝像機到對應該畫素點的頂點之間的距離。深度緩衝區的大小和顏色緩衝區 frame buffer 的大小一致。例如 如果要繪製乙個640 480解析度的,則在深度緩衝...

反向Z Reversed Z 的深度緩衝原理

參考文章 在數學中,與浮點數對應的是小數 數學上區間 0,1 之間的小數有無窮多個 計算機中,32位浮點數最多可以表示2 32個數 所以,計算機是不可能描述得盡的,必然會有一些近似,一些精度所示 當前,計算機中浮點數採用的是ieee 754標準。浮點數分為單精度浮點數 32位 和雙精度浮點數 64位...

深度緩衝中的深度值計算及視覺化

在渲染管線中的頂點變換中,介紹了頂點在各個座標空間的變換。變換到最後,是螢幕座標空間。在opengl中,螢幕空間座標的z值即是深度緩衝中的深度值。深度緩衝包含了乙個介於0.0和1.0之間的深度值,它將會與觀察者視角所看見的場景中所有物體的z值進行比較。本文將介紹深度值的計算,以及從深度值反向計算出相...