4.1 scene graph构建的基本问题

一,概述

Scene graph 的目的是组织物体。

两个原则: 1 。空间从属关系(树)

           2 Render State 的相似性。

原则一是为了快速剔除大批不可见物体。

原则二是为了减少 RenderState 的频繁改变。

二者均可使游戏速度大大提高。

原则一通过空间划分实现( bounding volumes ),原则通过排序实现。

然而两个原则是互不兼容的。若按 RS 排序,物体必然会分散于各个空间。理论上讲,两个原则那个更快就以那个为排序标准。

事实上 通常以原则一为准,即先将所有物体按空间从属关系分块,确定出可见物体后,再按 RS 排序。

扫描二维码关注公众号,回复: 2955396 查看本文章

以下为 scene graph 管理系统的宏观结构:

                       更新 Geometric State

              (如顶点数据,变换,空间从属关系等)

                             

                       更新 Render State

               global state lights effects 等)

                               

                        剔除不可见物体

                              

                      绘制(调用渲染系统)

                              

                         用户作出反应

                              

                   应用程序,回到初始循环。

WM4 中, culling pass drawing pass 完全分开,便于多线程渲染。

二, scene graph 的几个核心类。

关系: Geometry 派生于 Spatial Node 也派生于 Spatial Spatial 基于 Object

 

Spatial 类中封转了 local transformation world transformation world bound 等等。

对以上三个名词的解释:

1.  世界空间中有一个房间,房间里有一个桌子。将桌子摆到房间里的变换为 local~

2 .将房间摆到世界空间中的变换为 world transformation 。同时,桌子也会进行 world transformation

3 每个物体都有自己的 local bound (基于物体坐标系),进行 world transformation 后, local bound 的位置,大小,形状都有可能变化,变化后成了 WORLD bound

 

Geometry 类中封装了所有的物体属性( position,index,color,texture coordinates,scale factor,local bounding volume,normals 等等)

local bound ,其余属性都被封装在 VertexBuffer IndexBuffer 中。

另外,光照通过将 Light 类关联到 Geometry 实现(在 Geometry 类中存储一个 Light* ), local effect 通过将 ShaderEffect 类关联到 Geometry 实现。 Global effect 通过将 Effect 类关联到 Geometry 实现。

 

Node 类封装了对物体的组织函数,具体完成如下功能:

1.  在向下遍历中,先计算父节点的 world transformation ,再利用此 world~ 与子节点的 local transformation 相乘得到每个 child worldtransformation

2.  向下遍历结束后,每个 geometry 会利用计算好的 world transformation local bound 相乘得到 world bound

3.  向上遍历中,利用每一个 child world bound 计算父节点的 world bound

注:

Node world bound 乘以 world transformation 的逆变换可得 node local bound ,但用处不大,所以未能支持,需要时实时计算即可。

Node world bound ,但没有 model bound ,因为它只管理物体,本身并不是一个物体。

每个 Geometry 都有自己的 world transformation world bound

 

 

三个核心类之间的关系:

Geometry Spatial 的基础上增添了物体的所有属性和 local bound

Node Spatial 的基础上增添了向子节点的链接以及对物体的管理方法。

如此一来, Geometry 只负责物体本身, Node 只负责对物体的管理,使两个截然不同的概念相互分开,方便了代码的维护与扩展。

 

注:一种更简洁的设计方法是只创建一个类 Node ,它既负责物体属性,又负责物体组织,这样做使场景图更加简洁,代码也更易于使用,但增加了代码维护和扩展的难度。

 

三,关于 sharing object

共享类的目的有二:

(1)       节省内存,避免了大量数据的复制。

(2)       节省美工工作量,避免特意制作世界中的每一个物体。(当然,不能有太强的重复感。)

  但本 scene graph 并不支持 Node 类和 geometry 类的共享,即每一个节点只允许有一个父节点,但可以有多个子节点。因为如果支持多个父节点,代码开发难度会很大,详见 p230-232 。实际上,本 scenegraph 仍支持共享,不过是底层的共享,也就是说对 VB IB 的共享。

 

四, Controller 类和 Modifiers

Controller 是一个抽象类,它的作用是实现动画;而 modifiers 是对一系列类的统称,它的作用是提供物体属性的附加信息,因此, modifier 通常由 Geometry 派生而来。

 

Controller 的分类:(详见 5,7 章)

(1)       keyframe controller :用于关键帧动画。美工提供一系列关键帧(物体的位置和朝向) ,controller 对其进行平滑插值形成流畅的动画。

(2)       inverse kinematic controller :用于自动动画,例如人物去拿杯子, controller 便会计算出相应的位置和朝向,控制人物的动画。

(3)       vertex and normal controller :用于网格分解。

(4)       Render state controller :用于某些特效,如动态纹理。

(5)       Index controller :用于 LOD

基本思路是面向对象编程中的 open-close 原则。

Controller 是一个核心类,基于此派生新类以添加新的特性,但核心架构不发生变化这样易于维护和扩展。

猜你喜欢

转载自blog.csdn.net/huazai434/article/details/5970369