大气散射 GPU Gems2 Chapter 16. Accurate Atmospheric Scattering

效果图

这次先上效果图*4

散射概念

光线击中空气中的微小颗粒后的偏折导致了光线的散射。我们看到的阳光应该是由视线上的散射在视线方向上的集合。如果由地面的反射,还要加上经过散射计算的地面反射。

Rayleigh散射

由较小的空气分子引起的散射,对不同波长的光有不同的散射程度,蓝色最强。也就是天空为啥是蓝色的原因。

Mie散射

由较大的漂浮颗粒(气溶胶……PM2.5????)导致的散射

相位方程

相位方程描述有多少光会倍散射到相机方向上。


θ:采样点处光线(太阳到采样点)和视线(相机到采样点)的角度。

g:影响对称性,对Rayleigh散射,g可以取0。对Mie散射,g一般是在-0.75到-0.999之间。

外散射

就是计算散射对光的影响


:外散射是向散射点为球心的球面上均匀散射的,所以这个是球表面积,单方向的散射就没有4π了

光深(optical depth ): 就是公式的积分部分,可以理解为两点间的平均大气密度,这个值显然跟高度有关系。h就是归一化之后的采样点高度。H0大气平均密度高度,可以理解为在这里密度是1。选取的值是0.25。

散射系数K(λ):散射系数,这个系数跟海平面大气密度有关,也跟波长有关。不过rayliegh和mie都有所不同,比如大部分mie的实现是忽略波长的。

内散射

散射在视线方向上的集合,整个公式就是不进行球面积分的散射。

采样点处的两个外散射:采样点到相机和太阳到采样点的散射

Is(λ):光强度,可以在这里修改太阳光色,正常按白色就可以差不多。

表面散射

表面散射就是将地表的反射光/自发光进行到相机的散射处理

Ie(λ):地表发出的光(反射/自发光)。这有两个方案:1.认为地表自发光,地表的颜色就是这个值。2.认为地表的光是反射,在计算反射之前,要算上入射光经过大气层的散射,所以这个值要比没有大气直接反射小。

注意:这个方案中忽略了反射方向上的散射积分,所以地表颜色会有点片暗。

简化计算

进行归一化,将从海平面到大气上界的高度值scale到0~1

预计算查询表

将积分采样计算预先进行,生成相应的查询表

太阳光在大气内散射的预计算

将阳光认为是平行光,此时可以用高度和与平行光的角度来描述大气层内的任意一点,不唯一的点数值也都是一样的。

更好的预计算方法

上一个预计算方法只能解决两个外散射计算中的太阳光散射部分,怎么把视线散射部分也解决?
对于一个均匀大气层来说,任意一点按一定角度到任意方向大气上界的射线,都可以用射线发起点高度,和一个偏移角来描述。这个射线可以既可以用在光线方向的散射计算,也可以用在视线方向的散射计算,只要能描述两条射线就都没问题。
这样只要预先计算采样射线上的光深和大气密度(exp(-h/H0)),这样两个外散射积分就都不用计算了

使用预计算表注意

预计算表存的都是从采样点到大气上界的值,要是相机在大气内,是需要剪掉同方向上从相机位置到大气上界的相应计算结果的。
这种情况下如果采样点(定点)在相机上方,有可能出现计算用的射线穿过地表的情况,这个时候在低精度的shader中肯定由精度问题。于是将射线方向反转,向采样点方向取两个射线,计算结果是一样的(距离一样)。

Shader实现

shader的思路是不使用预计算,而用结果近似的简单计算。用一点效率来降低shader的硬件需求。

消除预计算表取值

使用x=0(海平面)的曲线将其他采样曲线归一化得到这个结果

v = exp(-4x)*scale(y)

scale(y),就是海平面处的曲线。这样x轴就被干掉了
这个scale曲线并没有什么通用的方案,是使用曲线拟合获得的一个多项式计算公式。于是这个实现有一个问题就是:**如果scale height(平均密度高度)不是0.25(从海面到大气上界的25%),这个scale的近似公式就要重新进行曲线拟合**

4个shader

首先地面和天空的顶点计算完全不同。另外要解决之前提到的大气内取值的问题,在大气内会有一些计算是大气外不需要的。为了减少shader内的逻辑判断所以分成4个shader,从大气看地面,从宇宙看地面,从宇宙看天空,从大气看天空。

一些奇怪的参数

有一些参数非常的怪异,文章中并没有什么说明。稍微说一说,省得以后自己忘了。
单位:波长的单位一般是nm,10^-9m。海平面分子数密度,2.55*10^25。 这种计算float基本不行了,所以在单位上要进行一些修正。由于Rayleigh中的散射系数是跟λ^4相关的,将λ变成10^-3单位,每个乘了10^6,4次就是10^24。这就几乎没有0 了。

Kr,4πKr:Kr是Rayleigh的散射系数。这里取值是0.0025。

我计算了一下β

这个结果和
[Efficient Rendering of Atmospheric Phenomena]中的基本相似

但是这时计算的K是 9.3 * 10^-8 这个我立刻就方了。根本不一样好不好,差好几个数量级呢!(差了3.72*10^-5)

我现在还没有想通,猜测有两个方向:1.光深计算上的区别,2.高度归一化的影响。四处看了几天也没有结果,下次我继续搞Eric.Bruneton那个计算了多重散射的再继续研究

Km,4πKm: Km是Mie散射的系数,也一样有很让人迷惑的计算结果

g:一个影响散射对称性的参数。
[Display_of_The_Earth_Taking_into_Account_Atmospheric_Scattering]里面有一点说明,不过更详细的在另外一篇文章。

u和空气质量相关,0.7~0.85

