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