sldbtree

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 :: 管理 ::

前言:

任何一种LOD (Level Of Detail) 方式最终想解决的问题,是在需要更多细节的地方尽量多的显示细节,也就是那些地方会有更多的面。解释一下:在没有LOD的时候,我们显示一个地形或者一个其他模型(LOD不仅是对地形而言),无论地形或模型跟镜头(视点)多远,在计算机内部运算的时候,都按照地形或模型拥有的所有面的数量来进行一系列基于数学模型下的运算,最终得到二维屏幕上的画面。在输出结果上,更远的模型占据到的屏幕的面积很小,极端情况可能就是几个像素。因此,计算机研究人员就一直致力于方法来优化这个状况。因为如果把很多不必要的运算(很多三维面经过几轮裁剪,最后没有在二维屏幕上显示)消除,就能让CPU或者GPU干点其他更有用的事情,毕竟资源是有限的。

 

在LOD的领域,目前来说还可以分为DLOD (Discrete Level Of Detail)和CLOD (Continuous Level Of Detail )两种具体形式。这篇博文讲述的Geomipmapping属于DLOD范畴。

 

Geomipmapping:

Geomipmapping跟mipmapping相似,前期可以通过美工或者程序(很多三维模型制作软件都具备把一个高精度模型进行LOD化的功能)制作出对应一个物体不同精度下的各个模型,这个一系列的模型就是这个模型的geomipmapping,有的书上也称作static LOD。不同的只是,mipmapping技术是针对于texture的,而geomipmapping技术,针对于geometric。

 

在geomipmapping中,每个物体都拥有一系列的geometric,我们给每个不同精度的模型一个特定的级别。然后,在程序运行的每一帧中,程序需要根据定义的规则,一般都是视点(camera)到geometric的距离,来判断需要用到那个级别的geometric。因此,geomipmapping技术,时间多用在前期美工对模型的建立上。程序实现上相对来说简单。

 

演示程序没有用到美工资源,本来应该美工做的活,我们用简单的方式来表现:对一个具体的地形,按照固定尺寸(程序用是17)把该地形分成一个个Patch。每个patch指定4个级别的level,不同的level表达的采样频率不同。下面就代码做一下相关的解释。

 

示例代码中,我们在update()中根据相机和每个patch中心的距离,来赋予不同的patch不同的level级别,每个级别代表了不同的细化程度。这些细化程度在本质上,决定了我们在高程图中的采样频率,更高的采样频率,意味着更接近高程度本来表现的地形复杂度。这也是每个LOD一定用到高程图的原因,对一个地形来说,本质上来说,高低起伏都是可以用在xz平面上y值的不同来表现的。

 

在Render()中,代码就利用刚才计算出的各个patch的级别,对每个patch做相应的工作。具体是需要更细化的patch,用到的采样频率就大一些。而可以粗糙一点的patch,采样频率就小很多。用这样的方式,我们渲染出在每个不同的视点位置的每一帧地形。

 

需要说明的是,程序用的地形是实时生成的(高程图实时生成)。因此打开程序的期初会需要一段时间,并且每次的“山峦”可能不一样。在实例代码中,没有用任何的裁剪方式(absolute brute-force ) - 除了D3D本身的投影体裁剪。因此初始的相机位置放置在“山峦”边缘,需要的话,请按up键往前推动镜头,观察“山峦起伏”,和顶点数量的变化。而且,渲染中的代码是除了逻辑清楚,没有任何效率的一种。当时写这个的时候,我也是为了留着做个对比,请看客只看逻辑。最后一点说的是,这个程序是早期写成的,也只有wireframe看看轮廓,对我来说,足够了。

 

附录:

1、源代码, VC9工程,在DirectX 9.0上编译。

http://www.163disk.com/fileview_325525.html

 


posted on 2011-06-28 15:00  sldbtree  阅读(823)  评论(0)    收藏  举报