基于LOD的大规模真实感室外场景实时渲染技术的初步研究(转载)第一部分:简介室外场景的实时渲染技术是游戏编程世界中的热点技术.同时它在其它领域也有着同样重要的作用。如GIS系统,飞行模拟系统,VR系统以及数字地球技术等都离不开室外场景的实时渲染技术。一个优秀的室外场景实时渲染技术在保证实时性以外还能创造出非常逼真的、有说服力的虚拟自然环境。如NovaLogic公司的著名的3D射击游戏DeltaForce系列,它除了能模拟出各种如雪地、草地、沙漠等地形以外,还能模拟出各种树木,杂草,以及各种天气效果。室外场景的实时渲染有许多技术上的难点,在以下的章节里我们将作详细的介绍以及针对一些主要问题的解决方案。本文的主要内容分两个部分:一、大规模地形的渲染。二、如何提高场景的真实性。分别第二部分和第三部分。3D场景的渲染离不开3DAPI。目前流行的3DAPI有两种,SGI公司的OpenGL和微软公司的Direct3D。两种API各自有自己的优点,均能很好的使用硬件加速功能。但是OpenGL是一种开放性的标准,有更好的移植性能,它能在Linux和FreeBSD下工作。甚至还可以使用硬件加速(nVidia公司专门为Linux/FreeBSD推出了驱动程序)。因此在本文里,我使用了OpenGL。不过如果熟悉原理,其实也大同小异,D3D到8.0以后做的非常的像OpenGL.第一章:大规模室外场景渲染技术简介第一节:室外Vs.室内下面我们把室内场景和室外场景做一个对比,来看看室外场景的实时渲染的主要难点。目前最成功的商业室内游戏引擎有Quake/DOOM系列、Unreal系列引擎。他们都基于BSP技术的。通过BSP技术,再加上PVS,Portal等技术可以大量减少场景的复杂程度,通过Portal技术甚至可以把一个室内场景和一个室外场景连接起来,关于室内引擎的渲染的进一步已经超出了本文的范围。我们知道,当我们站在一个房间里的时候,我们能欣赏到的景物不过是这个房间的摆设以及透过这个房间的门和窗能看到的景物而已。你只能在墙壁的约束范围内走动。换句话说,我们处在一个有限的空间内。我们有足够的理由阻止人们穿过墙进入墙外的世界,也有足够的理由把视野约束在高墙以内。图(1-1),一个典型的室内场景,使用idSoftware的QuakeIII地图文件,用的程序渲染但是,这些约束在一个室外的场景中都是不可能的。在一个飞行模拟器中,理论上你可以驾驶飞机朝任何一个无限远的飞去。因为事实也是如此,如果你愿意的话,你可以驾驶飞机绕着地球飞行而不用担心有墙来阻止你的前进。换句话说,一个室外场景的理想大小是无限的大!除了场景的大小以外,同时视野也是无限的。如果你站在高处,你可以俯视任何比你的底的地方,也就是说你有几乎无限的视野。图(1-2),典型室外场景,图片来自北航王正盛的Demo:NatureWing2.0截图我们知道,无限的大的场景需要无限的场景数据。但是这是不可能的,我们只能希望场景越大越好,室外场景的主要部分是地形的渲染,地形数据的多少决定了场景的大小。所以如何保存这些地形数据成了首要的问题。(但是在现在存储器成本迅速下降的今天,这个问题已经变的不是十分的突出。)其次是无限的视野问题,无限的视野就表示渲染无限的图元(图元即是3DAPI支持的简单的几何图形,详见OpenGL/Direct3DSDK),这也是不可能。图元的数量是以场景大小的平方的速度增长的。光考虑地形数据,一个2048X2048的地形,如果不考虑减低细节程度和裁剪的话,它将要渲染8M的三角形,这样的三角形量在PC级别上目前还是远不能实现交互式帧率的。所以,如何减少要渲染地形时候的图元数目成了室外场景实时渲染的关键问题。其他的情况还有如野外的地表衍生物:树木、杂草、地貌等。同时天气效果,如下雨、下雪,刮风和闪电等.这些东西在一个室内的环境下基本上是不需要考虑的。而且模拟这些效果都需要很高的代价,有些甚至根本就没有办法模拟。第二节:VoxelVs.LOD综上,我们知道,室外场景实时性渲染的关键地形的渲染。我们需要一种技术来降低地形渲染的开销。目前的地形渲染技术主要有两种Voxel和LOD,下面我来做个简单的介绍。Voxel也就是VolumetricPixel。也就是所谓的“体素”,它是相对于像素来说的,如果说像素是一个二维的矩形的话,那么Voxel就是一个三维的立方体。它的原理是比较简单的。JamesSharman自称他在1995年时就想出了这种方法。前面的提到的DeltaForce游戏就是使用了Voxel技术。关于Voxel的细节技术不是本文的重点,我不准备做深入的介绍。Voxel有一个天生的优点就是渲染的时候它和场景的大小没有关系,而且绝对不会渲染多余的东西(自带裁剪功能)。它的复杂度只和我们需要的视野,以及分辨率有关。而且可以在不使用硬件加速的情况下达到比较理想的速度(DeltaForceI就没有使用硬件加速),生成的图象也比较的细腻。它的缺点就是不够的灵活。LOD也就是层次细节(LevelofDetail)的简称,不同于Voxel技术,它是一种使用多边形的,真正的3D渲染技术。它根据一定的规则来简化物体的细节,我们可以根据需要来选择不同细节程度的物体表达方式。如离观察者近的选择较高的细节程度、反之选择较底的细节程度。用在地形渲染中,有时我们也称它为多分辨率地形(Muti-resolutionterrain)渲染技术。图(1-3),基于Voxel的渲染场景,图片来自中国游戏开发者网络,陈鹏《自己动手编Voxel3D引擎》图(1-4),基于LOD的渲染结果,图片来自本文的Demo:Sim-Nature.LOD算法处理起来比较复杂,但是它让我们可以足够自由的去控制我们的场景渲染,更加方便的使用显卡的硬件加速功能。而且可以很容易的在场景中组合其他的物体。如树木,太阳以及粒子系统等,天空如它可以方便的让观察者以任意的角度去观察场景,我们只要让摄影机旋转一定的角度就可以了。但是这在Voxel中是比较困难的,因为Voxel在处理非水平的视线的时候非常的麻烦。LOD技术是本文将要使用和实现的地形渲染技术。图(1-5),经过LOD处理的地形网格,有不同的细节。图片来自本文的Demo:Sim-Nature.第三节:动态地形Vs.静态地形地形的渲染通常分为动态和静态的两种。静态的地形的细节可以是均匀的,也可以是不均匀的。但是细节通常在事先就计算好了,不均匀细节的静态地形有许多的优点:如平原的地貌可以使用较底的细节,而起伏频繁的地方使用较高的细节等级。更为直观的一个例子是赛车一类的对可以到达地方有一定限制的应用,我们可以在离赛道近的地方建立起比较高的细节等级,而在较远的地方使用较少的细节。用这种方式也可以建立起不规则的地形。比如说,它可以沿着赛道的方向建立起一个地形模型,这样可以节省大量的空间。动态的地形是视点相关的。它是本文将要采用和实现的方法。随着视点的移动,地形网格将被更新。相对于静态地形来说这是一种更为先进的算法。这种方式建立起来的场景更加符合人的视觉特性,即看到的细节是变化的。动态地形网格的建立和更新要耗费额外的时间,但是这种开销是值得的。动态地形网格的建立是比较复杂的,它需要注意很多东西:如何决定细节,如何避免裂缝是两个主要的问题。同时它还应该把不可见的地形部分切除,几何形变(随着细节改变,地形表面的呼吸现象)也应该被考虑到。这些问题都在以后的章节被详细的讨论到。第四节:其他我们说过,在一个室外场景的渲染中。除地形以外其他的一些元素也是十分的重要的,这些元素可以提高场景的真实性。本文将实现其中的一部分元素,这包括:树木、地面细节,太阳、天空已经运动模糊等效果。他们将在本文第三部分集中讨论。第二部分:基于LOD算法的地形简化引言地形渲染是一个室外渲染引擎的核心部分。而实现一个大规模的地形渲染系统的关键是如何简化地形,抛弃不必要的渲染动作(如看渲染不见的三角形和不必要的细节)来加快渲染速度。动态LOD技术无疑是一个强有力的解决方案。第二章:LOD简介当我们要生具有相当真实感的场景的时候,由于场景本身的复杂性,要实现实时性往往时不太可能的。我们必须从场景的本身的几何特性入手,通过适当的方法来简化场景的复杂性。层次细节(LevelsofDetails)技术就是在这样的情况下提出来的。我们知道,当场景中的物体离观察者很远的时候,它们经过观察、投影变换后在屏幕上往往只是几个像素而已。我们完全没有必要为这样的物体去绘制它的全部细节,我们可以适当的合并一些三角形而不损失画面的视觉效果。对于一般的应用,我们通常会为同一个物体建立几个不同细节层度的模型,如下图的牛的模型,最左边的有最高的细节层度,而最右边的则经过了相当的简化。这样的技术在地形渲染中,我们也称之为多分辨率地形(Multi-ResolutionTerrain)。(图2.1)牛的层次细节模型,图片来自清华大学远程教育网这些不同细节层度的模型可以时在程序运行前建立的。也可以是在运行时刻计算生成的。我们可以从一个全细节的模型出发,通过一系列简化操作生成底细节层度的模型,简化操作可以分成三种(见[参考文献31]):顶点删除,边压缩和面片收缩技术。通过这样处理后,我们可以在特定的场合下选择合适的模型,而不必每次都选用全细节的模型,这样大大的降低场景三角形数量。地形作为一种特殊的几何物体,我们在运用LOD法则的时候有一些特殊的技巧。因为地形通常是一个规则的矩形网格。其简化模式可以有两种:规则的简化和非规则的简化,规则的简化通常是对这个矩形网格采用自顶向下(Up-to-Down)、分而治之的策略,典型的有四叉树和二叉树,它们从场景的最低细节层度开始,按需要不断的提高细节。非规则的简化通常是采用自底向上(Down-to-Up)的方法来处理的。它的实现则通常比较少。(图2.2)规则的简化(左边)和非规则的简化方式(右边)。图片来自[参考文献2,12]实现LOD算法时,除了如何对几何物体进行简化以外,还有一个很重要的问题就是如何决定是否对一个物体进行简化,或者说在某个时刻该如何决定使用哪个层次细节度的模型来表示物体。我们需要建立一个评价系统,由这个评价系统来决定要对物体简化到何种层度。这种评价系统通常是视点相关的,离视点远的物体通常只需要较少的细节,反之则需要比较多的细节。除此之外,物体本身的特性也必须考虑在内。比如说,一个平坦的表面只需要很少的三角形就能较好表现出来。而一个凹凸不平的表面是理所当然的需要更多的三角形去描绘的。用LOD算法渲染地形的时候,还有一个很重要的问题就是几何变形(Geomorphing)问题,由于对一些细节的丢弃,随着视点的移动,远处原来没有的细节很可能会突然出现,这种现象也称为“跳出”(“Pop”)。我们必须消除这种现象,或者至少要把它控制在可以接受的范围以内。由上可知,LOD算法其实并不很复杂,本文认为其关键处可概括如下:1.数据的存储布局,数据在内存中的布局必须要方便算法的实现,同时最好还要降低操作系统缺页中断的次数,也就是降低内外存之间的数据交换的次数。2.如何在生成连续的LOD化的地形网格,在地形LOD化过程中,要让两个由不同层度的细节的区域之间能平滑的过度。3.节点评价系统,这个系统必须要使生成的网格能尽量的减少几何形变,尽量的使画面质量能接近全分辨率时候的地形。同时还要保证实时性。第三章:相关的研究在过去的几年中,已经由相当的数量的实用的算法被开发出来。BryanTurner在他的论文[参考文献32]中提到,LOD地形法则可以由三篇优秀的论文来概括,它们为[参考文献12,4和7],在[参考文献12]中,Hoppe描述了一个ProgressiveMesh的模型,它是使用自底向上的模式。[参考文献4]作者是Lindstrom,它则使用了一种基于四叉树的数据结构,他用四叉树递归的把一个地形分割成一个一个小块(tessellates)并建立一个近似的高度图。[参考文献7]的作者是Duchaineau,