導語
Cesium 的渲染引擎是基于高精度渲染設計的,不過,就算是以米作為單位的常規游戲引擎,也會遇到精度問題,例如 z值沖突 和 抖動,
z值沖突是指兩個三角形接近時,有重疊的像素,但是深度快取的精度不足以確定哪一個三角形更接近相機,當視圖發生變化時,這些重疊像素會閃爍,
之所以會發生 z值沖突,是因為深度快取的精度 與 深度的倒數成正比,意味著越靠近截平面的三角形繪制精度越高,越遠則越低,
這里有一個動圖,顯示了相機在 WGS84 橢球上方約 8000 米觀察的地形發生的 z值沖突:

z值沖突的兩種解決方法:使用多視錐體、使用對數深度快取,
在 Cesium 1.45 版本中,Cesium 混合了這兩種技術以替代原來單一的多視錐體技術,
這么做的好處顯而易見:
- 更好的性能:減少了 drawcall
- 更好的視覺效果:可以在不影響性能的情況下將近平面盡可能移動得近一些
1. 多視錐渲染技術
Cesium 原來的多視錐體實作是使用 3 個視錐體,其分割距離分別是 [1, 1000],[1000, 100w], [100w, 10e] 米,
這些視錐體從后到前(相對于相機)的順序進行渲染,并且在每個視錐體中深度快取被清除,
渲染開始時,根據繪制命令(DrawCommands)的包裹范圍(boundingVolume),將繪制命令放置在一個或多個圓錐體中,
在兩個視錐邊界的繪制命令則兩邊都會繪制一次,為了優化這個重復繪制,Cesium 從視點觸發,根據最近和最遠的包裹范圍計算合適的近平面和遠平面距離,以最大程度減少視錐,(這句話翻譯得不太好,專業名稱比較多),
下圖是珠穆朗瑪峰的近地視圖:

將每個視錐分別著色后的樣子(第一個視錐是紅色,第二個視錐是綠色,黃色介于第一個和第二個視錐中,這里看不到第三個視錐):

下圖是一樣的地形場景,只不過把視錐體顯示了出來,第一個視錐(1~1000米)太小了這里看不到,

在這個場景下,有 137 個 drawcall,第一個視錐有 28 個,第二個視錐有 102 個,第三個視錐有 7 個,重復呼叫數有 26 個,第一個和第二個視錐之間的重復呼叫占 12 個;在所有視錐體中都重復的呼叫有 7 個,
2. 對數深度快取
z值沖突的另一種解決方法是使用對數深度快取技術,
將對數值輸出到深度快取,可以很好分配這些數值,Cesium 更新了頂點和片元著色器以支持對數深度快取,
關于對數快取技術,可以參考三篇博客(在國外國內訪問不了)
-
Maximizing Depth Buffer Range and Precision (outerra.blogspot.com)
-
Logarithmic Depth Buffer (outerra.blogspot.com)
-
Logarithmic Depth Buffer Optimizations and Fixes (outerra.blogspot.com)
對上述的場景使用對數深度快取,近平面為 0.1,遠平面為 1e8,只需一個視錐體,一共 111 個 drawcall,
這么做不僅可以減少 drawcall,而且默認情況下,近平面更接近相機,從而可以近距離查看,
對于多個視錐體,這并非不可實作,但是可能會有性能問題,只用一個視錐體,使用對數深度快取,可以減少將繪制命令分配給每個視錐體的 CPU 計算量,
視錐上清除命令和全屏掃描命令可能比較少,對數深度快取消除了視錐邊界處的奇怪問題,對后續開發的新功能(后處理、貼地線)會有幫助,

這是一張拖拉機的輪子,近平面為 1 米,

當近平面距離為 0.1 米時,輪胎看起來就比較完整了,
簡而言之,對于只有地形瓦片的視圖,洗掉重復的 drawcall 為 10~30個,對于 3dTiles 或 BIM 模型來說,能減少 20~40 個 drawcall,
在片元著色器中,覆寫平面很大一部分的三角形的深度資訊將被寫入深度快取,在頂點著色器中計算、插值得來的對數數值可能并不是對的,對數深度快取的典型優化方法是僅修改頂點著色器、僅修改接近相機的三角形的片元著色器兩種,
在片元著色器中寫入片元深度值會導致 GPU 的深度檢測被禁用,而在 Cesium 中是不可能的,因為存在一種情況:可能存在覆寫螢屏但是不靠近相機的三角形,例如覆寫整個陸地的超大多邊形,所以,瀏覽器得支持 EXT_frag_depth 這個 WebGL 擴展,才能在片元著色器中寫入片元深度,才能利用這個功能,否則 Cesium 仍會使用舊的多視錐體技術,
雖然 Cesium 中的大多數視圖僅需要一個單個對數深度的視錐,但是也有例外,一個極端的例子是,在非常遙遠的距離觀察一個很大的三角面,
下例是一個極端情況,即這里有兩個超級大平面,和地球切面差不多,它們尺寸是一樣的,但是空間距離上只差 300 米,但是相機到觀察目標的距離有 6400w 米,

對于上面的視圖,可以預見,幾何圖形在三角面距離比較遠時仍然可見(例如行星),三角面比較靠近的,則看不到,例如衛星,為了解決這個問題,Cesium使用了一種混合技術,在多個視錐體中,每個視錐都使用對數深度快取,減小 Scene.logarithmicDepthFarToNearRatio 的值,就會增加視錐體的個數,然后減少z值沖突,
*譯者注
簡而言之,配合對數深度快取技術和原來的多視錐體技術的靈活搭配使用,減少 drawcall,提升性能,提升顯示效果,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/228811.html
標籤:GIS
上一篇:Cesium中的圖形技術:Primitive API 高級
下一篇:匯聚視頻,看起來很簡單...
