目錄譯者注:本文翻譯自Cesium官方博文《Graphics Tech in Cesium - Rendering a Frame》,May 14, 2015 by Patrick Cozzi,
- 設定
- 更新
- 潛在可見集合
- 渲染
- 排序和批處理
- 拾取
- 未來的作業
- 地面通道
- 陰影
- 深度紋理
- WebVR
- 立方體貼圖通道
- 后處理效果
- 計算通道
- 致謝
- 參考
本文通過追溯Cesium的Scene.render,解釋了Cesium 1.9如何使用其WebGL渲染器渲染每一幀,在Scene.render中放置一個斷點,運行一個Cesium應用,然后繼續,
由于Cesium專注于可視化地理空間內容,因此使用許多不同光源的場景并不常見,因此Cesium使用傳統的前向陰影管線(Forward Rendering), Cesium的管道之所以獨特,是因為它使用了多個視錐體來支持巨大的視距,避免造成Z-fighting現象[Cozzi13],
譯者注:正向渲染/前向渲染(Forward Rendering)與延遲渲染(Deferred Rendering)相對,延遲渲染多用于多光照的場合,參看《正向渲染和延遲渲染彼此之間有什么不同》,
設定
Cesium將具有幀生存期的常量存盤在FrameState物件中,在每一幀的開始階段,將使用諸如相機引數和仿真時間之類的值對其進行初始化, 這個FrameState對可用于其他物件,例如在整個幀周期中生成命令(繪圖呼叫)的圖元(primitives),
UniformState是FrameState的一部分,具有通用的預先計算的著色器uniform變數, 在每一幀的開始階段,諸如視圖矩陣和太陽光線矢量等uniform變數將會被計算,
更新
Cesium具有經典的影片/更新/渲染管線,影片步驟可以在不與WebGL互動的情況下移動圖元(primitives,Cesium表示可渲染物件的術語),更改材質屬性,添加/洗掉圖元等, 這不是Scene.render的一部分,它可能會在應用程式代碼中,通過在渲染幀之前顯式設定屬性時發生;或者可能會在Cesium中隱式地,通過使用Entity API分配時間變值觸發,
經典的影片/更新/渲染管線
Scene.render的第一步是更新場景中的所有圖元,
在此步驟中,每個圖元會
-
創建/更新其WebGL資源,例如,編譯/鏈接著色器,加載紋理,更新頂點緩沖區等,Cesium永遠不會在Scene.render之外呼叫WebGL,因為這樣做會增加requestAnimationFrame的耗時,并使其難以與其他WebGL引擎整合,
-
回傳一組DrawCommand物件的串列,這些物件可以表示成繪圖呼叫命令,并參考了由圖元創建的WebGL資源, 有些圖元(例如折線或布告板(billboard)集合)可能會回傳單個命令;而其他的圖元(例如Globe或3D模型),可能會回傳數百個命令, 大多數幀將是幾百到幾千個命令的,
Globe物件是Cesium的地形和影像引擎,可以看作是一個圖元(primitive),它的更新函式可處理多層級結構的細節和揀選,以及用于加載地形和影像圖塊的核心外記憶體管理,
潛在可見集合
揀選是圖形引擎常見的優化方法,能夠快速的消除視野外的物件;以便管道的其余部分不必處理這些物件,通過可見性測驗的物件就是“潛在可見性集”,并繼續沿管道傳輸,它們可能是可見的,因為使用了不精確的保守可見性測驗來提高速度,
Cesium通過使用commands的世界空間的boundingVolume(包圍盒)物件,來對單個命令(圖元,例如執行自己揀選操作的Globe,可以禁用此功能),自動執行視錐和水平剔除[Ring13a,Ring13b],
傳統的圖形引擎可以通過檢查每個命令(command)的可見性測驗來找到潛在的可見集, Cesium的createPotentiallyVisibleSet函式更進一步,將命令動態地分為多個視錐(通常是三個),它們將所有命令限制在一定的范圍之內,并保持恒定的遠近比以避免深度沖突( z-fighting),每個視錐體具有相同的視場和寬高比,只有近平面和遠平面的距離不同,作為一種優化,此函式利用時間相干性,并且如果對于該幀的命令仍然合理,則將重用最后計算的視錐,
左:多視錐體;右: 在視錐體中的命令
渲染
每個視錐體都有各自的命令串列,組成視錐體串列后,我們現在可以執行命令了——也就是執行WebGL的drawElements/drawArrays的呼叫,以下會順著追蹤Cesium的executeCommands相關的內容,因為這是Cesium渲染管線的核心,
首先,清除顏色緩沖區,如果使用了與順序無關的透明度(OIT)[McGuire13,Bagnell13]或快速近似抗鋸齒(FXAA),則它們的緩沖區也將被清除(有關更多資訊,請參見下文),
然后,使用整個視錐體(不是單個計算的視錐之一)來渲染一些特殊情況的圖元:
-
包含星星的天空盒, 老式的優化方法是先渲染天空盒,然后跳過清除顏色緩沖區的操作, 如今,這實際上會影響性能,因為清除顏色緩沖區有助于最大程度地壓縮GPU(與清除深度相同),最佳做法是使天空盒最后渲染以利用Early-Z,Cesium首先渲染天空盒,因為它必須這樣做,需要在每個視錐體之后清除深度(正如下面所描述的那樣),
-
天空大氣,來自[ONeil05]的基本大氣,
-
太陽,如果太陽是可見的,則渲染太陽的布告板(billboard),如果還啟用了泛光過濾器,則會剪掉太陽,然后幾個通道將會被渲染:對顏色緩沖區進行降采樣,變亮,模糊(分別在水平和垂直通道中進行),然后進行升采樣并與原始混合,
接下來,從最遠的視錐開始,按照以下步驟執行每個視錐中的命令:
-
視錐體特定的uniform狀態量將會被設定,這只是視錐體的近距離和遠距離,
-
深度緩沖區將會被清空,
-
首先執行不透明圖元的命令, 執行命令會設定WebGL狀態,例如渲染狀態(深度,混合等),頂點陣列,紋理,著色器程式和統一,然后發出繪圖呼叫,
-
接下來,執行半透明命令,如果由于缺少浮點紋理而不支持OIT,則將命令從頭到尾排序,然后執行,否則,OIT用于提高相交半透明物件的視覺質量,并避免排序的CPU開銷,命令的著色器針對OIT進行了修補(并快取),如果支持MRT,則通過一次OIT渲染進行渲染,或者作為后備通過兩次渲染,可以參閱OIT.executeCommands,
使用多個視錐會導致一些有趣的情況,例如如果命令重疊多個視錐,則命令可以執行多次,詳細資訊請參見[Cozzi13],
至此,每個視錐體的命令已執行,如果使用OIT,則執行最后的OIT復合通道,如果啟用了FXAA,則會執行全屏通道以進行抗鋸齒,
與平視顯示幕(HUD)相似,覆寫通道的命令最后執行,
Cesium當前的渲染管線,
排序和批處理
在每個視錐中,保證按圖元回傳命令的順序執行命令,例如,Globe從頭到尾對其命令進行排序,以利用GPU Early-Z優化,
由于性能通常取決于命令的數量,因此許多圖元使用批處理通過將不同的物件組合為一個命令來減少命令的數量, 例如,BillboardCollection在一個頂點緩沖區中存盤盡可能多的布告板,并使用相同的著色器對其進行渲染,
拾取
Cesium使用顏色緩沖區實作拾取,每個可選取的物件都有一個唯一的ID(顏色),為了確定在給定的(x,y)視窗坐標中拾取到內容,將幀渲染到螢屏外的幀緩沖區,其中寫入的顏色為拾取ID,然后,使用WebGL的readPixels讀取顏色,并將其用于回傳拾取的物件,
Scene.pick的管道類似于Scene.render,但由于例如天空盒,大氣層和太陽無法拾取而得以簡化,
未來的作業
關于一幀中進行的渲染作業,有一些正在進行中還處于計劃階段的提升,
地面通道
上面描述的Scene.render中的通道在圖形引擎中很常見:OPAQUE,TRANSLUCENT,然后是OVERLAY, 實際上,OPAQUE分為GLOBE和OPAQUE, 可能會對其進行擴展,以便其順序為:基本globe,固定在地面上的矢量資料,然后是一般的不透明物件, 參見#2172,
陰影
陰影將通過shadow mapping實作,從每個陰影投射光的角度渲染場景,并且每個顯示投射物件都有助于深度緩沖區或陰影貼圖,即從燈光角度到每個物件的距離,然后,在主色通道中,每個陰影接收物件檢查每個光源陰影圖中的距離,以查看其片段是否在陰影內,實際的生產實作非常復雜,需要解決鋸齒偽像,柔和陰影,多個視錐體以及Cesium的核心外地形引擎, 參見#2594,
深度紋理
添加陰影的一個子集增加了對深度紋理的支持,例如,可以將其用于針對地形進行深度測驗的告示板,并根據深度重構世界空間的位置,
WebVR
添加陰影的另一部分是從不同角度渲染場景的能力,WebVR支持可以基于此,標準相機和視錐用于揀選和LOD選擇,然后使用兩個偏心的視錐(每個眼睛一個)進行渲染,NICTA的VR插件使用類似的方法,但是使用了兩個畫布,
立方體貼圖通道
陰影的另一個擴展是渲染立方體貼圖的能力,即形成一個盒子的六個2D紋理描述了盒子中間某個點周圍的環境,立方體貼圖可用于反射,折射和基于影像的照明,立方體貼圖通道的使用代價可能會變得昂貴,因此我懷疑這將僅少量用于即時生成,
后處理效果
Scene.render具有一些后期處理效果,這些效果經過硬編碼,例如太陽泛光,FXAA甚至是OIT合成,我們計劃創建一個通用的后處理框架,將紋理作為輸入,通過一個或多個后處理階段運行它們,這些通道基本上是在視口對齊的四邊形上運行的片段著色器,然后輸出一個或多個紋理,例如,這將用驅動后處理框架的資料代替許多硬編碼的太陽泛光,并打開許多新效果,例如景深,SSAO,發光,運動模糊等, 請參閱這些說明,
計算通道
Cesium會使用老式的GPGPU來進行GPU加速的影像重投影,在該渲染程序中,它將渲染一個與螢屏視口對齊的四邊形,以將重投影推向著色器,這可以通過在幀開始時的計算程序中使用后處理框架來完成,參見#751,
潛在的未來Cesium渲染管線(新階段以粗體顯示),
致謝
我和Dan Bagnell撰寫了大多數Cesium渲染器,要獲得娛樂,請參閱我們的Cesium Wiki注釋, 當我還在讀高中時,Ed Mackey在90年代就在AGI進行了最初的多視錐體實作,
參考
[Bagnell13] Dan Bagnell. Weighted Blended Order-Independent Transparency. 2013
[Cozzi13] Patrick Cozzi. Using Multiple Frustums for Massive Worlds. In Rendering Massive Virtual Worlds Course. SIGGRAPH 2013.
[McGuire13] McGuire and Bavoil, Weighted Blended Order-Independent Transparency, Journal of Computer Graphics Techniques (JCGT), vol. 2, no. 2, 122–141, 2013
[ONeil05] Sean O’Neil. Accurate Atmospheric Scattering. In GPU Gems. Edited by Matt Pharr and Randima Fernando. 2005.
[Ring13a] Kevin Ring. Horizon Culling. 2013.
[Ring13b] Kevin Ring. Computing the horizon occlusion point. 2013.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/241273.html
標籤:其他
下一篇:Vue——監聽器watch
