游戏人生

不积跬步,无以至千里;不积小流,无以成江海。

导航

引擎设计跟踪(四)

最近主要目标是做地形画刷.但是准备工作太多,只能一步一步来.目前加上了射线查询和地形的三角形集合的相交查询,主要是为了做贴花,这个是画刷显示的时候必须有的东西. 
关于地形的贴花,可以一直multipass,再画一遍,加上depthbias,使用画刷贴图做纹理投影就可以了,比如Ogre的Ogitor就是这么做的,
这样搞对于编辑器没什么问题,足够了.但是对于游戏中使用的贴花来说,最少要一个地形块多渲染一次,感觉太耗了.所以才想用地形三角面查询,只绘制需要的少量三角形就可以了,这对于游戏(而非编辑器)来说更好点.

至于射线查询,由于有了空间管理,所以找到与射线相交的三角形和点不难.而三角形集合相交的查询,要找到bounding volme内部的所有三角形,由于空间管理只定位到一个小地形块(假如类似WOW那样的,一个大约16x16的最小单位)那么这个块的三角形数量还是很多的(实时特效,不只一个贴花啊,可能有N个,比如战斗时),如果贴花在四个块的相交中心位置(一个"田"字的中心",那么可能同时占据了块,如果直接渲染,还是觉得可惜.所以想找到指定volume内部的三角形. 虽然对于现代GPU来说,渲染这点三角形没什么压力,我还是想尽量减小渲染负担.不过自己也不知道值不值..

方法是块内部三角形查询使用四叉数.(这个四叉数跟空间管理无关,空间管理可能是Octree或者Quadtree).
在使用了空间管理,找到对应的块之后,再使用块内部的四叉数结构找到相应的三角形集合,比如一个16x16的地形块,大概分到3-4级的四叉数就可以精确定位到三角形了.

遇到的问题是,地形块有不同的LOD,那么每一级的LOD,都对应有不同的三角形分部.现在的做法是,要建立所有LOD级别所对应的四叉数划分,然后运行时,根据当前的LOD级别,选择对应的四叉数.
这么做导致的问题是,内存使用量急剧上升.原来没什么东西100M左右,添加了这个功能之后内存达到了200M.这个是数据量确实很大.32x32的一个小块,细分到2x2的叶子,那么就有16x16个叶子,一个512的地形,就有256x256个叶子,再加上非叶子节点,还有不同的LOD,还有如果考虑3x3x512的大无缝,又要翻9+倍.....确实很吓人.
目前的解决方法是优化内存使用量.把内部四叉数的数据压缩,比如AABB本来是直接存储,现在改成动态生成,还有四个子节点指针,改成了索引.
 

class BlockQueryData
{

BlockQueryData
* mSubLeaf[4];
AxisAlignedBox mLocalAABB;
};
//40字节

//改成这样:

class BlockQueryData
{
//所有节点在数组中存放,一个节点的四个叶子的内存是连续的.
//这里存储四个连续索引值的第一个值
uint16 mSubLeafIndex;
//下面用于运行时构建AABB
uint16 mX;
uint16 mZ;
uint16 mSize;
fp32 mMinY; //float
fp32 mMaxY;
};
//16字节

  这样,这部分的内存使用量从90多M下降到了30多M,基本可以接受了.

目前的更新主要做了以上.也加上了DInput的支持,由于UI配置的机制是自己遍历工厂的可用对象,然后显示到UI列表,所以添加DInput代码之后,直接可以通过界面来选择,不用改UI的代码,现在真的感觉到爽了.扩展确实很方便的说.呵呵
还有UI界面的修改,比如所有的Toolbar和menu的图标都使用了直接渲染,而不使用MFC的默认方式,因为PNG的半透明,在MFC下转成ICO之后,羽化的边缘可能就没有了,直接空了,可能是残缺的.而且MFC自动转化出的灰色图标(Disable状态的图标)会有残缺,很郁闷,所以就改成直接用GDI+做了,效果还不错.图标尺寸也从16x16改为32x32了.不过这个由于之前的预留,支持多种大小的图标(16,32,48),所以只再创建的时候改一个参数就可以了,以后考虑加上用户运行时选择(像IE那样可以选择工具栏图标大小)不过这个...虽然更友好,但是对于我来说,有点偏离主题了..因为咱主要还是想学习渲染的说...

现在的工具系统的结构已经具备了一个雏形,有了toolbar等等,画刷也显示了.下一步准备加上工具栏按钮的右键点击配置(像UE的编辑器那样),主要是画刷的选择界面,还没有UI.准备写一个MediaLibrary来供用户选择Mask画刷等等(包括以后的texture,可能还有声音什么的,等等),这个界面要写完,才能开始画刷的计算,不过操作逻辑也有了,就差顶点的计算和更新了. 顶点的更新机制也需要考虑一下下...还有UI,想改成4视图的multi-view,同时把多窗口的MDI改成Tabbed风格(像VS的那种)不过这个也得等到后面看看再说吧,没有太多业余时间啊...UI的工作量确实很多很繁琐..暂时不考虑实现了.真的想考研了,呵呵.
..
然后下一步的目标是地形的贴图画刷,基本的逻辑都一样,所以尽量写的可复用,除了计算的对象从顶点/VB改为贴图的blend weight/blend texture.再然后呢....学习模型和动画,包括模型格式的设计.或者先给地形加上法线计算(放在编辑器端的逻辑部分),同时加上灯光对象(渲染系统太简陋了,目前没有Light),给地形打光... 这个是目前的计划.策略就是纵向和横向轮流搞,自上而下和自下而上轮流搞吧,这样才能尽可能及时的找到更多的问题,便于调整架构.不管怎么搞,个人对于图形学还有架构设计,都是有很大学习空间的.


最后来一张图吧... 用fraps显示的FPS,实在没时间写这些了.看到FPS,我又想到了一个问题,debug模式下挺好的,FPS比较稳定,二三百吧(下图).但是release下,稳定在1000,但只要鼠标一直移动,那么FPS就降到了30-90...发现是MFC的OnIdle太消耗的问题(因为注掉这一句就稳定了),网上搜了很多,但是目前没有太好的解决方案..这个mark一下,有空了再看看.

另,程序中使用的ICON都是网上搜到的,有的自己又PS了一下...,只是个人测试用的.还有上次一个哥们儿说到基于深度的贴花,我还没有想过这种方法,有空了也考虑考虑..

posted on 2011-08-20 02:26  crazii  阅读(602)  评论(11编辑  收藏  举报