Cesium中实现全球体积云
RayMarching
RayMarching 也就是光线步进,是 3D 图形学中的一种渲染方法,常常用来作为体渲染的主要渲染方式。
基本实现原理是,在每个像素上计算一条光线,当光线进入体纹理范围内后,将光线细分成更小的光线片段进行步进迭代,每次步进时计算相应的强度信息。最终迭代结束后,将所有步进结果进行叠加计算,得到像素的颜色。
体积云
体积云是利用 RayMarching 方式渲染的云效果,在一些大型游戏中很常见。
与其他渲染云的方式不同,体积云是真正具有体积感的云,一个最简单的区分方式是,体积云能够进入到云的“内部”。
如何渲染云
体积云的渲染步骤大致为:
- 计算每个像素的光线方向
- 计算沿光线方向是否能够和体积云范围相交
- 获取相交范围,并在该范围内进行光线步进
- 根据步进结果计算云的基础形状(也就是云的密度)
- 计算云的光照
而其实,上面列的步骤中,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;
}
}
计算云的光照
通常,体积云的光照分为两个部分:
- 总光能(当前位置接收到的总光能)
- 光能反射比例(当前位置的总光能有多少能够进入到眼睛)
总光能
在每一个点,向光源方向再做步进,累加噪声值得到该点在光源方向的“深度”。
举个例子:
在某点向光源方向做 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 体积云
原文链接
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!