目录
笔记导航:
LE7--渲染系统4:渲染管线,后处理:https://blog.csdn.net/m0_56399931/article/details/124790469
LE6--渲染系统3:游戏中的地形/天空/云渲染:LE6--渲染系统3:yo地形/天空/云渲染_This is MX的博客-CSDN博客
LE5--渲染系统2:光照、材质、Shadow:Games104笔记---LE5--渲染系统2:光照、材质、Shadow_This is MX的博客-CSDN博客
LE4--渲染系统1:渲染基础:Games104笔记---LE4--渲染系统1:渲染基础_This is MX的博客-CSDN博客_渲染系统
LE3--基础架构2:数据组织与管理:Games104笔记---LE3--基础架构2:数据组织与管理_This is MX的博客-CSDN博客
LE2--基础架构1:引擎架构分层整体Pipeline:Games104笔记---LE2--基础架构1:引擎架构分层整体Pipeline_This is MX的博客-CSDN博客
LE1--现代游戏引擎导论:Games104笔记---LE1--现代游戏引擎导论_This is MX的博客-CSDN博客
地形几何
高度图:
每个网格/顶点应用高度、材质等信息,我们每个顶点可以根据高度改变位移。
但是这种方法是不适用于开放世界的。很难直接画出几百万公里的场景
自适应网格细分
当fov越来越窄的时候,网格越来越细
那为什么是fov呢,如果写过摄像机系统的话,其实有一个方法实现缩放,就是变更fov,如果fov越小离物体就越近,所以这种时候网格就需要越精细。
几个原则:
· 距离摄像机和视场
· 与地面真实值相比的误差(预计算)
网格细分的方法:
基于三角形的网格细分:
基本方法:就是三角形最长的边取一个把一个三角形切分成两个三角形
但是会有一个T junctions的问题,这个得查找对应周围的边是不是更加细分,如果更加细分,那我相邻没有细分的也要进行切分
这个算法有个问题,对于地形数据的管理和中间的切分算法不符合我们制作地形的逻辑。
基于四叉树的网格细分:
四个四个进行合并或者细分
优点
①简单的构造
②便于地理空间下的数据管理,包括对象剔除和数据流
缺点
①网格细分不如三角形网格灵活
②叶节点的网格级别需要一致
这个更加适合引擎使用,更加的符合资源管理
这个方法也有T junctions的问题,这个可以通过三角形退化进行处理,把顶点进行合并
不规则网格:
优点
①容易在运行时渲染
②在某些地形类型中较少的三角形
缺点
①需要特定的预处理步骤
②可重用性差
硬件几何细分:
Shader入门---曲面细分着色器和几何着色器_This is MX的博客-CSDN博客_曲面细分着色器
这个曲面细分着色器和几何着色器可以看这个简单介绍。
曲面细分着色器的输入输出:
输入:Patch,可以看成是多个顶点的集合,包含每个顶点的属性,可以指定一个Patch包含的顶点数以及自己的属性
功能:将图元细分(可以是三角形、矩形等
输出:细分后的顶点
曲面细分着色器流程:
Hull Shader : 可以编程,决定细分数量(设定Tessellation factor以及Inside Tessellation factor),对输入的Patch参数进行改变(如果需要)
Tessellation Primitive Generation :无法编程,进行细分操作
Domain Shader : 可以编程,对细分后的点进行处理,从重心空间(Barycentric coordi)转换到屏幕空间
Mesh shader 开放了更多的权限,用户可编程程度更高,比如说可以自定义输入数据,输出数据和自己的细分算法。
实时变形的地形:
我们可以生成一个Deformable Terrain 根据我们的场景输入对地形进行偏移然后把周围的物质挤上来一些。
体素化:
在三维计算机图形学中,体素表示三维空间中规则网格上的值。作为2D位图中的像素,体素本身通常不会用它们的值显式地编码它们的位置(即坐标)
Marching Cubes算法:
地形着色:
存储内容:
地形纹理采样:
然后我们对上面贴图进行混合,如果只是简单的混合是有问题的
正确的过渡算法:
根据高度图进行调整
如果我们加权的高度差在0.2之间的时候我们可以让权重做一些插值,可以让我们的效果更加柔和
事实上我们的游戏中会有非常多的纹理,我们的纹理会存储在Texture array 。
那Texture array 和Texture3D的区别是什么呢?
Texture array 只是多层Texture,层和层之间是没有关系的
Texture3D的层之间是有关系的,如果我们采样一个点需要对一个点周围八个标准点进行插值
凹凸/视差/置换贴图:
凹凸贴图使用每个顶点不同的发现来呈现凹凸感
视差贴图属于位移贴图(Displacement Mapping)技术的一种,它对根据储存在纹理中的几何信息对顶点进行位移或偏移。一种实现的方式是比如有1000个顶点,根据纹理中的数据对平面特定区域的顶点的高度进行位移。这样的每个纹理像素包含了高度值纹理叫做高度贴图。
DisplacementMapping是一种真正改变物体表面的方式。通过一种称为micropolygons(微多边形)tessellate(镶嵌)的技巧来实现真正的改变物体表面的细节。
具体流程是这样的。首先,根据屏幕的分辨率,在模型的可见面上镶嵌和最终象素尺寸相同的微多边形。这个过程叫做镶嵌。然后读取一张Bump贴图。根据表面的灰度确定高度。然后根据镶嵌所得到的多边形,沿着原先的表面法线方向移动微多边形。接着再为新的多边形确定好新的法线方向。此时,物体的表面确实已经真的增加出了细节。
Virtual Texture:
为了解决采样纹理昂贵的问题,我们来看看虚拟纹理技术
这个技术有点类似计算机里面的虚拟内存
我们会把我们用到的存到内存中,没有用到的放在磁盘中,然后通过分页来对磁盘内容进行索引。
虚拟纹理技术主要是基于CPU的磁盘、主存和显存之间的缓存管理
地形渲染问题:
浮点数精度问题:
当距离边远,精度误差就会越来越大
解决方法:
我们可以使用在摄像机空间渲染
在任何其他几何变换影响物体之前,先通过世界空间相机位置来转换物体
然后,它将世界空间摄像机的位置设置为0,并相应地修改所有相关矩阵
地形植被:
天空渲染:
简单的天空模型:
优点
①计算简单高效
缺点
①仅限于地面视图。
②大气参数不能随意改变
更加合适的模型:
更加合适的理论,地球大气层厚度约为100km(由卡门线划定,卡门线是公认的外太空与地球大气层的分界线),它由氧气、氮气、氩气(瑞利发现的气体)、二氧化碳和水蒸气组成。
光传输方程:
我们需要光在粒子中传输的时候有多少能量被吸收,多少倍散射,有哪些是自发光的,有哪些是吸收的光
体积渲染方程:
散射的类型:
瑞利散射(空气分子散射光)是造成天空蓝色(以及日出和日落时的红橙色)的原因,而米氏散射(气溶胶散射光)通常是造成污染城市上方白灰色雾霾的原因(阴霾掩盖了天空的清晰度)。
瑞丽散射:
在这个等式中,h是高度,λ是波长,N是海平面的分子密度,n是空气的折射率,l是大气高度
米氏散射:
米氏相函数包括控制介质各向异性的项g(瑞利相函数不包括)。气溶胶具有很强的前向指向性。一些论文使用g=0.76。g>0,向前散射更多 ;g<0,更向后散射; g=0 就会退化成瑞丽散射。
大气吸收能量:
单次散射与多次散射:
实时大气渲染实现:
RayMarching实现:
我们使用步进的方式计算每一步的消耗衰减。
预计算:
我们可以预计算出视线和天顶,以及海拔高度的通透度,在用的时候直接采样
我们更进一步,预计算单次散射存储到LUT中
然后我们可以结合这两个图,进行积分,然后就能获取到多次散射的图
预计算大气散射的挑战:
1.预先计算成本
①多次散射迭代是非常昂贵的
②很难在低端设备上生成大气LUT
2.环境的创作和动态调整
①艺术家不能随意改变散射系数
②很难渲染像天气从阳光到雨雾,行星间的太空旅行
3.运行时呈现的成本
①昂贵的逐像素多维高维纹理采样用于透光性LUT和多散射LUT(总是需要向下采样以提高效率)
如何快速计算大气散射:
我们近似一个点在各个方向的散射是均匀的,那我们在散射出去的值是均衡能量衰减的,所以我们只要预计算一次两次的散射就能用级数来实现快速计算。
在这种假设下我们的lut计算复杂度就会减少,lut的维度会减少两个维度
在这种想法的考虑下,我们能达到良好性能和效果的平衡
云的渲染:
老的方法:
直接拿模型来模拟
或者拿插片模拟
新的方法:
体积云:
优点
①能达到真实的云的形状
②能够模拟大规模云
③支持动态天气
④动态体积照明和阴影
缺点
①必须考虑效率
体积云的实现:
Weather Texture:
首先它用一个weather texture ,表示云的分布,然后里面存的值是0-1表示云的厚度,如果我们要云飘起来就让他移动起来,如果要他不同的形状那我们就可以对它进行一些扰动
Perlin Noise/Worley Noise:
那扰动怎么实现呢?
我们可以使用Perlin Noise/Worley Noise
实现过程展示:
我们可以看一下,一步步使用上面讲的东西实现体积云的过程:
我们可以使用RayMarching来实现:
步骤1:为每个屏幕像素投射光线
步骤2:大步行进,直到碰到云
步骤3:云内密集步进采样,如果打到云了,就减小步进长度
步骤4:计算来自太阳的散射光
Pilot v0.0.2:
Pilot v0.0.2发布
学习资料:
1.Games104