不过基本上对Rayleigh散射g=0,对Mie散射在-0.75到-0.999之间

---

需要测试的问题以及额外的研究

大气内shader
生成预计算表,改成取值形式的shader
g对散射效果的影响
H0对散射效果的影响
参与散射的云
分开Mie和Rayleigh的相关计算
表面散射使用反射机制
表面散射增加视线上的散射积分
HDR 更丰富的战线

题外话

在研究散射系数的时候真的是很有一点挫败感,感觉虽然GPU Gems这书里面提供了一个很好的实现,但是道理讲得就有点模糊,想要继续挖掘的时候就显得很尴尬。
之后会作几个简单的改进,至少实现预计算取值形式的shader和简单的工具。再之后的……如果有作宇宙题材游戏的机会再进一步研究吧

时间: 2024-11-05 04:54:34

大气散射 GPU Gems2 Chapter 16. Accurate Atmospheric Scattering的相关文章

三维引擎设计专题--大气散射特效

在做GIS时, 地球周围会有一个大气圈, 大气散射, 这个方面的算法是计算机图形学界不断深入研究的领域, 不过目前有几个成熟的散射算法. 我借鉴了<<GPU精粹2.高性能图形芯片和通用计算机编程技巧>>第16章的算法,实现了一个大气散射. 效果如图. 图中蓝色的天空,就是散射的效果, 具体算法请自行查看书上的算法吧. 步骤: 1: 创建一个椭球, 生成顶点,与顶点索引数组.  这个椭球生成算法后续贴出来. 2: 根据算法传递uniform, 运行shader 3:关于影像,高程的处

chapter 16

Chapter 16 # string class Constructors (Page 952) string(const char *s) string(size_type n, char c) string(const string &str) string() string(const char *s,size_type n) template<class Iter> string(Iter begin, Iter end) string(const string &s

《JavaScript高级程序设计》Chapter 15 canvas + Chapter 16 HTML5

Chapter 15 Canvas Chapter 16 HTML5 Chapter 15 Canvas <canvas>元素:设定区域.JS动态在这个区域中绘制图形. 苹果公司引导的.由几组API构成. 2D上下文普及了.WebGL(3D上下文)还未足够普及. 基本用法 首先:width.height属性确定绘图区域大小.后备信息放在开始和结束标签之间. getContext():DOM获得这个canvas元素对象.再在这个对象上调用getContext()获取上下文,传入参数表示获取的是2

零元学Expression Blend 4 - Chapter 16 用实例了解互动控制项「Button」II

原文:零元学Expression Blend 4 - Chapter 16 用实例了解互动控制项「Button」II 本章将教大家如何制作自己的Button,并以玻璃质感Button为实作案例. ? 本章将教大家如何制作自己的Button,并以玻璃质感Button为实作案例 ? ? 01 拉出一个圆 请以Ellipse拖拉出一个圆形,并修改圆形的颜色 范例: Fill->Gradient brush->Radial gradient(0%.#FFFF0000)(100%#FF000000) ?

深度学习 GPU环境 Ubuntu 16.04 + Nvidia GTX 1080 + Python 3.6 + CUDA 9.0 + cuDNN 7.1 + TensorFlow 1.6 环境配置

本节详细说明一下深度学习环境配置,Ubuntu 16.04 + Nvidia GTX 1080 + Python 3.6 + CUDA 9.0 + cuDNN 7.1 + TensorFlow 1.6. Python 3.6 首先安装 Python 3.6,这里使用 Anaconda 3 来安装,下载地址:https://www.anaconda.com/download/#linux,点击 Download 按钮下载即可,这里下载的是 Anaconda 3-5.1 版本,如果下载速度过慢可以选

大气散射 Aerial Perspective

http://mathinfo.univ-reims.fr/IMG/pdf/PreethamSig2003CourseNotes.pdf https://blog.csdn.net/toughbro/article/details/7800395 Modeling Skylight and Aerial Perspective 大气的构成 有厚度 成分不一样 会发生散射  地球是圆的 朝一个方向上看的时候 光经过的大气层厚度不一样 颜色就不一样 小粒子的散射模型 Rayleigh scatter

大气散射模型的推导过程

大气中粒子的散射作用是产生雾霾的主要原因.无论是用人的肉眼观察,还是从拍摄获取的图像中观察,雾天的景象总是存在对比度和视野降低的问题.1925年,Keim & Nemnich[1]等人提出雾天图像能见度较低是大气中的悬浮粒子对光的吸收和散射造成的.1976年,John Wiley & Sons[2]等人提出粒子的散射作用造成目标和相机之间光在传输过程的衰减,并且增加了一层大气散射光(Airlight).1999年,针对雾天能见度低的问题,Srinivasa G. Narasimhan[3]

零元学Expression Blend 4 - Chapter 16 用实例了解交互控件&ldquo;Button&rdquo;II

本章将教大家如何制作自己的Button,并以玻璃质感Button为实践案例. 本章将教大家如何制作自己的Button,并以玻璃质感Button为实践案例 01 拉出一个圆 请以Ellipse拖拉出一个圆形,并修改圆形的颜色 范例: Fill->Gradient brush->Radial gradient(0%.#FFFF0000)(100%#FF000000) 02 把圆形转换成控件 选取圆形,并且在圆形上单击鼠标右键->Make Into Control 点选Button以及命名完成

Atmospheric Scattering in Unity5

本次实践效果仅有Atmospheric Scattering和AA,并无其他post-processing,看到类似depth of field等的效果全部是Atmospheric Scattering的效果!! 总共改进三次,一次比一次效果真实,下面上三个版本的效果图 ver0 ver1 no Rayleigh scattering&Mie scattering with Rayleigh scattering&Mie scattering point light ver2 博主近期渲染