InkSoul/content/computergraphic/双向反射分布函数.md

179 lines
6.2 KiB
Markdown
Raw Permalink Normal View History

2023-06-18 23:16:41 +08:00
---
title: "双向反射分布函数(BRDF)"
date: 2022-07-23T15:05:33+08:00
---
### 光的反射
对于在某一点上发生的反射,我们通常认为:
* 光进来打到了一个物体,被弹走后,改变了方向
* 光线打到了某个物体表面后被吸收,再从物体表面将吸收的能量辐射出去
#### 通过Radiance 和 Irradiance 来解释
从某个立体角($\omega$)来的Radiance会打在dA上在dA上转换成能量并以光的形式辐射到另一个方向上去(dLr),即表现为出去的Radiance
![](../../images/reflaction_radiance_irradiance.png)
对于dA来说其接收到的能量只考虑某一方向下立体角的Radiance,在投影后就可以计算dA接收到的Irradiance,Irradiance又会转换成Radiance反射出去
出于描述dA从某个方向接收到能量后向某一方向辐射的能量值的目的我们定义了双向反射分布函数(BRDF)
### Bidirectional Reflectance Distribution Function (BRDF)
BRDF描述了dA表面是如何把一个方向收集到的能量反射到另一个方向去(定义收集到的能量如何如何往各个方向去分配(漫反射还是镜面反射))
![](../../images/BRDF_define.png)
镜面反射下,反射出去的方向上分布了所有能量
漫反射下,吸收的能量会被均等的分配到各个不同的出射方向上去
BRDF本质上描述了光线和物体是如何作用的因而BRDF项也定义了物体的不同材质
### 反射方程(The Reflection Equation)
反射方程定义的是任意着色点,在不同的光照下,我们考虑任意一个输入的光照的入射方向对出射方向的贡献,并累加所有入射方向的贡献
![](../../images/the_reflection_equation.png)
公式解释:
考虑任一不同方向的Radiance到图示的点再通过BRDF的计算可以得到出射的Radiance
存在问题:
从某个方向观察着色点意味着需要考虑所有到达这个着色点的光线,在光线弹射次数大于一次的情况下,能到达着色点的光线并非只有光源,还可能有其他面反射过来的光线(一个面接收光源照射后反射的Radiance还能够照亮其他面产生递归问题)
### 渲染方程(The Rendering Equation)
渲染方程在反射方程上考虑了物体自发光的情况,提高了通用性,几乎所有物体表面的光线传播都可以使用下列公式来总结
$$L_o(p,w_o) = L_e(p,w_o) + \int_{\Omega+} {L_i(p,w_i)f_r(p,w_i,w_o)(n\cdot w_i)dw_i}$$
* 渲染方程与Blinn-Phong模型都假设所有方向向外(考虑所有入射来的方向为球心向整个半球的各个方向)
* $\Omega +$和反射方程中的$H^2$都表示半球
#### 帮助理解渲染方程
反射方程:
* 对于一个点光源反射方程描述Li进来经过BRDF反射到观察方向上去的能量
![](../../images/understanding_flection_equation1.png)
* 如果有多个光源,就累加计算每个点光源光线到这个点反射到观测方向上的能量值
![](../../images/understanding_reflection_equation2.png)
* 如果有一个面光源(一堆点光源的集合),则将面光源上任意一个点的贡献积分起来
![](../../images/understanding_reflection_equation3.png)
渲染方程:
* 在考虑其他物体反射过来的光时可以将反射面视为光源由于渲染方程假设所有方向都是向外的所以从x点指向反射面就要变成负的
![](../../images/understanding_rendering_equation1.png)
该点向某一观察方向辐射出去的Radiance是依赖于其他点辐射出去的Radiance即为递归过程
递归的另一用处:简化方程
在某个方向看向一点时,我们不知道看到的能量(Lr)、从其他反射到这一点的Radiance但其他项都已知可定义物体的不同材质(diffuse、gloss、specular)
![](../../images/rendering_equation_simplify.png)
可利用数学上的一些简单表达式进行简化
$$I(u) = e(u) + \int {I(v) k(u,v)dv}$$
I: 从两个不同位置(u,v表示)辐射出去的Radiance
e着色点自己发出的能量在加上从其他物体表面反射来的Radiance反射到该着色点后有多少能量辐射到观察方向
$k(u,v)dv$ : 方程核心
进一步简化:
将BRDF和积分写成某种操作符(算子)后简化为下列式子,
$$L = E +KL$$
所有物体辐射出的所有能量 = 所有光源辐射出来的能量加上辐射出来的能量被反射后的能量
解渲染方程
* 将KL移至方程左侧L写成单位矩阵*L的形式
* 将(I-k)移至右侧
* 计算(1-K)的逆即可解出L的值
$$L = E + KL$$
$$IL - KL = E$$
$$(I - K)L = E$$
$$L = (I - K )^{-1}E$$
算子本身具有类似泰勒展开的性质
$$L = (I + K + K^2 + K^3 + \ldots)E$$
$$ L = E +KE+ K^2E +K^3E + \ldots $$
可看做:
光源直接辐射(E),加上经过一次反射后的辐射(KE),加上经过两次反射后的辐射(k^2E)
即分解了光线传播过程的弹射次数
### 全局光照(global illumination)
光线弹射一次得到为直接光照,弹射两次及以上为间接光照,所有光线弹射次数的项加起来的结果为全局光照(直接光照+间接光照)
#### 实例-光栅化
光栅化在已知着色点与光源位置的情况下便可以做着色,着色实际为直接光照
因此光栅化能表现的光线传播内容实际上只有零次和一次弹射(光源自己+直接光照)
* 直接光照(光源能直接照射的地方有颜色,其余位置为黑的)
![](../../images/Direct_illumination_eg.png)
* 一次间接光照(光弹射两次)
![](../../images/one-bounce_global_illumination_eg.png)
* 两次间接光照(光弹射一次,两次,三次累积后的全局光照效果)
![](../../images/two-bounce_global_illumination_eg.png)
* 四次间接光照(玻璃灯内部变亮,在弹射三次时,仅足够进入物体,不足以离开物体)(双层玻璃需要两次弹射进入,两次弹射离开)
![](../../images/four-bounce_global_illumination_eg.png)
8次弹射和16次弹射只会提高暗处亮度难以感知到
在无限次数弹射下,亮度会收敛到某一个值上,不会有剧烈变化,也不会产生过曝
在相机的情况下,保持快门打开则会产生过曝现象,与辐射度量学中单位时间的条件相应,快门打开使积累能量的时间变长,亮度变亮