我们上一节最后说过,Cook-Torrance 模型的反射公式如下:
![97a905f0447b42c14f06c5312e22d954.png](https://i-blog.csdnimg.cn/blog_migrate/9f7a360c78fa81f910d6db92296bf7cc.png)
我们不分析整个公式,这一节先推导分母:
1/ (4* dot(v,n) *dot(l,n))
是如何来的。
所以微表面一笔带过,主要是基于上一节我们推导了漫反射积分后的思路。
本节的参数定义:
h :宏观平面法向量和光线方向向量之间的中间向量
n :宏观法线
m: 微观表面法线
_s后缀代表镜面反射
_d后缀代表漫反射
0.法线分布函数NDF
法线分布函数 (Normal Distribution Function),描述了平面法线分布的概率。写作D(h)或D(m)。
D(m)描述了微观表面上的表面法线m的统计分布。其代表了所有微观角度下微小镜面法线的分布情况,粗糙表面法线分布相对均匀,光滑表面法线分布相对集中
1.为什么镜面反射有独立的NDF函数?
其实漫反射已经隐含了一个NDF函数。
我们已经知道法线方向对于我们光线反射有关键作用。
对于漫反射,我们假设了一个理想模型:在单位立体角的微表面上,光线均匀的向半球四周(当然,是入射光线的另一面,所以其中一个角度积分是 2/π。)反射。
其实本质上是规定了微表面上一种特殊的法线分布的模型: 以球心为方向起点,法线方向均匀的在半球上向外分布。
大部分材质的漫反射都类似,所以这个模型还比较适合。
但各种材质的镜面反射部分差异很大,所以我们需要对材质的镜面反射部分,设计独立于漫反射部分的法线分布模型。
漫反射模型基本是通用的,镜面反射模型有很多种。
2.BlinnPhong的镜面反射计算 与 NDF 的共同点和差异?
法线分布函数(Normal Distribution Function,NDF),也叫 镜面分布Specular D函数
微表面上的每个点都会以略微不同的方向对入射光反射/散射或折射,而最终的表面外观是每个像素 = 许多具有不同表面取向的点的聚合结果。
早在我们计算BlinnPhong光照模型就知道,只有宏观法线取向方向与中间向量一致,光线才能被我们人眼接受到。
这是BlinnPhong和NDF的共同点1。
![51ff883d675267671ee9cee67c59458d.png](https://i-blog.csdnimg.cn/blog_migrate/a3bb560758c3e6ebd4b53a527bf695fa.jpeg)
BlinnPhong是使用法线与中间向量夹角大小来模拟高光的分布,同时有一个可以调节的指数speculargloss。
NDF则是引入了粗糙度Roughness(也可以用光滑度Gloss、Smoothness,可以是一张贴图或一个固定值),表示微观法线取向方向与中间向量一致的微平面占总的微表面数量的比例。如果我们的微平面中有35%的法线n与h取向一致,则NDF将会返回0.35。
所以,我们后文中 微观法线向量m,最后计算的时候,会被宏观中间向量h所取代。
注意:这个假设,来源于物理经验,不是数学上的严谨定义。它是我们用于计算brdf函数的假设。跟BlinnPhong的计算假设类似。
我们第2节提的一个问题: BlinnPhong为什么使用夹角来描述高光?
现在可以解答了,其实跟NDF的假设相同。这是BlinnPhong和NDF的共同点2。
物体表面是由很多个微表面组成。
宏观表面法线的方向上,大多数微表面都有很强的法线分布峰值,也就是NDF值很高。
所以,法线越偏移中间向量,NDF的值越小,这也是之前我们在BlinnPhong可以用夹角来描述高光的原因。
对于NDF:
当粗糙度很低时,与中间向量取向一致的微平面会高度集中在一个很小的半径范围内,会生成一个非常明亮的斑点。
当粗糙度很高时,微平面的取向方向会更加的随机,与h向量取向一致的微平面分布在一个大得多的半径范围内,同时更加灰暗。
![8c352321d4fcfa213aaf3105a9beaaf9.png](https://i-blog.csdnimg.cn/blog_migrate/7553c563e578144b493b86688129e5c5.png)
也就是这类法线取向方向与中间向量一致的微表面,才能单次反射,形成镜面高光。
其他微表面,都要经历多次反射、吸收、散射等等,到我们的眼睛里,形成漫反射等其他效果。
显然NDF对不同材质的适应性和精确性,要远远超过了BlinnPhong。
因为speculargloss没有明确的上限和下限,也不会对材质进行数学建模。
另外Roughness 还可以反过来控制漫反射的大小,达到能量守恒(通过后面的菲尼尔)。BlinnPhong的speculargloss则跟漫反射没有直接关系。
4.分母的数学推导
首先下文的推导,是基于一个前提:
![49559ee12358e92c9f8e94ddf475bbf7.png](https://i-blog.csdnimg.cn/blog_migrate/1896a10ef276f6c367d9e934474df0bc.jpeg)
微表面如上,是一个个连续的极小的镜面组成,不同镜面朝向不同。
如果建模不是这样,那么推导出来的brdf是不同的。brdf不止一种,跟你对微表面的建模有关。
第1步:利用能量守恒求解
第1步的推导,参考了孙小磊:基于物理的渲染:微平面理论(Cook-Torrance BRDF推导)
我们所关注的区域仅仅是一个着色的像素点,或者说一个微分面积元。
因此D(h) 所指的应该是单位面积下,每单位立体角,所有法向为h的微平面的面积。也就是我们的 NDF函数
然后,我们乘以,微分立体角dwh, 和单位微分面积dA
得到我们的真正红色微平面面积dAh = D(h) * dwh*dA
我们这一节,会用到上一节漫反射的很多推导结果,来加快我们的推导速度。
注:Φ表示光通量,S表示面积 , A表示微平面面积
辐射照度的定义: L=dФ/dS
所以: dΦi = Li * ds = Li * dwi * dA_垂直
dA_垂直,这里说的是微平面在 “入射光线方向上的垂直方向" 的投影。
而不是入射光线投影到微平面dwA上。我们的一切立体角建立,都要基于光线方向。
dA_垂直 = cosθi * dAh
dΦi = Li * dwi *cosθi * dAh
= Li * dwi *cosθi * D(h) * dwh*dA
我们不考虑菲涅尔效应、G函数,那么对于镜面反射也有:
dΦo = dΦi
根据辐出度radiance定义:
dLo = dФo / (dwo * cosθo *dA) = dΦi / (dwo * cosθo *dA) = Li * dwi *cosθi * D(h) * dwh*dA / (dwo * cosθo *dA)
= Li * dwi *cosθi * D(h) * dwh / (dwo * cosθo)
根据BRDF的定义:Fr = dLo/ dEi
我们上一节漫反射的结论:
Eo = ∫Ωout Lo * cosθ* dw = C* Ei
去掉积分得到:
dEi = Li * cosθi* dwi
Fr = Li * dwi *cosθi * D(h) * dwh / (dwo * cosθo)/Li * cosθi* dwi
= D(h) * dwh / (cosθo* dwo )
现在,只有 dwh/dwo 是未知数。
第2步:求解 dwh/dwo
正如我们第一节所说: 我们需要对整个物体表面做积分,那我们自然使用dwi来作为积分的变量,也就是入射光线方向,来充斥整个半球表面。
Lo(p,wo) = ∫Ω fr (p,wi,wo)* Li(p,wi)* dot(Wi ,n)dwi
这样接受光线的微平面点Q,作为新的出射光源,出射时的微表面是一个光源,求它的出射辐射度。
注意我们第一步推导时说了这句话:
dA_垂直,这里说的是微平面在 “入射光线方向上的垂直方向" 的投影。
而不是入射光线投影到微平面dwA上。我们的一切立体角建立,都要基于光线方向。
入射的时候,计算的辐射度,也是以wi作为法线的平面
所以我们把wi作为出射光源的朝向,求 dwh方向和 dwo方向的立体角比值。
所以我们会基于wi方向作为Z轴来建立立体角。
![f33f2dd37953162208bcc1125fbce759.png](https://i-blog.csdnimg.cn/blog_migrate/450d4d1548329b534241a828c7e04485.png)
因为反射光线与入射光线,基于微观法线向量m(宏观中间向量h)对称。
所以,dwo的θ角度,是dwh的θ角度的两倍。
上一节我们推导过:
漫反射_出射_微分立体角dw_d = sinθ * △θ *△φ
那么对于h方向的出射_微分立体角,我们可以复用结果:
h_出射_微分立体角 dw_h = sinθh * △θh *△φ
同样复用结果:
镜面反射_出射_微分立体角dw_ = sin2θh * △2θh *△φ = 2sinθh * cosθh * △2θh *△φ = 4sinθh cosθh * △θh *△φ
所以
dw_h /dw_o = 1/(4*cosθh)
Fr = D(h) * dwh / (cosθo* dwo )
= D(h) / (4*cosθh *cosθo)
最终结果:加上 G 和F
Fr = G *F *D /(4*cosθh *cosθo)
cosθo =dot(n,v)
cosθh =dot(n,L)