基本上是《3D Game Engine Architecture》第3章的剩余内容,说实话我有点后悔看这个了,应该直接看《3D Game Engine Design 2nd》,不过好歹记录一下,有些“亮点”我第一次看到还是不错的。
主要包括global state, lights, texture, effects
每种state都是集成自GlobalState的一个类,比如ZBufferState
每个Spatial拥有一个 global state列表,列表里每种global state只能有一个。Spatial的global state列表不是直接用来渲染的,后面还要通过UpdateRS来沿着tree收集所有的global state,最终给Geometry使用。Geometry类里面有一个global state数组,维数为global state种类数目。(UpdateRS机制后面说)
Light 类继承自Spatial,没啥可说的,都是光源的属性。不过WM3中,AMBIENT也算是一种光源,和平行光,点光源等并列了,我们知道在OpenGL 中是可以设置一个场景的ambient的,WM3中的这种光源是否就是场景ambient,如果是,只能有一个吗?
和global state一样,每个Spatial也拥有一个Light列表,Geometry类有一个使用到的Light smart ptr数组,其实是指向挂在scene tree上的那些light的。
WM3的texture类中封装了如下内容:
基本上他封装了所有纹理相关的内容了
这个Effect包含顶点色数组(RGB or RGBA),一组纹理的smart ptr, 一组uv坐标
WM3 可以scene grapha的各个节点上挂接渲染状态和灯光(上面说的global state和light),而只有叶子节点也就是Geometry使用渲染状态和灯光,通过UpdateRS,将每层挂接的global state和light向下传递,对于同类型的global state,子一层的设置会屏蔽上层的设置(每种state都有一个stack,遇到设置该state就push进去,最后使用的是pop出来的,也就是 最后一次push的,显然是最后一次设置的状态),到叶子节点也就是Geometry这儿,将各类状态stack的top pop出来存放到Geometry的global state数组中,供渲染时使用。
这儿还有另外一个问题,引发UpdateRS的那个节点,需要向上直到ROOT收集渲染状态和灯光,而所有的状态都有一个默认值。这是通过PropagateStateFromRoot实现的。
所有这些状态和灯光都是shared ptr,所以WM3里面,只有状态被添加或移走时才需要更新RS。
关 于这些,我不想多写了,看代码一目了然,而且我想知道WM4里面是怎么弄的了。不过这种基于scene grapha的渲染状态树我之前没见到过,irrlicht中,每个需要渲染的节点是自己设置这些状态的,driver层会设置默认状态。WM3这种机制 有什么好处还要看看~
1)首先camera会有个culling操作,基于bound volume,这儿有两个东西有点意思:
2)scene渲染:这块儿没怎么看了,准备直接看WM4的,大概就是一个OnDraw和一个Draw, onDraw里面检测culling,并且调用draw, 而draw对于spatial是一个纯虚函数,Node的draw会调用子节点的OnDraw形成递归,Geometry的draw直接调用 renderer的draw(Geometry*),这里面会设置当前使用的geometry和effect,调用DrawPrimitive去执行。当 然这儿还有一个所谓DrawDeferred,后面才讲不知道是什么。另外还有所谓global effect被设置时,node会直接调用draw。
DrawPrimitve里面就是: