Cesium中实现全球体积云

2023-12-19 06:34:45

RayMarching

RayMarching 也就是光线步进,是 3D 图形学中的一种渲染方法,常常用来作为体渲染的主要渲染方式。

基本实现原理是,在每个像素上计算一条光线,当光线进入体纹理范围内后,将光线细分成更小的光线片段进行步进迭代,每次步进时计算相应的强度信息。最终迭代结束后,将所有步进结果进行叠加计算,得到像素的颜色

在这里插入图片描述

体积云

体积云是利用 RayMarching 方式渲染的云效果,在一些大型游戏中很常见。

与其他渲染云的方式不同,体积云是真正具有体积感的云,一个最简单的区分方式是,体积云能够进入到云的“内部”

在这里插入图片描述

如何渲染云

体积云的渲染步骤大致为:

  1. 计算每个像素的光线方向
  2. 计算沿光线方向是否能够和体积云范围相交
  3. 获取相交范围,并在该范围内进行光线步进
  4. 根据步进结果计算云的基础形状(也就是云的密度)
  5. 计算云的光照

而其实,上面列的步骤中,1-3 均为 RayMarching 的实现。因此事实上,真正渲染体积云的步骤只有两个:计算强度和计算光照。

云的密度:
云的密度

云的光照:
云的光照

计算云的密度

体积云的密度计算比较简单,只需要在 RayMarching 的过程中,采样相应的噪声图,并累加噪声结果,直到达到噪声最大值或者结束步进。

最终累加的结果就是云的密度。

float cloudDensity = 0;
for(int iii = 0; iii < _Iteration; iii++) {
    float3 stepPos = startPos + iii * _StepLength;
    cloudDensity += SampleNoise(stepPos);

    if(cloudDensity > MaxCloudDensity){
      cloudDensity = MaxCloudDensity;
      break;
    }
}

计算云的光照

通常,体积云的光照分为两个部分:

  1. 总光能(当前位置接收到的总光能)
  2. 光能反射比例(当前位置的总光能有多少能够进入到眼睛)
总光能

在每一个点,向光源方向再做步进,累加噪声值得到该点在光源方向的“深度”。

举个例子:

在某点向光源方向做 8 次步进,前 3 次在云的内部,后 5 次在云的外部。

该点的深度为(1 + 1 + 1 + 0 + 0 + 0 + 0 + 0)/ 8 = 0.375。

光能反射比例

我们算出了一个点接收到的总光能,但这些光能只有一部分能反射到我们的眼睛(摄像机)。

从该点向摄像机方向做步进,累加噪声值得到该点在摄像机方向的“深度”,深度越大损失的光能越多。

传递到摄像机的光能 = 接收到的总光能 - 中途损失的光能。

蓝噪声

体渲染通常对性能消耗是很大的,因此为了保证帧数,体积云的渲染会采用较低的步进次数,这样做会导致云渲染出现分层。

为了解决这种问题,通常需要使用噪声对步进的起始点进行扰动。

椭球体

由于 Cesium 是 GIS 相关的渲染引擎,因此体积云必须考虑适配 Cesium 的地球形状。

解决方式是,以云最低高程和最大高程,依据 WGS84 椭球外扩两个椭球范围。并以这两个椭球范围作为体渲染的范围进行 RayMarching 计算即可。

实际效果展示

Cesium全球体积云

参考资料

RayMarching 实时体积云渲染入门(上)
RayMarching 实时体积云渲染入门(下)
体积云渲染(Volumetric Clouds),技术美术教程
Unity URP RayMarching 体积云

原文链接

Cesium中实现全球体积云

文章来源:https://blog.csdn.net/weixin_43481439/article/details/135063803
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。