PBR理论(二)

openGL高级光照部分目录 见 openGL高级光照部分目录

这给我们带来了一个叫做渲染方程的东西,一个非常聪明的人想出的一个精心设计的方程,它是目前我们用来模拟光的视觉效果的最好的模型。基于物理的渲染强烈遵循渲染方程的一个更专门的版本,即反射方程。要正确理解PBR,首先要对反射率方程建立坚实的理解:

反射率方程一开始看起来让人望而生畏,但当我们仔细分析它时,你会发现它慢慢开始有意义了。为了理解这个方程,我们必须深入研究辐射测量学。辐射测量是测量电磁辐射,包括可见光。有几种辐射量可以用来测量表面和方向上的光,但我们只讨论一个与反射率方程相关的辐射量,称为辐射率,这里表示为L辐射量用于量化来自一个方向的光的大小或强度。一开始理解起来有点棘手,因为辐射是多个物理量的组合,所以我们将首先关注这些物理量:

辐射通量:辐射通量Φ是光源的传输能量,单位为瓦特。光是多个不同波长上能量的集合,每个波长都与特定(可见)颜色相关。因此,一个光源的发射能量可以看作是它所有不同波长的函数。390nm到700nm(纳米)之间的波长被认为是可见光谱的一部分,即人眼能够感知的波长。下面是每波长日光的不同能量图像:

辐射通量测量不同波长函数的总面积。直接将波长的这种测量作为输入有点不切实际,因此我们经常简化表示辐射通量的方法,而不是将其作为波长强度的函数,而是作为编码为RGB(或我们通常称之为:光颜色)的光色三元组。这种编码确实会带来相当大的信息损失,但对于视觉方面来说,这通常可以忽略不计。

立体角:立体角,用ω表示,它告诉我们投影到单位球体上的形状的大小或面积。投影到该单位球体上的形状区域称为立体角;可以将立体角视为具有体积的方向:

想象一下,作为一个观察者,站在这个单位球体的中心,朝着这个形状的方向看;你从它所形成的轮廓的大小就是立体角。

辐射强度:辐射强度测量每一个立体角的辐射通量,或光源在单位球体上投影面积上的强度。例如,给定一个全向光,它在所有方向上均匀地辐射,辐射强度可以给我们一个特定区域(立体角)的能量:

描述辐射强度的方程定义如下:

式中 I 是立体角ω上的辐射通量Φ。

利用辐射通量、辐射强度和立体角的知识,我们最终可以描述出辐射的方程。辐射度被描述为在辐射强度Φ的光的立体角ω上的区域A中观察到的总能量:

辐射度是一个区域内光照量的辐射量度,按光与表面法线的入射(或入射)角θ进行缩放,如cosθ:当直接辐射到平面上的程度越低时,光线就越弱,当它直接垂直于表面时最强。这与我们在“基本照明”一章中对漫反射照明的理解类似,因为cosθ直接对应于光的方向向量和曲面法线之间的点积:

float cosTheta = dot(lightDir, N);

辐射方程非常有用,因为它包含了我们感兴趣的大多数物理量。如果我们认为立体角ω和面积A是无穷小的,我们可以用辐射度来测量击中空间中某一点的单光线的通量。此关系允许我们计算影响单个(碎片)点的单个光线的辐射度;我们有效地将立体角ω转换为方向向量ω,并将a转换为点p。这样,我们可以直接在着色器中使用辐射度来计算单个光线对每个碎片的贡献。

事实上,当谈到辐射度时,我们通常关心点p上的所有入射光,这是所有辐射的总和,称为辐照度。有了辐射和辐照度的知识,我们可以回到反射率方程:

我们现在知道,渲染方程中的L代表某个点p和某个入射无限小立体角的辐射度,可以认为是入射方向矢量。记住cosθ根据光入射到表面的角度来缩放能量,我们在反射率方程中找到了。反射率方程计算了一个点在方向上的反射辐射率之和,该方向是观测者的出射方向。或者换一种说法:表示从方向上观察,光线投射到点p上反射出来的辐照度。

反射率方程是以辐照度为基础的,辐照度是我们测量光的所有入射光的总和。不仅是单个入射光方向,而且是以点p为中心的半球Ω内的所有入射光方向。半球可以描述为围绕曲面法线n排列的半个球体:

为了计算一个区域或(在半球的情况下)体积内值的总和,我们使用一个称为积分的数学结构,在反射方程中表示为半球Ω内所有入射方向dωi的 ∫ 。积分测量一个函数的面积,可以用解析法或数值法计算。由于渲染和反射方程都没有解析解,所以我们需要离散数值求解积分。在半球领域Ω中按一定的步长将反射率方程分散求解,然后再按照步长大小将所得到的结果平均化。这种方法被称为黎曼和(Riemann sum) ,我们可以用下面的代码粗略的演示一下:

int steps = 100;
float sum = 0.0f;
vec3 P    = ...;
vec3 Wo   = ...;
vec3 N    = ...;
float dW  = 1.0f / steps;
for(int i = 0; i < steps; ++i) 
{
    vec3 Wi = getNextIncomingLightDir(i);
    sum += Fr(P, Wi, Wo) * L(P, Wi) * dot(N, Wi) * dW;
}

通过按dW缩放步长,总和将等于积分函数的总面积或体积。在反射率方程中,每个离散步长的dW可以看作dωi。从数学上讲,dωi是我们计算积分的连续符号,虽然它与代码中的dW没有直接关系(因为这是Riemann和的一个离散步骤),但用这种方式来考虑它是有帮助的。请记住,采取离散的步骤总是可以得到函数总面积的近似值。细心的读者会注意到我们可以通过增加步数来提高黎曼和的精度。

反射方程求出半球Ω上所有入射光方向ωi的辐射强度,该半球Ω按fr表示,并返回观察者方向上反射光Lo的总和。入射光可以来自我们熟悉的光源,也可以来自于测量每个入射方向的辐射的环境地图,我们将在IBL章节中讨论。

现在唯一未知的是fr符号,称为BRDF或双向反射分布函数,它根据表面的材料特性来缩放或衡量入射辐射。

猜你喜欢

转载自blog.csdn.net/tiao_god/article/details/107331176
PBR