赞
踩
环境光贴图: 一张图,图上记录着场景中任意方向的来自无限远的光照是多少。场景中任何位置的物体接收的光照都是一样的,因为应用同一个贴图。
场景中已经应用了一张环境光贴图,如何计算物体的着色?(不考虑可见性项)
IBL
:基于图像的光照计算,即光照信息是从图像中获取,在渲染方程中的体现为入射光Li。并且我们认为,着色点不存在遮挡问题即不考虑可见项。
一般方法:蒙特卡洛(不适用)
,数值解、需要大量采样。缺点:特别慢,实时渲染中不可用。只要涉及采样,都会特别慢。
如何解上述方程并且避免采样???
观察
不太smooth
,但也还能接受smooth
马上考虑到把 乘积的积分 拆成 积分的乘积
就是在一定条件下,把积分拆开计算,得到近似的结果
积分域比较小
or 值比较smooth(最值相差不大)
的情况下比较准确。注意:
Ω
G
Ω_G
ΩG为g(x)的积分限积分域较小(glossy)
、smooth(diffuse)
为了得到着色点的环境光计算结果,这个公式分为了两部分
Stage 1:左半部分计算
采样
BRDF范围的贴图上的光照强度,然后求均值
采样太慢了,不想采样
这里就引出一个思想:预计算(Pre filtering)环境光照
查询
上面公式的左半部分的值,不用采样
,更不用计算Stage 2:右半部分的计算
现在虽然已经有更好的解决方案,但是接下来的方法很经典 必须掌握
如何避免采样 —— 同stage1的思想,预计算
如果此处的BRDF采用微表面模型(Microfacet BRDF)来描述,如何用预计算来减少工作量呢?
Fresnel term —— 颜色
NDF term —— 表面法线分布
NDF中 θ h θ_h θh可以用入射角θ通过一定的方式来表示,从而降低至三维,对预计算来说,三维依然太高,如何能将参数的纬度降低至2维?
2个变量(入射角、吐槽度)
,所以只需要两张texture(分别对应两个积分的预计算结果),甚至省一点,一张texture的两个通道存放预计算结果。渲染时根本不用计算,直接查询以上便是借助Split Sum方法进行预计算,从而完成IBL下物体的着色计算
UE4中的Split Sum应用效果
避免采样
,效果非常好,很接近离线渲染的效果了不考虑阴影:使用Split Sum方法进行IBL下的着色计算,确实能得到很好的效果,并且与计算好后,渲染时能够极快的查询到结果
考虑阴影,则计算难度就不同了,几种不同的视角看待环境光贴图中的光源
环境光贴图下的阴影计算相关研究:imperfect shadow maps 、light cuts(离线)、实时光线追踪、PRT
这里主要学习PRT,而学习PRT之前必须了解什么是 球谐函数
前置基本概念
把任何两个函数乘积的积分看做filtering操作
∫
Ω
f
(
x
)
g
(
x
)
d
x
\large \int_{Ω}{f(x)g(x)}dx
∫Ωf(x)g(x)dx
基函数(Basis Function): 一系列用来表示其他任意函数的函数
B
i
(
x
)
\mathbf{B_i(x)}
Bi(x)。比如傅里叶展开、泰勒多项式展开
f
(
x
)
=
∑
i
c
i
⋅
B
i
(
x
)
\large f(x) = \sum_{i}c_i·B_i(x)
f(x)=i∑ci⋅Bi(x)
球谐函数SH:一系列定义在球面上的2D基函数 B i ( ω ) \mathbf{B_i(\omega)} Bi(ω),可以理解为关于方向的函数,三维空间的方向可以用两个角度描述(θ、φ)。
球谐函数的可视化
对于任何一个原始的函数,都能用一堆基函数和系数来描述
环境光贴图就是一个二维的函数,光照值为立体角的函数,因此环境光贴图可以用一系列基函数表示!可以把这个函数投影到任意阶数的HS的基函数上,用前n阶的球谐函数来恢复这个二维函数的低频信息。越高阶占用的存储空间越多,能恢复出来的频率越高
投影(Projection):已知任何一个2D函数
f
(
ω
)
f(\omega)
f(ω)都能用一系列基函数的和来表示,而计算每个基函数的系数
c
i
\large{c_i}
ci的过程就是投影。求解公式为
c
i
=
∫
Ω
f
(
ω
)
B
i
(
ω
)
d
ω
\large \color{red} c_i=\int_{Ω}{f(ω)B_i(ω)dω}
ci=∫Ωf(ω)Bi(ω)dω
在明白球谐函数后,得到系数的过程叫投影,思考一下空间中的一个点如何表示的?
投影
点乘
,,积分本质是连续求和,如果用离散的思维来考虑,每个
ω
ω
ω对应一个
f
(
ω
)
f(ω)
f(ω)和
B
i
(
ω
)
B_i(ω)
Bi(ω),遍历所有ω,得到的其实是两个向量,而两个向量的乘积就是 点乘
;因此可以很容易的看出上面的基函数系数计算本质就是 点乘再连续求和
。应用球谐函数:不考虑阴影的情况下,环境光照下diffuse物体的着色计算
Prefiltering + single query == no filtering + multiple queries
Prefiltering
,再沿着某个方向进行1次查询
,结果如右图所示,像一个diffuse小球,等价于不Prefiltering
,往任何一个着色点的法线方向的球面多次查询
,取平均再看Render Equation。被积函数有两个,逐点相乘后积分起来,这就是 点乘
,
L
i
L_i
Li是环境光贴图提供,而环境光贴图相当于一个 二维的球面函数
,初步考虑能用SH函数来表示,问题是存多少阶合适呢?
低通滤波器
。所以Li 不管高频有多少,只要乘上漫反射BRDF项后,根本就没有高频信息留下来!因此,利用这个信息,既然任何环境光贴图在漫反射物体上的着色结果都只有低频信息,那 直接用低阶SH来表示环境光贴图不就好了
SH的美丽属性(下面diffuse案例结尾中还有补充)
正交性 任何两个基函数互相垂直,自己投影自己为1,不同的基函数相互投影为0
投影计算简单,任意一个函数可以投影到任何基函数上,做product integral即可
SH预计算好的光照可以任意旋转,重新计算基函数的系数代价很低。如果旋转光照,等于旋转SH的所有基函数,而旋转任何一个基函数,都可以用同阶的基函数线性表示,所以只要查表就能得到旋转后的光照所对应的SH基函数的线性组合
少量几个基函数,就能很好的还原球形函数的低频信息。下图N代表基函数个数(高频信息想要很好地还原需要很大代价)
只要确定阶数,则基函数就确定了,不确定的只有系数,可通过投影得到。(个人猜测)
球谐函数跟平时常用的XYZ坐标系一样,每个基函数都是互相垂直的坐标基,因此SH基函数也构成了一个SH space(个人猜测)
足够多的基函数能表示任何函数
保留某个频率以下的内容,只需要取前面的一部分基函数就能重建原函数,得到原函数的低频信息
如果两个函数都是SH的基函数表示,那么他们其实就是点乘
实时渲染中,环境光照下考虑可见性(阴影)
的Render Equation
可简写成下面这样
环境光照
、可见性
、BRDF
分别可以球面函数(6张贴图)表示。(由于相机位置固定(o为常数),BRDF就只剩两个参数了(i入射角拆为天顶角,方位角),所以也能看做是球面函数)SIGGRAPH 2002中的这篇论文提出了PRT技术
PRT基本思想:假设整个场景 只有光照可以发生变化
(光照可以旋转、可以更换),该着色点的其他部分如BRDF、可见性、相机位置都不变。总之被积函数分为两部分,lighting
部分以及与lighting无关的light transport
部分,并且这两部分都能用球谐函数表示。
Light Transport部分就像其命名一样,描述光如何从入射
L
(
i
)
L(i)
L(i)变化到出射
L
(
o
)
L(o)
L(o)
旋转、替换环境光贴图后,需要重新预计算SH组合
不随光源变化的
性质
向量点乘
矩阵-向量乘法
lighting
部分可以用SH表示,然后可以把系数部分的求和提出来,因为系数
l
i
l_i
li与积分变量
ω
i
ω_i
ωi无关
实时渲染中
积分符号
与求和符号
可以认为是等同的(连续和离散的区别嘛)
投影
,投影就是在算基函数
B
i
B_i
Bi的系数(这里注意,外面的
l
i
l_i
li是Lighting部分用环境光函数投影出来的系数,假设是前3阶,则应该是9个系数求和)。积分内预计算结果就是用不同于
l
i
l_i
li的另一组 系数
向量点乘
下一节课中有提到另一个思路:
- 把lighting和transport部分都用SH替代
- 然后渲染方程可以变成这样两部分
- 积分外:两套系数的双重求和,乍一看是一个矩阵的所有元素的和(每个元素都是 c p c q c_pc_q cpcq的乘积)
- 积分内:俩基函数的互乘。p==q时,结果为1;p≠q时,结果为0。
这里也间接印证了我的前面的在SH美丽的属性部分的猜测吧?两部分的原函数不同,但是都转换成SH表示的话,下标相同的基函数是同一个基函数,所以点乘为0。百度了一下确实存在基函数表这种东西
- 因此:实际上仅当p==q时,结果不为0,也就是说除了主对角线,其他部分都是0,因此依然是两个向量/两套系数做
点乘
PRT Diffuse总结(SH函数性质的部分补充):
任何球面函数,用SH来表示后,其实就是一个 系数向量
系数向量计算方式为投影,即把原函数投影到SH空间中,即product integral
l
i
=
∫
Ω
L
(
ω
)
⋅
B
i
(
ω
)
d
ω
l_i=\int_ΩL(\omega)·B_i(\omega)d\omega
li=∫ΩL(ω)⋅Bi(ω)dω
对原函数的还原只需要用每个系数与对应的基函数相乘后相加即可,也就是个点乘,一个系数向量,一个基函数向量
L
(
w
)
≈
∑
l
i
B
i
(
w
)
\displaystyle L(w)\approx \sum l_iB_i(w)
L(w)≈∑liBi(w)
效果
diffuse部分结束
与diffuse不同的地方在于,glossy的brdf不是一个常数,是一个4D函数(io分别两维),它的o与视点是有关的,不同视角/入射角度的反射率都不同
把 L ( i ) L(i) L(i)用SH表示很简单,跟diffuse案例中是一样的
而Light transport部分就不一样了,因为diffuse的brdf是常数,不用考虑,而glossy部分的brdf既是i
的函数,也是 o
的函数,这就很麻烦了。
如果仅仅是i的函数也还好,因为transport部分依然为2D球面函数,可以用球谐函数表示。关键还是o的函数,即每更换一个相机位置 o
,就要重新投影得到一组系数,因此最终着色点的计算是向量·矩阵。
注意下面公式省略了中间一些过程,即
L
(
i
)
L(i)
L(i)用SH表示,系数求和提到积分外,积分内的基函数用于transport部分的投影计算,最终得到下面的
L
(
o
)
≈
∑
i
l
i
T
i
(
o
)
\displaystyle L(o)\approx\sum_il_iT_i(o)
L(o)≈i∑liTi(o),必须看懂这个看起来简单的式子(
∑
T
i
(
o
)
\sum T_i(o)
∑Ti(o) 相当于二维矩阵,
T
i
j
T_{ij}
Tij,即不同相机角度o对应不同的
T
i
T_i
Ti向量,L(o)最后得到的是一个向量,确定o才能确定具体着色结果)
T
i
(
o
)
T_i(o)
Ti(o)又是一个球面函数
,又能投影到SH 空间中去,但是这个过程略有不同,
因为此时的球面函数
T
i
(
o
)
T_i(o)
Ti(o)是位于
∑
i
\sum_i
∑i的作用域下的
L
(
o
)
≈
∑
i
l
i
(
∑
j
t
j
⋅
B
j
(
o
)
)
=
∑
(
∑
l
i
t
i
j
)
B
j
(
o
)
)
\displaystyle L(o) \approx\sum_il_i(\sum_jt_j·B_j(o))=\sum(\sum l_it_{ij})B_j(o))
L(o)≈i∑li(j∑tj⋅Bj(o))=∑(∑litij)Bj(o))
最终着色点结果就是计算 向量·矩阵
代价:任何一个着色点 or 顶点 都要存一个矩阵(i、o的组合)
效果图
总结
如果选择SH基函数为16个,则着色计算时
Light Transport部分预计算过程的理解方式
接下来的学术界研究内容
还有很多基函数种类,其中具体讲了Wavelet,效果很好,不仅能还原低频信息,还能还原高频,但是不能旋转光源,具体内容这里就不写了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。