1. PBR一般概念
1. 什么是PBR
PBR(Physicallly-Based-Rendering), 基于物理的渲染,有时也叫PBS(Physicallly-Based-Shading),(其实Unity自带的Standard就是一个完整的PBR,实际中需要对官方的性能调优)。为什么叫基于物理的,因为目标是基于与现实世界的物理原理基本相符的理论构成渲染技术。这样美术就可以直接以物理参数为依据来编写材质,不论光照如何材质看上去都是正确的。
PBR是一套渲染解决方案,包括基于物理的材质制作,基于物理的灯光PBL,基于物理的镜头,等等。
这里只是将下PBS,PBS其实是一套成熟理论下的光照模型。
2. PBR涉及到的理论
PBR光照模型的三个条件:
① 基于微平面的表面模型;
② 能量守恒;
③ 应用基于物理的BRDF。
微平面理论:
PBR基于微平面理论,即达到微观尺度后任何平面都可以用被称为微平面的细小镜面来描绘。平面越粗糙,微平面的排列越混乱,镜面反射时就会向完全不同的方向发散开来。我们可以用统计学的方法估算粗糙程度,而粗糙程度表示微平面上平均取向和半程向量(下段介绍半程向量)的方向一致的概率。
Blinn-Phong模型不依赖于反射向量,而是采用了所谓的半程向量,即光线与视线夹角一半方向上的一个单位向量。当半程向量与法线向量越接近时,镜面光分量就越大。当视线正好与(现在不需要的)反射向量对齐时,半程向量就会与法线完美契合。所以当观察者视线越接近于原本反射光线的方向时,镜面高光就会越强。
(Blinn-Phong与冯氏模型唯一的区别就是,Blinn-Phong测量的是法线与半程向量之间的夹角,而冯氏模型测量的是观察方向与反射向量间的夹角。除此之外,冯氏模型与Blinn-Phong模型也有一些细微的差别:半程向量与表面法线的夹角通常会小于观察与反射向量的夹角。所以,如果你想获得和冯氏着色类似的效果,就必须在使用Blinn-Phong模型时将镜面反光度设置更高一点。通常我们会选择冯氏着色时反光度分量的2到4倍。)
半程向量:H = (L + V) / || L + V || ;
所以,粗糙度越大,微平面上平均取向和半程向量(下段介绍半程向量)的方向一致的概率越小,那反射的轮廓就会越大。
能量守恒原则:
出射光线的能量永远不能超过入射光线的能量(自发光除外)。当一束光线碰撞到一个表面的时候,它就会分离成一个折射部分和一个反射部分。反射部分就是会直接反射开来而不会进入平面的那部分光线,这就是我们所说的镜面光照。而折射部分就是余下的会进入表面并被吸收的那部分光线,这也就是我们所说的漫反射光照。
(并非所有能量都会被全部吸收,而光线也会继续沿着随机的方向发散,然后再和其他的粒子碰撞直至能量完全耗尽或者再次离开这个表面。而光线脱离物体表面后将会协同构成该表面的(漫反射)颜色。不过在基于物理的渲染之中我们进行了简化,假设对平面上的每一点所有的折射光都会被完全吸收而不会散开。次表面散射(Subsurface Scattering)技术的着色器技术将这个问题考虑了进去。)
物质的光学特质:(渲染领域大多分为2类:金属和非金属)
金属表面所有折射光都会被直接吸收而不会散开,只留下反射光或者说镜面反射光。亦即是说,金属表面不会显示出漫反射颜色。所以金属和非金属材料在PBR中需要区别处理。
基于能量守恒,可以得到:
float ks = CalculateSpecular;// 反射/镜面 部分
float kd = 1.0 - ks;// 折射/漫反射 部分
PBR ,反射率方程
L:辐射率,单一方向上发射来的光线的大小或者强度。
Φ :辐射通量,表示的是一个光源所输出的能量,以瓦特为单位。一个光源所放射出来的能量可以被视作这个光源包含的所有各种波长的一个函数。)
ω :立体角,它可以为我们描述投射到单位球体上的一个截面的大小或者面积(人在球心观察)。投射到这个单位球体上的截面的面积就被称为立体角(Solid Angle)。
辐射强度(Radiant Intensity)表示的是在单位球面上,一个光源向每单位立体角所投送的辐射通量。
辐射强度:I = d Φ / d ω
一个拥有辐射强度Φ的光源在单位面积A ,单位立体角 ω 上的辐射出的总能量:
θ 为入射光线和平面法线间的夹角。
反射率方程:
P:将上述的A转换为了点。即可以计算单束光纤对meig每个片段的作用;
ω i :入射方向向量, n⋅ω i 即cosθ ;
ωo :表示观察方向,也就是出射方向;
∫ :反射率公式中的符号,它的运算包含了半球领域Ω 内所有入射方向上的dω i 。
反射率方程概括了在半球领域Ω内,碰撞到了点p 上的所有入射方向 ωi 上的光线的辐射率,并受到fr 的约束,然后返回观察方向上反射光的Lo 。
BRDF
fr 被称为BRDF,或者双向反射分布函数(Bidirectional Reflective Distribution Function) ,它的作用是基于表面材质属性来对入射辐射率进行缩放或者加权。
BRDF可以近似的求出每束光线对一个给定了材质属性的平面上最终反射出来的光线所作出的贡献程度。它接受入射(光)方向ω i ,出射(观察)方向 ωo ,平面法线n 以及一个用来表示微平面粗糙程度的参数a 作为函数的输入参数。
BRDF分为两部分,折射部分(漫反射)+ 反射部分(高光反射),很多种BRDF都可以近似为下面的公式:
kd 是入射光线中折射部分的能量所占的比率,而ks是反射部分的比率。BRDF的左侧表示的是漫反射部分,用flambert 来表示。BRDF的右侧表示的是镜面反射。
D:正态分布函数(法线分布函数),估算在受粗糙度影响下,取向方向与中间向量一致的微平面的数量。
F:菲尼尔反射,描述在不同的表面角下表面所反射的光线所占的比率。
G:几何函数(阴影-遮掩函数),描述了微平面自成阴影的属性。即平面表面上的微平面挡住其他微平面从而减少表面所反射的光线。
Unity5.3以后使用GGX模型(这种模型的DFG采用了GGX特定的函数形式,因为每个函数不止一种形式)。
最终,我们得到Cook-Torrance反射率方程:
金属:
金属具有很高的反射率(>=0.5),不会出现任何次表面散射和透明效果。金属的所有可见光都来自反射,即所有可见颜色都来自反射。
非金属反射率低(<=0.06),产生镜面反射和漫反射,镜面反射为单色/灰色。
菲涅尔反射:
光源入射方向与平面法线法线夹角的对应关系。夹角越大,亮度也就越大,反之夹角越小,亮度也就越小。
线性空间光照:
为了保证光照渲染的正确性,最好是在线性空间中进行操作与计算。PBR计算要放在线性空间中。
次表面散射(Subsurface Scattering):
这个在BRDF中不讨论,实现方式在另一个更物理的模型BSSRDF内实现。
为什么现在流行BRDF,而不使用更物理的BSSRDF ? 我的理解是,虽然万物都有次表面散射现象,但是这个效果在大部分材质上表现并不明显。而为了实现这个性能开销却很大,简单来说就是性价比不高,所以就去掉了这部分计算。但是在另一部分物体中,次表面散射表现明显:玉石、翡翠、牛奶、皮肤 … …。所以遇到这类材质时如果要求好的表现效果,就只能改用BSSRDF光照模型了。
那如何编写PBR材质呢?
美术师一般是如何编写一个我们可以直接输入PBR的平面物理属性的。PBR渲染管线所需要的每一个表面参数都可以用纹理来定义或者建模。使用纹理可以让我们逐个片段的来控制每个表面上特定的点对于光线是如何响应的:不论那个点是金属的,粗糙或者平滑,也不论表面对于不同波长的光会有如何的反应。输入PBR渲染管线一个纹理列表,就会得到相应的视觉输出,纹理列表如下:
反照率(Albedo)纹理:
为每一个金属的纹素(Texel)(纹理像素)指定表面颜色或者基础反射率。这和我们之前使用过的漫反射纹理类似,不同的是所有光照信息都是由一个纹理中提取的。漫反射纹理的图像当中常常包含一些细小的阴影或者深色的裂纹,而反照率纹理中是不会有这些东西的。它应该只包含表面的颜色(或者折射吸收系数)。
法线贴图纹理:
法线贴图使我们可以逐片段的指定独特的法线,来为表面制造出起伏不平的假象。
金属(Metallic)贴图:
逐个纹素的指定该纹素是不是金属质地的。根据PBR引擎设置的不同,美术师们既可以将金属度编写为灰度值又可以编写为1或0这样的二元值。
粗糙度(Roughness)贴图:
可以以纹素为单位指定某个表面有多粗糙。采样得来的粗糙度数值会影响一个表面的微平面统计学上的取向度。一个比较粗糙的表面会得到更宽阔更模糊的镜面反射(高光),而一个比较光滑的表面则会得到集中而清晰的镜面反射。某些PBR引擎预设采用的是对某些美术师来说更加直观的光滑度(Smoothness)贴图而非粗糙度贴图,不过这些数值在采样之时就马上用(1.0 – 光滑度)转换成了粗糙度。
环境光遮蔽(Ambient Occlusion)贴图或者说AO贴图
为表面和周围潜在的几何图形指定了一个额外的阴影因子。比如如果我们有一个砖块表面,反照率纹理上的砖块裂缝部分应该没有任何阴影信息。然而AO贴图则会把那些光线较难逃逸出来的暗色边缘指定出来。在光照的结尾阶段引入环境遮蔽可以明显的提升你场景的视觉效果。网格/表面的环境遮蔽贴图要么通过手动生成,要么由3D建模软件自动生成。
美术师们可以在纹素级别设置或调整这些基于物理的输入值,还可以以现实世界材料的表面物理性质来建立他们的材质数据。这是PBR渲染管线最大的优势之一,因为不论环境或者光照的设置如何改变这些表面的性质是不会改变的,这使得美术师们可以更便捷的获取物理可信的结果。在PBR渲染管线中编写的表面可以非常方便的在不同的PBR渲染引擎间共享使用,不论处于何种环境中它们看上去都会是正确的,因此看上去也会更自然
贴图纹理
· 1. 颜色贴图(Albedo)金属度(Metallic||Metalness),粗糙度 (Roughness),法线贴图。
2. 渲染方程
因为本人是个数学白痴,所以方程这块懵懵懂懂,所以本想把方程放入概念内,一笔带过就行了。结果在后面的学习中发现,根本不行啊!!如果对方程没有比较深刻的了解,在最后求最终函数时就是懵逼的。还是过一过吧,最好拿笔写几遍,理一理。
1. 大名鼎鼎渲染方程公式:
想象我们现在要计算表面上某点的出射辐射率,我们已知到该点的观察方向,该点的出射辐射率是由从许多不同方向的入射辐
射率叠加后的结果。其中,f (ωi , v)表示了不同方向的入射光在该观察方向上的权重分布。我们把这些不同方向的光辐射率(L i (ω i )部分)乘以观察方向上所占的权重(f (ω i , v)部分),再乘以它们在该表面的投影结果((n · ω i ) 部分),最后再把这些值加起来(即做积分)就是最后的出射辐射率。
但是,积分累加部分在实时渲染中基本无法实现,因此积分部分通常会被若干精确光源的叠加所代替,而不需要计算所有入射光线在半球面上的积分。
2. 出射辐射率:
对于一个精确光源,我们可以使用下面的等式来计算它在某个观察方向 v 上的出射辐射率:
l c 表示精确光源的方向,c light 表示它的颜色。
式子使用一个特定方向的 **f (l c , v)**值来代替积分操作,这大大简化了计算。
如果场景中包含了多个精确光源,我们可以把它们分别代入上面的式子进行计算,然后把它们的结果相加即可。也就是说,反射等式可以简化成下面的形式:
现在剩下的问题就是 f (l c , v)项怎么算?f (l c , v)实际上描述了当前点是如何与入射光线进行交互的:当给定某个入射方向的入射光后,有多少百分比的光照被反射到了观察方向上。在图形学中,这一项有一个专门的名字,那就是双向反射分布函数,即 BRDF。
3. 双向反射分布函数(BRDF)
定量描述了物体表面的一点是如何和光进行交互的。
BRDF的理解:当给定观察方向(即出射方向)后,BRDF 可以给出从所有入射方向到该出射方向的光线分布。
BRDF 可以用于描述两种不同的物理现象:表面反射(高光反射项specular term)和次表面散射(漫反射项diffuse term)。
1. 漫反射项(两种)
①. 最简单但也是最广泛的漫反射模型: Lambert (虚幻4)
给定入射方向 l 的光源在表面某点的出射漫反射辐射率为:
②. Disney BRDF:(unity)
许多材质在掠射角度表现出了明显的高光反射峰值,而且还与表面的粗糙度有着强烈的联系。粗糙表面在掠射角容易形成一条亮边,而相反地光滑表面则容易在掠射角形成一条阴影边。这些都是 Lambert 模型所无法描述的。
baseColor 是表面颜色,通常由纹理采样得到,roughness 是表面的粗糙度。
这个公式使得光滑材质可以在掠射角具有更为明显的阴影边,而又使得粗糙材质在掠射角具有亮边。
2. 高光反射项
微面元理论中,表面法线为 n,这些微面元的法线 m 并不都等于 n。
因此,不同的微面元会把同一入射方向的光线反射到不同的方向上。这意味着只有一部分微面元反射的光线才会进入到我们的眼睛中,这部分微面元会恰好把光线反射到方向 v 上,即它们的法线 m 等于 l 和 v 的一半,也就是半角度矢量 h。
但是,这些 m = h 的微面元反射也并不会全部添加到 BRDF 的计算中。这是因为,它们其中一部分会在入射方向 l 上被其他微面元挡住。
微面元理论的BRDF 高光反射项:
分母 4(n ⋅ l)(n ⋅ v) 是用于校正从微面元的局部空间到整体宏观表面数量差异的校正因子。
F(l, h)则是这些活跃微面元的菲涅尔反射 ( Fresnel reflectance )函数。告诉我们每个活跃的微面元会把多少入射光线反射到观察方向上,即表示了反射光线占入射光线的比率。
大多数 PBS 实现选择使用Schlick 菲涅耳近似等式来得到近似的菲涅尔反射效果:
c spec 是材质的高光反射颜色。
通过对真实世界材质的观察,发现金属的高光反射颜色值比较大,而非金属的则较小。
G(l, v, h)是阴影—遮掩函数(shadowing-masking function)。它用于计算那些满足 m=h 的微面元中有多少会由于遮挡而不会被人眼看到,因此它给出了活跃的微面元(active microfacets)所占的浓度,只有活跃的微面元才会成功地把光线反射到观察方向上。
阴影-遮挡函数 G(l, v, h)也被称为 几何函数( geometry function ) ,它表明了具有给定面法线 m的微面元在沿着入射方向 l 和观察方向 v 上不会被其他微面元挡住的概率。
由于G(l, v, h)表示的是一个概率值,因此它的值是一个范围在 0 到 1 之间的标量。
某些BRDF中,将该项的值设为 1。这意味着,这些 BRDF 中的G(l, v, h)表达式等同于
这个会和分母进行抵消。但是这种 G implicit 的实现忽略了材质粗糙度的影响,缺乏一定的物理真实性,因为我们希望粗糙的表面具有更高阴影和遮挡概率。(简化公式时可选这个)
通常阴影-遮挡函数 G(l, v, h)依赖于法线分布函数 D(h), 因为它需要结合 D(h)来保持 BRDF能量守恒的规定。
目前在图形学中广受推崇的是 Smith 阴影-遮掩函数
θ v 表示观察方向 v 和表面法线 n 之间的夹角。
D(h)是微面元的法线分布函数 ( normal distribution function , NDF )
法线分布函数的值必须是非负的标量值,它决定了高光区域的大小、亮度和形状,因此是高光反射项中非常重要的一项。
GGX (也被称为 Trowbridge-Reitz 法线分布函数)公式如下:
-
参数 α 是与表面粗糙度相关的参数。
https://editor.csdn.net/md/?articleId=108270452
3. 其它 移动版PBR
除了官方标准版PBR实现
1. SSS次表面效果,添加到PBR内尝试(BSSRDF)
BSSRDF 渲染方程,Unity3d shader之次表面散射(Subsurface Scattering)
2. 艺术化风格的PBR效果,也可以叫NPR的PBR
思路:将梯度漫反射和描边效果添加进PBR渲染方程
参考资料
必读资料
《UnityShader入门精要》 18章
https://learnopengl-cn.github.io/07%20PBR/02%20Lighting/
https://learnopengl-cn.github.io/07%20PBR/01%20Theory/