Cesium中实现太阳丁达尔效应体积光

体积光的物理意义

当光线穿过胶体,由于胶体微粒对光线的散射作用,产生丁达尔现象。在实时渲染中这样的效果常称为体积光 (Volumetric Light),有时也称作上帝光 (God Light),或叫做Light Shaft、God Ray。

体积光应用例子

常见的体积光实现方式

在实际渲染中,实现体积光的方式有很多种。下面简单举例几种常见的方式。

基于Billboard的体积光

基于Billboard的体积光很简单,直接在需要体积光的地方放上特效贴片,模拟出灯光即可。

Billboard体积光效果

这种方式比较简单,效果也还过得去。尤其是用于远景的体积光表示是很合适的。但是对于近景,尤其是观察角度比较自由的情况下就容易穿帮。并且不太适用于大场景。

基于后处理的体积光

基于后处理的体积光从实现方式上来说,比较类似于高亮后处理。基本只是模糊的方式不一样而已。

后处理的实现步骤大致是:

  1. 渲染整个画面
  2. 只保留能够产生体积光的物体,其他部分discard
  3. 对保留下来的部分进行径向模糊
  4. 将径向模糊后的内容与原图进行叠加

后处理体积光原图
后处理体积光处理过程

这个方法的效果不错,消耗不大,而且效果可以独立控制,但是有个硬性要求是光源必须能够看见。另外,体积光的那种颗粒感和不均匀的线条感很难得到。如果改用更复杂的后处理算法的话,消耗会增加得比较厉害。

Unreal中采用bloom method渲染的体积光也是基于这个思路。

基于RayMarching的体积光

Ray-Marching 简单的说就是步进光线,常见的体渲染基本都是通过这个方式来实现的。

RayMarching的实现步骤大致是:

  1. 从屏幕像素点出发发射光线
  2. 光线步进,并计算每个步进点的光源亮度
  3. 叠加所有步进点的亮度

RayMarching体积光

这种方式实现的体积光具有真正的“体积”,相比于其他方式有更多的变化,也更加真实。但是这种做法往往需要迭代几十次,因此对性能的消耗很大。

Cesium中实现体积光

由于Cesium本身需要承担大场景的渲染,因此为了兼顾性能和效果,这里选用后处理的方式来生成体积光。

基本实现原理前面已经提过了,在Cesium中实现起来是一样的步骤。

只是这时候径向模糊的方向是根据太阳的方向来计算的而已。

同时为了避免太阳移出视野外没有God Ray的情况,所以使用整个天空作为整个光源来模糊。

直接看效果吧。

实际效果展示


Cesium中实现太阳丁达尔效应体积光
https://www.liaomz.top/2023/11/17/cesium-zhong-shi-xian-tai-yang-ding-da-er-xiao-ying-ti-ji-guang/
作者
发布于
2023年11月17日
许可协议