探索未知種族之osg類生物---渲染遍歷之裁剪一

前言

上面我們用了四節課的內容,講解了一些osg概念性的內部原理。希望大家可以再看今天的講解之前先再仔細的研究一下前四節的內容。這樣你就會對整個osg的渲染過程有一個更加清晰的認知,有助於理解下面兩個函數cull()和draw()。

osg::Util::SceneView::cull()

好,相信大家已經又複習了上面幾節的內容,那我們就進行sceneView的第一個重要功能osg::Util::SceneView::cull()函數。場景的篩選函數 cull 主要完成了以下幾個工作。

1、通過_camera->getNodeMask()==0來判斷主相機下的根節點是否可見,如果不可見則不用進行cull操作。

2、進行視圖的渲染信息(_renderInfo)的初始化

3、通過updateUniforms();更新一些osg內設的 osg::Uniform 著色器變數(osg_FrameNumber,osg_FrameTime等)。因為opengl中Uniform表示這個變數可以被所有的shader訪問到,所以我們在編寫 GLSL 程序時調用這些變數獲取 OSG 提供的一些場景和時間方面的信息。

4、對篩選訪問器(_cullVisitor),狀態樹根節點(_stateGraph)和渲染樹根節點(_renderStage)進行初始化操作。

5、通過_displaySettings->getStereo()來判斷是否進行立體渲染(例如VR等),那麼此時 OSG 會針對左/右眼(osg::DisplaySettings::LEFT_EYE/RIGHT_EYE)以其它各種設置做出適當的處理,相關的函數包括 SceneView 類成員 computeLeftEyeProjection,computeLeftEyeView,computeRightEyeProjection,computeRightEyeView 等。這些就等我們研究到osg與vr(ar)結合的時候我們再仔細的研究

6、(不是立體渲染)進行普通渲染,通過cullStage進行cull操作。我們進入SceneView::cullStage內。

A、首先判斷camera中是否存在遮擋節點(OccluderNodes)如果存在,就會通過_collectOccludersVisitor->traverse(*_camera),根據投影矩陣(projection)、視圖模型矩陣(modelview)以及視口矩陣(modelview)來對場景圖進行遍歷,找到發生遮擋的位置(也就是得到被遮擋的節點)。將篩選所需的數據送入篩選訪問器(CullVisitor),包括篩選設置(CullSettings),狀態樹根節點(StateGraph),渲染樹根節點(RenderStage),渲染信息(RenderInfo)

B、設置狀態樹以及渲染樹構建所需的各種信息。例如viewport、ClearColor、ClearDepth、ClearAccum、ClearStencil、ClearMask、camera等,還要對全局狀態節點以及局部狀態節點進行默認設置(上一節說到過)。

C、如果camera中設置了CullCallback回調函數,那麼就要對攝像機下的所有節點都要進行遍歷,並且執行回調函數。如果沒有則使用篩選訪問器cullVisitor遍歷場景中的節點,在遍歷過程中將篩選出那些無法被用戶看到的對象(被遮擋的,以及超出視椎體的),並將它們裁減掉,從而提高場景繪製的效率。

7、進行完了cull操作後。先後「彈出」模型視點矩陣(所用函數為popModelViewMatrix,事實上只是彈出堆棧中的臨時數據,計算結果仍然保留,下同)、投影矩陣、視口矩陣,渲染狀態(使用 popStateSet))

8、依次對篩選訪問器執行之後得到的渲染樹內容進行排序RenderStage::sort和精簡StateGraph::prune(構建過程中可能有些空節點需要剔除)

9、最後,計算出場景中動態對象(DYNAMIC)的數目,並保存到 SceneView 的成員變數_dynamicObjectCount 中

10、返回結果computeNearFar。

接下來我們將要深入osgUtil:: CullVisitor類,進一步研究裁剪操作。

原文鏈接 探索未知種族之osg類生物---渲染遍歷之裁剪一


推薦閱讀:

TAG:3D渲染 | 三維GIS |