研究地形渲染中——经过一番辛勤努力实现了QuadTree

来源:互联网 发布:弹出广告拦截软件 编辑:程序博客网 时间:2024/04/20 11:53

  从发上一篇文章搞出地形程序框架之后,就一直在看《Focus On 3D Terrain》的四叉树部分,感觉这个办法最经典最可靠,当然,顺应我的低智商,也最容易实现:D于是努力了两天,把QuadTree地形渲染给实现了,虽然时间不长,收获和启发还是不少。

  和那些CLOD,Geomipmap,ROAM相比,QuadTree的实现确实是比较简单了,对一个完整的网格进行四叉分割,选那些需要细化的地块继续分割,直到细节效果达到要求为止,最后画出来,大概的描述就是这样。具体实现还是有不少要注意的地方,数据和参数太多了,一不小心就错的很离谱。最后的实现是自己参考了很多资料独立完成的,感觉有不少细节都可以改进。有以下几点:

  1.看了《Focus On 3D Terrain》,作者是从整个地块开始分割的,判断摄像机所在的地块,然后用顶点距摄像机的水平距离和高度作为参数,整出了一个复杂的公式,作为判断是否分割一个地块的依据,我感觉这样计算实在麻烦了,把这个判断改为视距判断,直接计算地块中点到摄像机的距离,判断是否达到某个精度等级。这样的好处是地块细节的变化只和观察距离相关,比如视点在高空观察时(比如飞行或俯视的战略游戏),所有突起的山顶都会有高一些的细节,而不是只有摄像机下方区域有高细节。

  2.补洞。正好工作比较空闲,花了一天时间研究了各种填补裂缝的方法,期间除了这本经典著作,还看了叶志军的《Visual C++/DirectX9 3D游戏开发导引》(我学D3D的入门书),上了GameRes论坛,找到了程东哲牛人写的一篇《地形制作全攻略》,把《Focus On 3D Terrain》的重要内容都给表达出来了,最后还参考了一篇论文...3D开发行业真是遍地英雄啊,在这里要谢谢各位大师们献出好书好文指引我:) 讲一下补洞的心得,我是开一个char*缓存,每个char保存1个顶点的标记信息,对地块中心的顶点,用它保存地块的精度等级,一般不会太大(不会超过127吧?),对地块四边的4个中点,把它当做bool类型,需要分割一个地块时,就把这四个char置1,否则置0。因为任何等级的任何地块的中心点和四边中点永远都不会重复,所以这些数据也不会混乱,只要自己明白不同点的标记含义就可以了,这样在对低精度地块邻接高精度地块补点时,既得知邻接地块的精度,也得知邻接边的分割状况,如此补洞就没有难度了...是现在感觉没难度了,研究这些算法再实现可真是一件辛苦的事。

  3.优化递归过程。从设定的最低精度节点开始进行递归分割,而不是从整个根节点递归分割。整个地块相当于根节点,一直分割到达到相应距离上的精度停止。一般一个2^N密度的网格,渲染时允许的降级是不超过N,经常是比N小的多,比如256x256的网格,总的细节等级是8(2^8=256),一般设定最低精度是3-5,在最低精度为4时,最粗糙的地块是占16个单位的网格(2^4),此时没有比这再粗糙的地块了,所以不必从整个地形开始分割切,把256的地形分成N个16单位的最低精度地块(正好也是256个),然后分别递归细分。这样就省去了从第0层递归到第4层的处理时间。

  最后是测试。这次测试真的验证了我之前一篇文章的提到的预感,显卡性能的提高已经使LOD算法的优势不再明显了。在之前那个电脑上测试,PentiumD 2.8GHz CPU+GF-7300GT显卡,用了QuadTree算法渲染256密度的地形,由于CPU密集运算,运行时占用率不小于10%,这还只是在分割地形,没有其它交互应用,我觉得自己把算法优化了一些应该不会太浪费时间。而之前没有任何优化的256均匀网格渲染起来完全是显卡任务,CPU使用率经常是0%-5%,至于显卡是否增加负担看不出来,也许应该用PIX?无论怎样,在这个显卡技术日益上升的时期,多画几w个面对显卡没什么性能影响,对这种256地形网格到底该怎样渲染现在有了灵活的选择。

  对再大点规模的地形,使用LOD算法才有稳定的性能提升,后来换1024网格的地形测试,那个BruteForce就变成“幻灯片”了,而用5级QuadTree渲染可以保持二十多帧的速度。那以后就尽可能的画高密度的地形网格好了,不然自己的辛苦岂不是白费:D

  截了两张图,发到相册了。

  Terrain_QuadTree_256_FaceMode:真实效果

  Terrain_QuadTree_256_WireMode:线网效果(展示视距相关的动态细节)

原创粉丝点击