解决上一篇中的问题
辐射率:
透过一定立体角到某个和光线垂直面积的辐射通量,那么对于每个点来说,辐射率就是它接收到的来自某个立体角的辐射通量,而当立体角特别小的时候,就是一束光线上的辐射通量。
假设我们拥有一个点光源,辐射通量用RGB表示(参考不同波长的光线具有不同的能量,RGB三个颜色就近似代表三个波长区间),该光源的辐射强度等于其在所有出射光线的辐射通量。
但是对于要照射到的一个点来说,在点的半球领域上,只有一个入射方向向量来自于该点光源。也就是说其他方向上辐射率为0。
也就是说,每个光源只有一个方向上的光线会影响所照射的点,这就使得PBR对直接光源计算相对简单,因为我们只需要遍历所有有贡献的光源。
当考虑IBL的时候(考虑环境照明),就需要用积分计算了,因为光线可能从任何一个方向入射
在具体的代码实现中,原则上我们需要完整的表达出这个式子:
fr=kdflambert+ksfcook−torrance
f
r
=
k
d
f
l
a
m
b
e
r
t
+
k
s
f
c
o
o
k
−
t
o
r
r
a
n
c
e
但是由于在BRDF中,菲涅尔系数中我们已经和
Ks
K
s
相乘过了,所以我们并不需要再对后一项乘
Ks
K
s
。
代码中遇到的坑和收获:
首先第一遍实现下来发现材质很暗,这是正常现象,因为我们没有考虑环境光的作用,对于球来说,只有一个点光源对着它,每个被照射到的点来说,半球区域内只有一束光线。
关于正态分布函数:
这是主要的高光区域的来源,它接收粗糙度作为参数,分子是粗糙度的平方,分母是四次方,分母中包含中间向量和法向量的点乘,点乘结果越大,则分母越小。对应的是粗糙度越大,函数返回值越小,点乘结果越大,分母越小对应函数返回值越大。这个函数返回的结果是微平面取向和中间向量一致的概率,粗糙度越大,则取向一致概率越小,本身法向量与中间向量越接近(越大),则取向一致性概率越大。
这个函数是主要的镜面反射来源。
关于菲涅尔函数:
菲涅尔方程表式的是在不同视线方向和法线方向情况下,光线的反射情况。也就是最终反射部分的取值,菲涅尔函数的传入值包含了视线方向和表示材质的一个量,所以如果有金属度,应该将金属度改变后作为参数传入这个函数。
关于几何函数:
几何函数表示微平面间相互遮蔽的概率,也受粗糙度影响,粗糙度经过变换后出现在分母处,粗糙度越大函数返回值越小,代表光线越弱,同样它与视线方向和光线方向有关。如果视线方向和法线方向垂直,那么应该没有太大的遮蔽,相反,如果几乎平行,则遮蔽应该最大,光线方向也同样如此,所以可以是同一个函数传入两个不同的值,再把结果相乘,作为几何函数的返回值。
这三项之外,还要考虑折射部分,折射部分与物体材质有关,如果是金属,则折射部分被全部吸收,这一项就不存在,如果是非金属,则折射部分的能量应该等于1减去菲涅尔函数的返回值。
这些量都有了之后,再与光线自身的量相乘,即辐射率。辐射率分为两部分,一部分是光线强度,根据光源的属性而定,另一部分根当前表面和光线的方向有关,如果垂直入射,则辐射率应该最大,所以是法向量和光线方向的点乘。