Isometric Tile

东学学,西学学了半天,这次学回到老本行了。

Isometric Tile,45%俯视视角。

实现的过程中,在显示对象的深度排序上花了不少的时间,最终确定的方案是逐帧更新对象的深度依赖。这样一来,整个显示列表的移动物体比例小于50%,就能达到优化的效果,如果都是静态场景,那么每帧的深度排序时间几乎是没有的,因为只有在第一帧才会计算深度依赖。

 

说说我的渲染流程:

可见对象检测 --> 计算深度依赖 --> 渲染

 

可见对象检测:

  使用四叉树,考虑到移动对象,每帧都会有插入、移除的操作,而且由于要缓存深度依赖,子节点的AABB不能交叉,实现又简单,就用了这个方法。在计算可见对象时,生成一颗子树,将不需要显示的节点进行截枝。为了方便,我在四叉树节点上增加了一个Bool值,标示是否需要显示,快速计算出树形的显示列表。

计算深度依赖:

  使用之前计算好的显示子树,计算每个需要显示的对象的深度依赖,找出对象遮挡的关系,纪录对象之间的遮挡关系,借助四叉树,可以有效减少遮挡计算次数,大大提高效率。

渲染:

  根据计算好的深度依赖,拓扑排序的同时将对象渲染到屏幕上。

 

依赖关系缓存优化:

  如果整个场景的物体不多,那么每帧都进行一次深度排序也是可以的,不过如果场景中的静态物体不少,那么选择将深度依赖关系缓存起来是一个不错的选择。无论是否缓存深度依赖关系,以上的流程都是适用的,只有一些小区别。

  首先,如果不缓存深度依赖关系,那么在计算深度依赖时,只需要计算需要显示的对象之间的深度依赖,若要缓存,那么计算深度依赖时,需要将场景中被当前对象遮挡的所有对象都找出来,不过幸好,有四叉树在,找出所有可能被当前对象遮挡的对象不困难(被遮挡的物体只可能在自身所在节点以及子节点族中)。

  然后,缓存深度依赖关系需要增加一个标识位,标示需要重新计算深度依赖,对象移动之后需要重新计算深度依赖。

  还有,不缓存深度依赖,计算深度依赖时只需要保存被遮挡的关系,既A物体遮挡了B,我们只需要纪录A遮挡了B,而不要纪录B被A遮挡了,而缓存深度依赖,则要将两者都纪录下来,为了在重新计算深度依赖时删除旧的关系。

  最后,如果场景中的活动物体不多,那缓存深度依赖提升的性能那是刚刚的,即时场景中所有物体都在移动,损失的性能大概是不缓存的20%左右(我的测试可能不够准确)。

posted @ 2013-10-15 12:08  JasonZXX  阅读(534)  评论(0编辑  收藏  举报