GAMES104:06游戏中地形大气和云的渲染1-学习笔记


先来一张课程开始的美图——Mother Nature;环境包含了天空云系统、植被、地形(Terrain)
在这里插入图片描述

一、地形的几何

1.1高程图Heighfield

虽然方法古老,但依旧是现代游戏的主力,因为简单有效:先建立密集顶点MeshGrids(比如1km*1km,每米一个顶点),再用Heighfield对每个顶点进行位移和材质渲染。

1.2 网格自适应细分

但是在开放世界里几百公里的地形这个方法就计算量太大了。在开放世界中经常使用LOD处理远处地形,但因为地形的特殊之处在于一直是连续的,因此需要使用一些技术比如下图,根据视角FOV(八倍镜原理)和距离进行网格的自适应细分
在这里插入图片描述
优化视图两条原则:

  1. 离相机越近越密集,fov越小越密集;
  2. 要保证在简化合并的时候,采样点变少,地形高低误差不能超过一个阈值(Error Bound,这个阈值是在view空间上,理想情况下不要超过一个像素)。

1.3 三角剖分

1.3.1二叉树

  • 二叉树是最基础的切分方法,就是对等腰三角形的斜边进行切分,如下图,黑色是看不见的区域,高亮是可见区域

  • 问题:对地形数据的管理和剖分算法不符合制作地形时候的直觉(将大地形切成豆腐块,即四叉树思想),因此用的不太多
    在这里插入图片描述

  • T-Junctions:如果某一条边的两侧采样密度差很多,可能会导致出现高低差裂缝(稀疏那侧在这条边上没有采样点,密集那侧可能采样点的高度和稀疏侧不同),这时候就必须对稀疏的一侧也进行进一步采样直到缝隙消失。这个行为就是T-Junctions
    在这里插入图片描述

1.3.2四叉树(Quad)

最常用的方法仍是四叉树

  • 优点:容易构建;因为和其他几何材质数据形式更贴合,所以易于管理各类几何空间数据,包括Culling和tex streaming等
  • 缺点:切分没三角形那么灵活;叶子结点的方格必须是连续的

四叉树也会遇到T-Junctions问题。解决方案让采样密度高的一侧多出来的采样点调整高度,吸附到采样密度低的那条边上,如下图
在这里插入图片描述

1.3.3 TIN(Triangulated Irregular Network)不规则三角形网格

用得不多,但前沿

  • 优点:容易实时渲染;在特定地形下需要的三角形更少(比如大面积平原、沙漠)
  • 缺点:需要特定预处理;重复使用性低
  • 上边实时处理的方法比TIN渲染的三角形多呢?:上边的方法是等间隔采样,不能保证每个采样点正好在高频区域,而TIN是定制的

1.3.4 GPU Drived Tessellator(Hardware Tessellation)

外壳着色器(Hull Shader)、镶嵌器(Tessellator)、域着色器(Domain Shader)-----(老师说)反人类设计,还好有新的Mesh Shader来代替了(Vulkan和DX12以上 win10+,win7不支持)

  • Mesh Shader:在传统的图形管线中,顶点着色器和几何着色器是按顶点或图元(如三角形)顺序执行的,这种方式在处理大量几何体时可能会导致 GPU 的计算能力没有被充分利用。而 Mesh Shader 则采用了一种基于任务的并行处理模型,它可以将一个大的几何体(如一个模型或场景)分解成许多小的任务(称为“meshlets”),每个任务包含一小部分的顶点和图元,然后这些任务可以在 GPU 上并行处理。这种方式可以更好地利用 GPU 的并行计算能力,从而提高渲染效率。
  • meshlet:一个 meshlet 是一个包含一组顶点和图元的小型几何体,它是 Mesh Shader 处理的基本单位。

GPU Drived Tessellator可以实时调整所有顶点的位置和数量,实现实时变形地形(Real-Time Deformable Terrain,类似于堆弹簧在地面上,当压他的时候就会变形)->(黑神话悟空预告片中雪地场景)。

1.4 Non-HeightField

像桂林象鼻山这种有洞的地形就不能使用HeightField生成,比如在山体模型上挖个洞做隧道,通过取一个隧道中心点,将其位置设为NAN,现代引擎就会自动去掉所有包含这个点的三角形,最终形成一个洞,后续再用一个美术的隧道模型插进去掩盖锯齿状的边缘

1.5 体素化Marching Cube

老师的私心介绍:
医学CT建模、点云等都用到了Marching Cube,对应到地形的情况可以做一个查找表,具体的看原文

二、地形的材质

真实世界中材质数量很多,有大量材质混合情况。

2.1 texture splatting纹理混合

用于2种材质混合:

  • 传统纹理混合相当于用alpha混合的逻辑,但是太过平滑不够真实,见左图,一看就是p的
  • 后来有了利用地形高度混合的方法,谁高显示谁的纹理,见右图,效果还不错,但是由于2种材质是01切换,在相机移动或者视角很低时,会出现抖动或者分界线sharp的问题
  • 所以又引入一个高度bias来优化,并且结合高度和alpha一起过渡,代码和效果如下图

2.2 Texture Array

多材质混合时使用(一般1个点4种材质),把所有要混合的材质纹理放入Texture Array中,根据index及其权重来进行混合计算:获取材质index,分别获取各材质纹理,计算混合权重,混合各材质。

「注意:Texture Array与3D texture不同,3D texture是用cube的八个顶点采样并上下两个面进行Tri-linear三线性插值计算最终采样结果,而Texture Array每层之间没关系」

2.3 视差贴图、位移贴图

在这里插入图片描述

  • 法线贴图只能实现平面上的光照差异,但模型表面和纹理感都很塑料。(大部分应用)
  • 视差贴图在视觉上做了一个offset,从而让视角效果更好。但是视差贴图成本高些,因为需要走几步更新一下,并且几何上实际还是没有改变。
  • 位移贴图是利用高度贴图将简单网格按照高度细分,改变网格位置
![在这里插入图片描述]()

2.4 Virtual Texture虚拟纹理

用Texture Array进行纹理混合时,每个点需要采样4组材质,这是非常昂贵的;并且在很远的地方也需要采样大量同精度纹理,也不合理,因此有了虚拟纹理技术。

原理是把需要用到的纹理tiles based on viewdepend LOD(虚纹理)地装载到内存中的一张物理纹理中,并且保存其uv、mipmap level等信息的映射关系,渲染时直接采样这张图,可以大大节省效率;并且在摄像机移动时,动态的更新替换其中的一部分。并且可以在烘焙tile的时候直接融合好材质再放入物理纹理中。

虚拟纹理应用非常广泛,已经一统天下了

在这里插入图片描述

值得关注的前沿硬件技术:

  1. 正常数据流程是硬盘-内存-显存,而DirectStorage 可以让压缩数据经过内存,直达GPU显卡里解压,CPU只需要传递压缩后的数据,传递效率能提高
  2. 索尼的DMA技术能直接把数据从硬盘传到GPU,并且显卡之间的数据交换也可以直连,不需要转手内存了

2.5 浮点数精度溢出

浮点数是32位表示,精度是有限的,所以数字越来越小或者越来越大是就会出现问题,比如当相机和某个点距离过大时,最小精度可能会超过1,然后就会出现抖动,这就是浮点数的精度溢出;虽然可以扩大数据精度使用double,但也不能覆盖广阔的数据范围。

  • 解决方案Camera-Relative Rendering:在任何其他几何变换影响物体之前,通过重设世界空间相机位置来转换物体,用相对位置来计算,比如UE5会把一个关卡切成很多个subLevel,分别重置世界坐标
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值