voxel:VOXEL技术在即时渲染地形中的应用



  VOXEL 技术其实是种很简单技术但它对于即时渲染地形确实又是种十分有效技术写这篇文字有两个方面是为大家介绍这个古老技术方面更重要是希望大家看了本文能多有启发从而发展出更多简单实用好技术就我自己感觉而言创作游戏更多时候就是在寻找种更简单而又更有效思路方法切不可能变为可能这便是游戏设计的魅力所在

   BTW本来去年就想写这篇文字居然能够拖到了今天看来我懒惰毛病是发作得非常厉害算了闲话休提还是让我们现在就起踏上有趣 VOXEL 技术的旅吧!

   VOXEL 技术出现得相当早据 James Sharman 自称他在 95 年时就想出了这种思路方法而 NOVALOGIC 则是这种技术忠实拥护者从早期 COMMANCHE 到最近 DELTA FORCE 和 DELTA FORCE II直使用 VOXEL 技术来搭建图形引擎核心

   VOXEL 技术思想其实很简单它不是用现在很流行多边形思路方法来描述地形而是用种线性插值办法来形成自然连续起伏地形如果只用句话来描述就是由近及远地依次画出对应地形轮廓线同时记录屏幕投影高度坐标值以供画下条轮廓线时比较从而只画后面新露出来部分
\" width=320 border=0>



  根据这种想法我们首先必须要考虑就是如何来表示地形以及如何去求取并绘制出每条地形轮廓线

   通常在使用 VOXEL 技术时我们会建立个 2维来记录地面上均匀分布各点高度比如 HEIGHT[34] = 100 就表示在位置 [34] 处地面高度为 100习惯上通常高度取值在 0 到 255 的间

\" width=260 border=0>



  有了这个以后步我们便依次开始求取并绘制出每条地形轮廓线

\" width=261 border=0>



  在上图中V 表示观察者所处位置L1 和 L2 分别表示是前后裁减范围红色线段所表示就是我们要绘制地形轮廓线

   对于任何条红色线段来说知道了观察者位置、观察方向和观察夹角以及到观察者距离这几个条件以后代入 3角公式就可以很容易地计算出这条红色线段两个端点位置

   现在我们有了这条红色线段两个端点位置下面就可以开始绘制地形轮廓线了

   首先我们从离观察者最近条红色线段开始假设两个端点位置是 (X1, Y1) 和 (X2, Y2)而实际屏幕显示宽度为 W

   接下来我们把这条红色线段按等分取 W 个点这些点就是我们绘制时用采样点

   然后我们便该依次求取出每个采样点上地面高度在求这些采样点上地面高度时我们通常使用线性插值思路方法

