PBR学习

PBR学习

https://learnopengl-cn.github.io/07%20PBR/01%20Theory/

请结合所给参考链接中的图示进行学习,我主要对参考链接中的资料翻译和理解,为了方便理解另外查阅了一些资料,但都过于零散我也没记住有哪些。
能用文字说清楚的地方我并没有给出图示,但显然图示更易于理解。

PBR满足的三个基本条件

  1. 基于微平面的表面模型
  2. 能量守恒
  3. 基于物理的BRDF(存在不基于物理的BRDF,后续会详解)

先解释这三个条件

微平面模型

在微观尺度下,没有任何一个平面是完全光滑的。把一个表面看成方向各不相同的微小的镜面的组成。粗糙的表面上微平面的排布就更加混乱,当光线照射时,反射方向会发散开来,而光滑的表面微平面排布会更有序,反射方向会更倾向于向一个方向。

粗糙度

在说明“粗糙度”这个量之前,我们先看一下我们是如何衡量粗糙程度这个人的直观感受的。当我们计算一个点的镜面反射时,我们会用到该点到视线方向 v v 的向量和该点到光照方向的向量l" role="presentation">l,我们先求出两个向量的中间向量(介于两个向量正中间的向量) h=l+v||l+v|| h = l + v | | l + v | | ,如果中间向量和表面法向量一致的话,证明镜面反射光是直射到人眼的,两个向量相差越大,则反射光越弱。
粗糙程度表现就是对于越粗糙的物体,总体的镜面反射越弱,对于越光滑的物体,镜面反射越强。而前面提到,所有的平面都是由许多微平面组成,我们无法具体到每个微平面方向,但是我们可以估计所有微平面方向和中间向量一致的概率,而估计这个概率用到的参数,就是粗糙度。
拿一个球举例,假设该球非常光滑,即对于球上的每个微平面,其法向量等于该微平面的位置与球心位置的差。那么对于球的不同的地方,微平面方向和中间向量一致的概率就是不同的,准确的说只有一个微平面和中间向量一致,其余都或多或少有区别(这时还没有引入粗糙度)。也就是说,此时球面上只有非常小的一个区域,它满足中间向量和表面法向量一致这个条件,也就是该点最亮,其他地方都是黑的。
Alt text
而当我们引入了粗糙度,我们将微平面的方向逐渐打乱,在原先最亮的位置,由于并不是所有的微平面方向都一致,那么势必该点亮度会有所下降,而其他地方由于也有可能存在方向满足条件的微平面,其他部分亮度会有所上升。
Alt text

能量守恒

出射方向能量永远不能超过入射光线的能量。(微平面近似法显然满足这个条件,显然上面的一切说理都未添加新的能量)随着粗糙度上升,镜面反射区域会增加(一些本来没有变量的区域因为部分微平面方向和中间向量一致而有了镜面反射),但是亮度会变暗(一些本来变量的区域因为部分微平面方向和中间向量变得不一致而反射减弱)。
为了遵循能量守恒定律,我们需要对漫反射光和镜面反射光作区分。当一束光线碰撞到表面的时候,一部分反射(我们前面一直在说的镜面反射),另一部分折射。
折射指的是光线进入物体表面被吸收。实际上是光线与物体表面微粒不断碰撞导致能量消耗的过程,在这个过程中,一部分能量被完全吸收(能量消耗完毕),另一部分幸运儿在能量消耗完毕之前会从表面的另一个位置离开表面,并参与构成了表面的漫反射。在次表面散射中会模拟计算这一个折射过程,因为对于玉石,皮肤,牛奶这样的结构,它表面的散射不仅和光线入射点的位置相关,还跟内部的结构有关,所以需要跟踪折射的过程(当然是模拟啦)。
对于次表面散射来说,有两个基本的问题。一是折射会有能量损失,二是入射点和出射点并不在同一个位置,我大概以后会单独介绍次表面散射,现在回到基本的PBR。在PBR中,实际上我们并没有完全按照折射的原理进行光线跟踪计算,我们通常以为折射的所有光线能量都完全被吸收(但是漫反射依旧是需要模拟出来的)。
而对于金属表面来说,所有的折射光是真的会被吸收而不会散开,所以金属表面是真的不会显示出漫反射颜色的。
根据能量守恒的关系,首先计算出镜面反射部分,等于入射光线被反射的能量所占的百分比,折射光部分可以用1减去这个百分比。就能确保能量总和永远不会超过入射光线的能量。

反射率方程

PBR遵循的是反射率方程的一个特化版本,我们先从最初的反射率方程开始学习。
需要涉及到辐射度量学的内容(用物理量度量辐射(光线能量)的学问(一种我很难理解但是死记下来后好像就是那么一回事的学问))

辐射率

辐射通量: 表示的是光源所输出的能量(单位时间穿过截面的光能),单位是瓦特。光线的能量跟其波长有关,所有的光都是由不同波长(颜色)的光线组合而成,所以根据不同波长光线的比重和其对应的能量,就可以求出该光源输出的能量。
数学一点,就是光源所放射出来的能量可以被视作这个光源所包含的各种波长的一个函数,对于白光(日光),不同波长所具备的能量如下:(横坐标是波长,纵坐标是能量)
Alt text
所以如果我们想求白光的辐射通量,就是求彩色部分的面积,也就是那个函数的积分。但我们通常并不这样求(因为我们并不能给计算机输入这个函数,即输入每一个波长对应的能量),我们一般用RGB三个颜色进行编码(是不是档次一下子就掉下去了?)。
立体角: Alt text
立体角用 w w 表示,它描述的是站在某一点的观察者测量到的物体大小的尺度。立体角的大小是,以它的顶点为圆心,画一个半径为r的球,它在球面上的面积除以半径的平方。也就是说,它度量的是它在单位球面上截取的面积。对应于二维的弧度(原文这里有些不清楚,我这样更正了一下,希望可以更清楚些)
Alt text
辐射强度: 指的是每单位立体角的辐射通量。
I=dΦdw" role="presentation">I=dΦdw
辐射率定义为在指定方向上的单位立体角和垂直此方向的单位面积上的辐射通量。
L=d2ΦdAdwcosθ L = d 2 Φ d A d w c o s θ
Alt text

