games104现代游戏引擎学习笔记整理(06游戏中地形大气和云的渲染——地形篇)

Heightfield:即高程图,是被用于表示地形的变化的一张图(如等高线图)。如今常被利用在地形渲染中的地形表示中。

对地形的渲染通常通过对地形模型的网格化,然后逐个渲染面片来实现。但是在开放世界情形下,如果采用这种渲染方式,则计算所需的面片可能会过多。因此,LOD(Level of Detail)的概念被踢出,即根据观察距离的远近来改变渲染模型的精度,近处采用高LOD,即高精度的模型来渲染,而远处采用低LOD,即低精度的模型来渲染。

由于LOD这个概念本身是离散的,但是地形本身却是连续的,因此地形的LOD需要被仔细设计。自适应曲面细分就是其中的一个概念,它能够根据摄像机视锥的角度和距离观察点的距离来决定地形的渲染精度。一般来讲,视锥越细,位置距离观察点越近,视角范围内某位置的渲染精度也就越高。

 当对网格简化合并时,合并后地形和原来的地形误差不要超过一个阈值,这个阈值是由对地形图上的点的采样密度决定。这个阈值被称为Error Bound

地形精度的变化可以通过三角划分来实现。每次细分都是在三角形的最长边上做划分,将大三角形分割为两个小三角形。这种划分的底层数据结构可以用二叉树结构来实现,因此这个又被称为binary triangle-based subdivision

 T-Junction:在同一边上的两个相邻三角形由于不断切分的次数不同,最后会由于精细度的误差导致三角形在拼接时容易形成一个裂缝,其效果就是从远处看会看到很多白边。最简单的解决方案是当发现邻居切分比较密的时候自己也多切几次,以使相邻的两三角形精度接近,从而减少误差。

 此外,现代的软件还支持基于四叉树的地形表达。四叉树的表达方式一般为基于方形网格的地形。其优点是形成的地形很规整,处理很方便,且基于方块的切分方法更符合常识。

 方形切片解决T-Junction的方法:吸附,当两边由于切分次数不同存在误差时,切分细的一方会将切分边上的点自动吸附到切分粗的一方上,从而使整个表面具有水密性(其实三角形网格也可以这么解决吧?)。

 

用的不是很多的地形表示方法:Triangulated Irregular Network(TIN)非规则三角形网格

在大面积平坦的地形(沙漠,平原等)下,原先的方法会产生很多不必要的三角网格。因此可以通过简化形成不规则的三角网以减少三角网格数,以降低计算所需空间和时间。这种方法的优点自然是渲染简单,更少的三角网格能加快渲染速度。但缺点是其只能针对特定场景优化特定的网格,且需要对地形进行预处理以计算不规则网格。

 值得注意的事,现代的GPU基本都能自动完成三角细分的步骤。

shader中三角细分的经典步骤:Hull Shader->Tessellator Shader-> Domain Shader。其中Hull Shader会生成曲面的控制曲线的参数,并为后两者提供细分的相关参数,而Tessellator则会生成细分后面片对应的纹理坐标(uv图)。最终上述的输出被输入到Domain Shader中,从而计算出地形的顶点坐标。详细可参考文章:DirectX 12 曲面细分着色器笔记_hull shader_wowodadai的博客-CSDN博客

而现代GPU将过去几个关于三角细分的繁杂的shader步骤组合在一起,集成为Mesh Shader Pipeline

 Real-Time Deformable Terrain:地形实时变形技术,其原理是地形的每一个面片相当于一个小弹簧,物体在上面的挤压导致地面的变形。这个东西在提升游戏真实性上非常有用。(但在变化较大时需要记得改变地面的碰撞体积)

 非高程图表示的地形:地形上可能存在一些横向洞窟的设计(如山洞),而这些是高程图难以表示的,需要用其它的地形表示来实现。

传统游戏中地形挖洞的小技巧:将部分面片设置为无效的面片(在GPU中不渲染),然后在生成的洞中插入隧道的模型。

现代游戏引擎的一个做法:在三维空间中使用体素化分割,在每个体素中规定该处的地形。

Marching Cubes:在每个体素中存储数个三角面片以表示地形。这个方法存储地形的研究比较少。

(这方面我有做过一定研究,Marching Cubes实质上是一个用于提取零等势面的方法,但这种思想其实也可以用于地形的建模。改天我整理出那篇论文的内容。)

地形材质的混合:简单的地形材质混合就是将各种材质通过笔刷混合在一块,边界通过某种混合算法进行过渡。

 该方法带来的问题:混合算法带来的过渡太过于平滑,其渐变的过渡有时候会造成不好的效果。

 解决方案:高度信号的锐化,即弱化过渡效果,在高度差异小时其混合效果也较为尖锐。但这可能会导致边界线过于明显的情况。因此通常对于小高度差异的地形混合边界也会通过添加高度偏差的方式实现一些颜色上的混合。

 在早期的材质混合中,一般会用 Texture Array存储各层材质,并通过设定不同层材质的权重来进行地表材质的混合。

贴图效果的进化:颜色贴图->凹凸贴图(支持一定的光照效果)->视差贴图(在贴图表面造成一定的凹凸感)->displacement mapping(在近处的视差贴图会被细化成真实的网格)

由于材质混合需要不断读取各种材质并进行采样计算,因此计算比较昂贵。(为什么不能事先混合好?)

Virtual Texture:不把全部贴图材质存在GPU的显存中,而是只存储一部分,用到哪些读哪些。

 

Direct Storage:图像数据的传输方向一般是硬盘->内存->显卡,在内存处解压数据。而Direct Storage则是直接以压缩的形式将数据传输到显卡,大大减少了传输量。

DMA技术:直接将图像数据从硬盘传输到显卡的技术,不经过内存,从而加快了传输速度。

目前地形绘制的问题:浮点数的数据溢出,由于采用的是世界坐标系,因此在距离过远或差距过小时,贴图数据可能会由于精度问题发生位置显示的抖动,且距离越远/差距越小抖动越明显。

解决方案:

Camera-related rendering:以相机中心为坐标系进行渲染。

Sub-level:将整个场景分成多个小场景,每个场景内重置一遍世界坐标系

其它的地形相关rendering:tree rendering,decorator rendering(草一类的装饰物),road and decals (贴片)rendering。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值