`

Terrain(地形) Geometry Clipmap

 
阅读更多

在大的室外场景中,地形的几何体需要较大的存储空间和渲染带宽。为解决这个问题,出现了很多LOD的技术。然而,大多数技术都是在CPU端实现的,需要运行时创建和修改顶点缓冲区。

 

Geometry Clipmap:

把地形当做2D的高度图,并把它预过滤进一个L层的mipmap中。对于大场景来说,完整的地形mipmap太大,无法全部加载。所以 Clipmap会在每层缓存一个nxn顶点样本的页面,页面以视点为中心。这里需要注意的是:每一层的顶点都是nxn,也就算是每一层的三角形数量是一样的,只不过大小不一样,所以每一层表现出的面积也不一样,目的是让三角形在屏幕空间中的大小一样。视点移动的时候,对nxn的顶点数据进行更新,采用的是环形方式访问。

 

除了第一层以外,其他的层都是一个空心环,”回“ 字

这里看起来,每个外环的三角形是内环的4倍大小。

 

裂缝问题的解决:

每一层网格的大小一定是奇数,最好是(n = 2幂k - 1) 因此一般取n = 255。为啥要是奇数呢?主要是为了上一层有一部分覆盖到下一层上。

这里采用细的层次多出一个边的方式,对粗的层次进行覆盖,这里只增加一行一列是因为重心位置做了偏移,应该是用0.5格来覆盖边缘部分。这个图很重要,它告诉你每一个环由那些块组成的,把环算出来了,所有的环都可以进行类推。这个橙色的部分,是两块的接壤部分,采样的是退化三角形,本身是不怎么站面积的。

对于每一层执行了14次draw 其中12次灰色区块,1次内部调整,1次剩余的三角形。每帧总体需要:6L+5  L为层数。

另外,由于外层的面积是内层面积的2倍,所以内存只移动1格的时候,外层是不需要移动的。难道这才是为奇数的真正原因?

 

总结:一个无限大地形的世界场景如何实现呢?

1.首先,假设世界地图是无限大的,那么你肯定无法全部加载。所以,加载到内存的时候,是9个地形块,其中最中间的一个是当前使用的地形块,而其它8个是缓存起来备用的,这个类似九宫格。

2.根据当前视角的位置,加载当前使用的地下块到显存里面去,这加载的部分就是上面的mipmap,回字格L层,包括高度和法线数据。

3.draw 按照上面画的一个环裁剪后6次,这个裁剪是在CPU端计算的。这一步完成后基本上结果已经显示出来了。

4.视点位置移动时对数据进行更新。

这样基本上就可以实现一个无限大的世界了。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics