一、地形的几何
1.1 高度图
记录不同定点的高度,对每个网格/顶点应用高度、材质等信息,我们每个顶点可以根据高度改变位移
但是这种方法是不适用于开放世界的。很难直接画出几百万公里的场景
1.2 自适应网格细分
当fov越来越窄的时候,网格越来越细
那为什么是fov呢,如果写过摄像机系统的话,其实有一个方法实现缩放,就是变更fov,如果fov越小离物体就越近,所以这种时候网格就需要越精细。
几个原则:
- 距离摄像机和视场
- 与地面真实值相比的误差(预计算)
网格细分的方法:
1)基于三角形的网格细分:
基本方法:就是三角形最长的边取一个把一个三角形切分成两个三角形
但是会有一个T junctions的问题,这个得查找对应周围的边是不是更加细分,如果更加细分,那我相邻没有细分的也要进行切分
这个算法有个问题,对于地形数据的管理和中间的切分算法不符合我们制作地形的逻辑。(不是正方形,而是三角形)
2)基于四叉树的网格细分:
四个四个进行合并或者细分
这个更加适合引擎使用,更加的符合资源管理
这个方法也有T junctions的问题,这个可以通过三角形退化进行处理,把顶点进行合并
3)不规则网格:
对于平面地形,合并不必要的顶点
优点:
- 容易在运行时渲染
- 在某些地形类型中较少的三角形
缺点:
- 需要特定的预处理步骤
- 可重用性差
1.3 实时变形的地形
我们可以生成一个Deformable Terrain 根据我们的场景输入对地形进行偏移然后把周围的物质挤上来一些。
1.4 体素化
如果我们想在山中挖个隧道怎么实现呢?
在三维计算机图形学中,体素表示三维空间中规则网格上的值。作为2D位图中的像素,体素本身通常不会用它们的值显式地编码它们的位置(即坐标)
Marching Cubes算法:
二、地形的材质
2.1存储不同的地形内容:
2.2地形纹理采样
然后我们对上面贴图进行混合,如果只是简单的混合是有问题的
正确的过渡算法:根据高度图进行调整
事实上我们的游戏中会有非常多的纹理,我们的纹理会存储在Texture array 。
那Texture array 和Texture3D的区别是什么呢?
Texture array 只是多层Texture,层和层之间是没有关系的
Texture3D的层之间是有关系的,如果我们采样一个点需要对一个点周围八个标准点进行插值
凹凸/视差/置换贴图:
凹凸贴图使用每个顶点不同的发现来呈现凹凸感
视差贴图属于位移贴图(Displacement Mapping)技术的一种,它对根据储存在纹理中的几何信息对顶点进行位移或偏移 。一种实现的方式是比如有1000个顶点,根据纹理中的数据对平面特定区域的顶点的高度进行位移。这样的每个纹理像素包含了高度值纹理叫做高度贴图。
DisplacementMapping是一种真正改变物体表面的方式。通过一种称为micropolygons(微多边形)tessellate(镶嵌)的技巧来实现真正的改变物体表面的细节。
具体流程是这样的。首先,根据屏幕的分辨率,在模型的可见面上镶嵌和最终象素尺寸相同的微多边形。这个过程叫做镶嵌。然后读取一张Bump贴图。根据表面的灰度确定高度。然后根据镶嵌所得到的多边形,沿着原先的表面法线方向移动微多边形。接着再为新的多边形确定好新的法线方向。此时,物体的表面确实已经真的增加出了细节。
2.3 Virtual Texture
为了解决采样纹理昂贵的问题,我们来看看虚拟纹理技术
这个技术有点类似计算机里面的虚拟内存
我们会把我们用到的存到内存中,没有用到的放在磁盘中,然后通过分页来对磁盘内容进行索引。
虚拟纹理技术主要是基于CPU的磁盘、主存和显存之间的缓存管理
2.4 地形渲染问题
浮点数精度问题:当距离边远,精度误差就会越来越大
解决方法:我们可以使用在摄像机空间渲染,在任何其他几何变换影响物体之前,先通过世界空间相机位置来转换物体,然后,它将世界空间摄像机的位置设置为0,并相应地修改所有相关矩阵