案例学习——Unity基于体绘制的大气散射shader

本案例学习资料来源
Volumetric Atmospheric Scattering

0 效果展示

先看看实现的效果(米氏散射和瑞利散射结合的地球大气+云层+地球昼夜)
在这里插入图片描述
在这里插入图片描述

1 引入

抬头望天,我们会发现天空经常是蓝色
在这里插入图片描述
日出日落时天空经常会是红色
在这里插入图片描述
这样的光学现象主要是光进行了瑞利散射(Rayleigh scattering),本文依照AlanZucconi大神的教程,介绍如何对大气散射进行数学建模,来重现这些大气中的视觉效果。

1.0 介绍

对于传统的渲染技术,会假设物体是一个空的外壳,我们在外壳表面即可进行所有效果的计算。这种简化方式对于渲染物体表面来说是很高效的。

但是有些效果是由于光穿透了物体才能实现的,比如半透明物体正是如此。不过聪明的人们也研究了一些快速近似半透明物体的方法(GDC 2011 – Approximating Translucency for a Fast, Cheap and Convincing Subsurface Scattering Look)。

但是大气就很难这么做了,因为天空并不是一个“物体”,我们不能只是渲染表面的壳,我们还需要模拟光线在大气中到底经历了什么。

不光光渲染壳,同时也要渲染物体内部的光线传播,这个技术通常被称为体积渲染/体绘制(volumetric rendering),在本文的上一篇文章做出过一些小的探讨(比如光线步进和有向距离函数)。

不过仅是这样还不足以模拟大气散射,接下来会介绍一种更合适的方法,被称为体积单次散射(volumetric single scattering)

1.1 单次散射(Single Scattering)

在游戏引擎的基本光照模型实现中,都假设光线在真空中传播,所以物体的表面属性往往是影响光照的唯一因素。

然而在物理上,传播媒介对光的影响也是很重要的,对于大气来说,穿过的空气多少或者空气的成分就很能影响光照的效果。

在图形学进行大量的简化之后,空气影响我们感知光线的方式,通常会分为两种,分别是出射散射(Out-Scattering)入射散射(In-Scattering)

1.1.1 出射散射(Out-Scattering)

出射散射也就是光子打中空气分子后,原本要射向摄像机的光线进行了偏转,光线的方向进行了改变。
在这里插入图片描述
对于一个大光源来说,能够发射出很多很多光子,因而在空气中传播时经常会发生出射散射。
空气密度越大,光线传播的距离越长,出射散射发生的光线偏转越多,对光线的削弱效果越明显。
在这里插入图片描述

1.1.2 入射散射

与出射散射相反,本来不指向相机的光线也可能被偏转到相机的方向,这就是入射散射。
在这里插入图片描述
入射散射允许相机看到不在可视范围内的光源,比较明显的例子就是光晕,比如下图由于Particle的偏转,会让人觉得沿着视线和Particle的连线处有光线,看起来也就是光晕。
在这里插入图片描述

1.2 基于体绘制的单次散射模型(Volumetric Single Scattering)

光线在实际传播当中会偏转很多次,就像下图这样
在这里插入图片描述
进行仿真是光线追踪的内容,对于本文来说,我们只考虑单次散射——即光线从太阳发出过、只经过一次散射改变方向后射入我们的眼睛。

对于渲染一个行星的大气,我们会逐步构建一个模型,首先我们考虑相机
在这里插入图片描述

  • 摄像机的视线从A处进入大气,经过B处
  • 我们计算光线从B到A的过程中,每一个位置P造成的出射散射的衰减贡献&入射散射的叠加贡献

该模型中也存在光源的贡献,我们通常假设是太阳的光线经过入射散射的偏转来到我们眼前
在这里插入图片描述
太阳在照射到P的过程中也存在出射散射
在这里插入图片描述
总结这些部分,混合在一起,也就是如下的样子
在这里插入图片描述

  • 相机的视线从A进入,经过行星大气到B
  • 我们需要去计算AB段上每一点P的散射贡献
    • P点接受的光线都来自于太阳
    • P点接受的光线进入大气层时会受到出射散射的影响
    • P点接受的光线经过入射散射偏转进入摄像机,途中又会经过出射散射偏离

2 大气散射背后的理论

2.1 透射函数

为了计算传入相机的光线有多少,我们可以先考虑一段光线,如下图所示
在这里插入图片描述

  • 光线从太阳传到C,此时是真空,所以没有损失,我们用 I C I_C IC指代C点的光强
  • 在从C到P的过程中,经过出射散射,光强会衰减,我们用 I P I_P IP指代P点的光强
  • I P I_P IP I C I_C IC的值也就是透射率(transmittance)
  • 透射率 T T T表示在某段路径上的对光照的衰减程度。 T ( C P ‾ ) = I P I C T(\overline{CP})=\frac{I_P}{I_C} T(CP)=ICIP
  • 对于某一个值的透射率 T T T,P点的光强也就是 I P = I C ∗ T ( C P ‾ ) I_P=I_C*T(\overline{CP}) IP=ICT(CP)

2.2 散射函数

P点在接受光照后,会因为散射偏转一部分
于是我们需要散射函数 S S S来表示某一方向上光线的偏转情况。

如下图,那些偏转了 θ θ θ角的光线才能被指向A点的摄像机
在这里插入图片描述
S ( λ , θ , h ) S(λ,θ,h) S(λ,θ,h)的值来代表发生了 θ θ θ度偏转的光线比重。

λ λ λ代表光线的波长, θ θ θ是偏转角度, h h h是P点的离地高度(高度会影响大气密度,密度会影响散射程度)

于是我们可以得到从P点出发到A点的光强了
在这里插入图片描述
带入之前求出的 I P = I C ∗ T ( C P ‾ ) I_P=I_C*T(\overline{CP}) IP=ICT(CP)
在这里插入图片描述
整个过程是这样

  • 光从太阳进入 C C C点,真空中无影响
  • C C C点进入大气传到 P P P点,受到出射散射影响只有占比 T ( C P ‾ ) T(\overline{CP}) T(CP)的光线到达了 P P P
  • P P
评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值