地形、大气和云的渲染
June 25, 2023About 10 min
地形、大气和云的渲染
Info
本章的内容涉及了很多的物理和数学知识,目前是简单展开为主.
地形渲染 Terrain Rendering
地形渲染需要模拟真实的地面环境,另外还需构建一些想象的环境

- 高层图: Height Ma
- 等高线图: Contour Map
- 符合分形的原则

- 高层图使用样例

- 简单实现: 每隔一段距离(比如1m)做一个均匀的网格, 把顶点根据高层图采样做位移.
- 缺点:如果要处理的世界特别大,数据量会特别大

- 观察者主要关心自己观察角度(FOV)里的细节.
那么只需细化FOV范围内的三角形,稀疏分布FOV外侧和远处的三角形。
这样处理后我们还会发现当FOV越来越窄的时候,地形也会变得越来越大。 - 三倍镜/高倍镜原理
- 简单地把FOV变小了,缩小了观察范围变小–让眼睛更聚焦,对应观察位置就放大了。
- 越高倍的望远镜它的FOV越小。
- 假设屏幕是同等像素量的情况下,FOV越小,三角形投影后的像素就会增加。

- error bound: 在数据上要保证对网格进行简化合并时–采样点变少了,地形高低误差不超过一个给定的阈值.

- 怎样让三角形变得疏密相见:
永远在等腰直角三角形的最长边切换—二叉树 - 这张图高亮的地方是可视区

- T-Junctions: 当两个相邻三角形共享一条一条边,若其中一个三角形没被切分这条边。
另外一个三角形在当前边加了点进行切分,这个点(有高度变化)会导致产生误差(裂缝). - 解决方案:
如果法线有T-junction, 就保持和邻居一样的均匀切分.

- 问题→ 对地形数据的管理不方便(全是三角形),也不符合地形制作直觉

- 使用四叉树管理地形, 方块对认知也更好.
- 主流的地形表达方式

- 把小块合并成大块(block),以block为单位打包关联数据.

- Stitching→ 把邻居多的点移动到上面去,会产生面积为0三角形→退化三角形.
- 在绘制的时候不绘制退化三角形



- 用不规则的三角形去简化地形网格
- 从样例可以看到很多顶点很巧妙地align到山体上
- 虽然难以调整,但是三角形数量少带来地数据少了很多

- 现代GPU提供了很方便的动态扩展实现


- 早期的CPU通过各种shader提供实现
- Hull Shader 生成了一个细分表面(subdivision surface)的patch. 这个patch表示一小块的几何区域,可以让平面变成球面。
- Tessellator shader 雕花流程
- Domain shader 地形起伏

- DX12已经可以通过小片的Mesh lite来完成细分

- 当需要产生地面痕迹效果时:
- 假设地面以下有一个个小弹簧,受到压力弹簧就压下去了,同时一点点的把物质向上挤
- 黑悟空的dirform slow ground(地形缓慢变形)效果就是dynamic terrain的效果
Non-Heightfield Terrain

- 把要挖掉地方的顶点做个标记,这样的顶点在Vertex shader里输出是NAN–无效整数.
- 现代GPU会把包含这种顶点(Position为None)的三角形视为退化三角形, 全部干掉.

- 地形如果通过体素化的方法在三位空间上采样一堆点,每个点存一个权重值代表空间的物质密度
→ 就不用通过上面的方式去挖洞然后再插入一个新物体.

- 如果你在空间上有一些采样点,可以找到它的一个等质面(在上下左右找8个点),
通过14种方法切分这个cube形成一个水密的三角面片集把这个形状表达出来。 - CT的扫描点最后生成形状就是通过这个方式生成的.

- Volumetric + Marching 用于地形算法的研究样例

- 世界需要更自由的变化,这种算法适用于增加更多的交互
Paint Terrain Materials

- 分组存储不同地形材质的各种信息,然后加上Splat混合贴图(每个channel对应一种材质的权重)生成一个最终的材质

- 这种混合方式在跨区域变化会不够真实

- hack: 在过渡过程中如何发现要混合两种材质,把height用权重做调整–height高权重下降慢,height低很快就退掉。
- 在两种材质间的切换是0~1切换,在相机移动时会出现抖动, 远处低视角观察会出现sharp.

- hack+: 通过扰动来优化

- 通过Texture Array存储游戏中各种材质。
- Texture Array的材质只通过index查询,然后最后通过权重值去混合。

- Parallax→只能产生视觉上的效果,实际是光滑的
- Diplacement→通过hack算法去修改地形


- 为了解决材质混合的高开销问题
- 只把用到东西才放到内存中,内存占用不用超过阈值

- 通过避免多次数据交换来提速,比如让显存从硬盘直接读取

- 浮点数摄像机观察距离非常远的时候精度不够, 会导致闪烁

- 把庞大的世界坐标系转换为相对坐标系来避免精度不够
Other objects On the Terrain

- 近处通过mesh表达,远处是插片来表达

- 草,灌木丛,小碎石等装饰物 --> Decorator

- 通过spline样条线来创建,但是需要对高度场处理
- decals: 贴花来增加多样性
- 这些都可以提前烘培到virtual texture
天空和大气 Sky and Atmosphere


- 两个影响参数
- 观察者向上看的角度–到天顶的夹角(0~Π)
- 现在看的高度和太阳的夹角

- 空气中各种微小粒子(如气溶胶)会影响光线的传播

- 将光学现象进行拆分
- 吸收 Abosrpition
- 向外散射 Out-scattering
- 自发光传播 Emission
- 来自于球面其他光的共享 In-scattering
- 通过上面的分解建立辐射传递方程

- 基于体积的渲染:通过M点开始的传播获路径积分来获取最后结果
- M点到P的路径投影积分
- M点到P的路径下小分子的光学现象叠加

- 真实世界大气中可见光拆分




- 天空的颜色和太阳光传播时候经过大气折射分解后的情况有关















云的处理

早期解决方案





- 使用噪点去产生变化也是非常用的一种算法