\" width=173 border=0>



  比如有点 N位置是 (X, Y)其中 X=Xa+XbY=Ya+YbXa 和 Ya 是 X 和 Y 整数部分Xb 和 Yb 是 X 和 Y 小数部分按照线性插值此处地面高度应该是:

   HN=(H(Xa,Ya)*(1-Xb)+H(Xa+1,Ya)*Xb)*(1-Yb)+(H(Xa,Ya+1)*(1-Xb)+H(Xa+1,Ya+1)*Xb)*Yb

   如此这样我们就求出了该采样点上地面高度然后我们把这个地面高度按线段到观察者距离进行坐标变换最后得到该点对屏幕投影产生纵坐标值同时该点对屏幕投影产生横坐标值直接由它在这 W 个点中排列位置得到比如说第个点横坐标值就是 0第 2个点横坐标值就是 1第 3个点横坐标值就是 2 等等……

   为了正确地处理每前后空间关系我们将为每列保留个最高纵坐标值在实际显示地形轮廓线点时我们需要把每点纵坐标值同该列这个最高纵坐标值进行比较并在超过此值时覆盖这个最高纵坐标值由于我们目前是画是最近条地形轮廓线所以不需要考虑是否被更近地形轮廓线所挡住直接判断每点纵坐标值是否在屏幕以内就可以了如果是话则直接修改该列最高纵坐标值为此纵坐标值否则让该列最高纵坐标值为最低

   接下来在由近及远依次显示除了最近条的外其它地形轮廓线时我们通过对每列最高纵坐标值进行这种比较和更新就可以跳过那些被遮盖住部分从而达到正确显示

   般地在选取地形轮廓线时越远地形轮廓线可以选得越稀疏由于透视原因这样不会产生明显失真而计算量可以减少很多

   到了这剩下工作已经不多了觉得光是这样地形轮廓线太简单了不是?想要看到更真实地形吗?那么就让我们开始有关地表蒙皮话题吧!

   在 VOXEL 技术中地表蒙皮是件非常简单事情实际上就是用许多短竖线去填充地形轮廓线的间空缺







  图 5给出种最简单情况只做了些非常简单对亮度处理在这种情况下使用是地形轮廓线的间填充按照亮度插值生成短竖线思路方法理解了这种思路方法就不难去理解其它更复杂思路方法了

   首先我们必须求出地形轮廓线上每点(准确说应该是指像素)亮度使用我们前面求每点高度时类似办法这个问题将不难解决但我们还得先建立个同高度 2维 HEIGHT[x, y] 对应亮度 2维 BRIGHT[x, y]

   亮度计算有很多种办法这里介绍种按坡度来求取亮度简单思路方法:

   BRIGHT[x][y] = 128+(HEIGHT[x+1][y+1]-HEIGHT[x][y])*4;
   (BRIGHT[x][y]<0) BRIGHT[x][y]=0;
   (BRIGHT[x][y]>255) BRIGHT[x][y]=255;

   求出了地形轮廓线上某点亮度以后剩下工作就是填充条按照亮度插值生成短竖线

   为了达到这个目我们在显示条地形轮廓线时除了会记录该列最高纵坐标值外还要记录产生最高纵坐标值亮度值这样当我们在画从第 2条开始地形轮廓线时旦发现当前采样点纵坐标值超过了该列最高纵坐标值就按照从记录中最高纵坐标值对应亮度值到当前采样点亮度顺序画条亮度渐变短竖线这条竖线起点就是记录中最高纵坐标值终点是当前采样点纵坐标值然后把该列最高纵坐标值置为当前采样点纵坐标值并记录下最后亮度值即当前采样点亮度值

   如此亮度值地表就被我们轻松实现了

   下为了获得更真实效果我们将开始考虑如何实现对地表纹理映射

   在此要声明对于纹理映射这个概念我不想在这里详细解释否则本文会变得太长且内容过于分散所以以下便假设读者已经熟悉了 3D 中纹理映射这个概念如果你确实不知道话就说我回头再单独写成文字便是

   James Sharman 在他文章中曾经提出了种思路方法就是按高度渐变来产生地表纹理映射他首先为各个区别高度地面建立系列纹理如下:





  有了这系列纹理我们接着在做地形绘制时便按照每点实际高度和以前面提到 Xb、Yb 作为 U、V 坐标来选取对应纹理进行映射得到结果如下图所示:





  其中相邻两条地形轮廓线的间填充是对 U、V 坐标使用线性插值思路方法得到为了让大家能更好地看清这个过程请参考下图:





  现在对这种先计算出若干地形轮廓线然后再用线性插值思路方法填充思想应该理解得非常清楚了吧

   不过在 DELTA FORCE 这样游戏中使用是另外种方式在这种方式中先把整个地图做成张巨大纹理然后在映射时是只按照位置来进行纹理映射而不考虑高度这种方式可以得到更逼真细节但同时也要求更多内存另外在 DELTA FORCE 中阴影是直接做在纹理上而不是实时计算得到这样有利于提高效率

   说到这里无意抬头望了望天发现时候已经不早了太阳都快出来了是该准备去休息时辰了虽然还有千言万语但瞌睡来了确实挡都挡不住所以只好溜去睡觉言有未尽的处大家莫怪……zzZ




Tags:  学会应用地形图ppt 地形图的应用 voxelhead voxel

延伸阅读

最新评论

发表评论