这里参考了毛星云的《Real-Time Rendering 3rd》提炼总结: 辐射率表示物体表面沿某一方向的明亮程度。一种直观的理解辐射率的方法是:可以将辐射率理解为物体表面的微平面所接受(反射)的来自于某方向光源的单位面积单位立体角的辐射通量。

辐照度 照射到单位面积的辐射通量。辐照度可以写成辐射率在入射光所形成的半球上的积分。
Alt text
注意辐射率是不是有个除以 cosθ c o s θ ?这里乘了回来。
我们把 cosθ c o s θ 改成光线入射方向和法向量的点积,就构成了反射方程的一部分。
完整的反射方程如下:
Alt text
这个方程描述的是在半球领域内,碰撞到了点 p p 上的所有入射方向的光线的辐射率,并且受到了fr" role="presentation">fr的约束。
补充说明:
这个反射方程得到的是出射方向(视线方向)的辐射率,因为所有的入射方向都有可能会向出射方向反射,所以我们用的是积分求和。
现在我们只需要解决第一个 fr f r 所代表的函数就好了。而这个函数就是BRDF。

BRDF

双向反射分布函数,输入参数是入射光方向,出射光方向,平面法向量和一个用来表示微平面粗糙程度的参数。
BRDF的返回值给定了出射方向和入射方向能量的相对量。其定义为出射时的辐射率和入射时的辐照度之比。
BRDF可以近似求出每束光线对一个材质属性在一定的平面上最终反射出来的光线的贡献程度。如果是绝对光滑(微平面方向有序),那么除了入射角恰好和反射角相同的光线返回1,其他光线都返回0。
常见的实时渲染管线使用的都是一种被称为Cook-Torrance BRDF的模型。(这句话只针对PBR啊,毕竟BRDF模型分类超多的)

Cook-Torrance

Cook-Torrance BRDF有漫反射和镜面反射两个部分。
(请思考:我们假设PBR所有折射都被吸收,那么漫反射是如何来的?)
fr=kdflambert+ksfcooktorrance 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
两个 k k 分别代表折射和反射部分所占的比例。
flambert=cπ" role="presentation">flambert=cπ c c 表示表面颜色。(回答:所以它的漫反射只是结合折射所占比例来模拟的)
但是漫反射依旧是需要知道光照方向和表面法向量方向的(镜面反射才需要知道反(出)射方向),这个公式中虽然没有表现这一点,但是需要记住这个公式是那个大公式里面的内容,在大公式的最后就是入射方向和表面法向量的点积。
镜面反射部分要稍微复杂一些,形式如下:
fcooktorrance=DFG4(w0n)(win)" role="presentation">fcooktorrance=DFG4(w0n)(win)
其镜面反射包含三个函数。分别是
D: 正态分布函数
在受到表面粗糙度的影响下,取向方向和中间向量一致的微平面的数量。(这是估算微平面的主要函数)
F:菲涅尔函数
不同的表面角下表面所反射的光线所占的比例
G:几何函数
描述了微平面自成阴影的属性。当一个平面相对粗糙的时候,平面表面上的微平面有可能挡住其他的微平面从而减少表面所反射的光线。
现在一一介绍每个函数的作用:
D :从统计学上近似的表示与中间向量取向一致的微平面所占的比例。如果微平面中有35%与中间向量取向一致,则该函数会返回0.35。
(思考,这个函数除了需要知道传入的粗糙度参数外,还需要知道什么?)
(回答:还需要知道当前位置的法向量和中间向量,因为对于一个不规则的物体,就算不引入粗糙度这个概念,不同的部位对应的一致程度就是不一样的,就像和光线完全相反的一个部分,这个函数的返回值总是非常小,而法向量和朝光线相同的部分,返回值总是非常大的)
G:同样需要粗糙度作为参数,因为粗糙度较高的表面微平面相互遮挡的概率就越高。
F:描述的是反射部分比折射部分这个比例,这个比例会随着我们观察角度不同而不同。

谈谈如何使用已经做好的PBR

反照率(Albedo)为每一个金属的纹理,指定表面颜色和基础反射率,它只包含表面的颜色或者折射吸收系数。
法线贴图:这个没什么区别
金属度:金属贴图逐像素指定该纹素是不是金属质地的,或者金属质地的程度。
粗糙度:为每个纹素指定某个表面有多粗糙。
AO:环境光遮蔽(Ambient Occlusion)为表面和周围潜在的几何图形指定了一个额外的阴影因子,需要知道我们的反照率贴图是不管任何阴影的,它只是表面的颜色,但是对于像砖块这样的表面具有裂缝的物体来说,裂缝区域应该偏暗。

最后自己做了一个假的PBR
Alt text
仍旧存在的疑惑:
1. 辐射率怎样程序实现,光照的辐射通量怎样表示?
2. 怎样计算多少光反射多少光折射

IBL(Image-Based Lighting)

以上就是直接光照的PBR,但是就画面效果来说,和之前的渲染并没有太大的进步。
让PBR表现优于上一个世代的画面效果的,是环境光部分。
原理是保存周围环境的不同模糊程度的景象(是一个立方体贴图),然后贴在原先模型上。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部