在实时渲染的领域里,全部的东西都是胡诌的,只有相对胡诌和没那么胡诌的区别。PBR材质就是相对没那么胡诌的那个,当中仍是有大量的东西是很随便的。程序员
咱们都知道经典的Phong材质控制五个参数,除去Ambient以外,有:segmentfault
Diffuse Intensity函数
Diffuse Colororm
Specular Intensity游戏
Specular Colorip
Specular Hardnessget
反正就是这五个自由量了,咱们把它转换成另外的一些参数:博客
Albedo Color:反照颜色数学
Metalness:金属性,或导电性it
Fresnel Color:菲涅耳颜色,即反射颜色
Roughness:粗糙度,即1 - Glossiness(光滑度)
略有差异,可是大都是对应的,除了Diffuse Intensity,由于从如今开始Diffuse Intensity是一个常量了,与材质无关的常量。
$$
L = (f_{\text {Albedo}}(v, l, c_{\text {Albedo}}) + f_{\text {Specular}}(n, l, v, c_{\text {Fresnel}})) \otimes c_\text {Light} \cdot \pi (n \cdot l)
$$
咱们看这个公式整体上是一种(A+B)*C的感受。C是一切视觉的源头 —— 光,因此它做为整个式子的一个因子乘进去。$\pi (n \cdot l)$跟咱们之前用Phong模型的时候算diffuse部分的方式同样:不难理解,越是斜的面越难以接收到光。$c_\text {Light}$是光的颜色,你能够根据距离衰减即不少其它的因素,决定这个颜色,也没必要局限在0到1的范围内,反正咱们有HDR。
剩下的A+B,就分别是Albedo项和Specular项了。跟Phong模型相比,而Specular仍然是完美的镜面反射。可是Diffuse项不见了,变成了Albedo项。
不知你们还记不记得Diffuse的意义:表面均匀反射光源的方向到半球各个方向。而Albedo是这样一个意义:不知道从哪里来可是在通过若干(物体内部或者表面的)反射散射以后,总而言之,这表面上这一点射出的一堆杂乱的光线”。二者不一样的是,Diffuse咱们知道光线是从哪里射入的,也知道从哪里射出。可是Albedo咱们不知道光线是从哪里射入的,包括漫反射和次表面散射。这个很是难以估量。
“哦,很是难以估量对吧”。游戏程序员听完光学专家的报告后,一摔笔记本,“那咱们他妈就不算了”。今后在不少游戏里,就有:
$$
f_{\text {Albedo}}(v, l, c_{\text {Albedo}}) = \frac 1 \pi c_{\text {Albedo}}
$$
也就是说直接乘了一个系数平衡一下外面光照的那个$\pi$。对就是这么任性。咱们能够看到把这一项提到括号外面以后,是否是有一种Lambertian模型漫反射的感受,虽然它的意义是反照。这就是为何我刚才说漫反射系数变成了常数(1)。而不少地方在讲这一项的时候,仍是把它说成是Diffuse或者Lambertian Model。可是要记住,这实际上是Albedo,只不过咱们在简化它的时候不精确地简化成了漫反射而已。
讲完了胡诌的Albedo,就是没那么胡诌的BRDF了。讲数学、讲物理,我是怎么都不够那些大神来的了。你们在读这一节的时候,记得要跟龚敏敏的文章和Real Time Rendering一块儿看。
BRDF(双向反射分布函数)是仅仅对表面反射的度量,表面如下的散射状况是不考虑的。它是一个描述“从某个方向射入的光线,从哪些方向上反射出去了呢?”的分布,或者“从某个方向看到了一束光线,它多是由哪些方向射进来的光线的反射光组成的呢?”的分布,这是它“双向”的意义所在。分布是Solid Angle空间上的,也就是弧度角的三维版,不过咱们大可不去关心它。
BRDF虽然度量全部的反射光线,可是没有规律可循的反射,咱们刚才放在Albedo里一块儿算了。因此如今算的就只有有规律可循的,也就是镜面反射的。因此咱们引进了微表面模型来度量镜面反射。总结来讲,咱们对射出光线的三种分类:
* | 次表面散射(SSS) | 漫反射(Diffuse) | 镜面反射(Specular) |
---|---|---|---|
实时渲染 | Albedo | Albedo | Microfacet |
简化模型 | 0 | Albedo | Microfacet |
物理度量 | BSSDF | BRDF | BRDF |
微表面模型的核心是假设了物体由不少微小的__完美镜面__组成,而且创造出“宏观法线”和“微观法线”的概念。所谓宏观法线,就是在描述物体形状时计算出来的法线,或者法线贴图中采出来的法线。而微观法线,是用来衡量物体微观、微表面下的粗糙程度用的,它对材质的光学性质有很大影响,可是不描述物体的几何性质。
两个法线是有必定联系的,毕竟宏观是由微观组成的。微表面大多数仍是和宏观表面同向,可是呈现必定的几率分布。对于粗糙的表面来讲,貌合神离,不少微表面朝向其它方向;对于光滑的表面来讲,众志成城,你们都向反射同一个方向的光。
微表面度量镜面反射,抛弃全部没法将光线反射到人眼中的微表面。没有被抛弃的那些微表面,拥有Half Vector,它们是光源和人眼之间的完美镜面。Half Vector是什么?记不记得之前算Specular是怎么算的,用视线和光线之和,跟法线求点积。对,如今你知道Half Vector是什么了。
$$
h = \text{normalize}(v + l)
$$
Cook-Torrance是在微表面理论上创建的模型,引入了Roughness这一个参数,做为整个模型的核心,核心思想是度量拥有Half Vector的可见微表面数量。咱们先回顾一下刚才谈到的概念:
只有拥有Half Vector的微表面能提供Specular高光
微表面法线(就是微观法线)整体跟宏观表面一致,可是有必定的分布
微表面有可能不可见,稍微要调整一下
咱们为了计算Specular高光,就是要计算表面上__可见的、拥有的Half Vector的微表面__。因此,咱们一个一个解决这些问题。
$$
f_\text{CookTorr}(n, v, l) = \frac{DGF}{4(n \cdot l)(v \cdot n)}
$$
分母是用来保持能量和一些经验参数,不去深究。咱们来一个一个看看DFG分别解决的是什么问题:
Distribution(n, h): 分布项。解决的最基本的数量问题。
Geometry(l, v, h, n): 几何项。解决的是可见的问题。
Fresnel(n, l, h): 菲涅耳反射项。解决的是颜色和反射强度的光学问题。
单纯按照一个表面的法线未必能把光源的光反射给你,可是它下面的一个微表面或许能够。显然,这样的微表面的法线与宏观表面越是接近,出现的机率就越大。这很容易用一个几率密度函数去表达。只要是围绕一个中心分布,你喜欢的话能够用正态分布、学生氏分布 —— 可是在图形学里咱们更喜欢Beckmann分布,它更有物理背景。
$$
\alpha = \text{Roughness}^2 \\
D(n, h) = \frac{\alpha^2}{\pi((n \cdot h)^2 (\alpha^2 - 1) + 1)^2}
$$
这个因子在考虑光线的射入和射出可能会被遮挡的问题。
$$
k = \frac {(\text{Roughness} + 1)^2}{8} \\
G_1(x, n) = \frac{n \cdot x}{(n \cdot x)(1 - k) + k} \\
G(l, v, h, n) = G_1(l, n)G_2(v, n)
$$
握草这一大堆什么来的。不急不急咱们慢慢看一下。k就是遮挡率了,一个由粗糙度算出来的经验参数。在遮挡率接近0的时候,G1也接近1,也就是几乎全部的微表面都能被看到,固然,不多是0,由于算不出来(笑)。在遮挡率接近1的时候,G1接近nx,也就是越是垂直于表面的光线难以被遮挡,越是斜的光线越是被遮挡得多。
刚才咱们一直都在算微表面的数量,而如今作的则是相似于之前算反射强度的那一步,而且把反射颜色引入进来。固然了,如今算的就不是什么点积了,那不物理。物理的是Fresnel方程,它描述了反射光强度和反射角度的关系。
不知道你们之前学大学物理光学的时候,有没有接触过偏振光。一束天然光里经常会有两种偏振态的偏振光,两种的电场方向相互垂直。电场方向与反射介质平面的夹角越是小的一方,就越容易被反射。之前作过相关练习题,到如今还有印象。你们也能够试着回忆一下之前物理老师讲过的偏振原理。
根据物理测量,Fresnel方程能够经过Schlick等式去近似:
$$
F_{\text{Schlick}}(l, h) = c_\text{Fresnel} + (1 - c_\text{Fresnel})(1 - (l * h)^5)
$$
这里倒没有太多咱们非物理专业能够折腾的事情了。
根据物理测量,导体的Albedo Color几乎为0,而Frenel Color各异且较高。而绝缘体的Albedo Color各异,但Fresnel Color略低(0.04),且均匀反射。游戏程序员因而又动了歪脑筋:他们一直嫌GBuffer的空间太少了。
他们把两个颜色合并成了一个颜色,称为Base Color(基调色),而后根据材质的导电程度,看看这个基调色到底是做为反照色仍是反射色。又或者是半导体 —— 既组成反照色也组成反射色。
光学原理很基础的一条就是线性性:光的叠加就是线性叠加,不是混合,没有前后。因此多光源的材质,只须要多遍渲染,而后用Plus Blend混合起来就能够了。
在多光源达到一个极致的状况下,就是处处都是光源。不少时候咱们用环境贴图来描述这些极致多的光源,一般用来描述镜面反射的结果。由于以前咱们曾经有一个Distribution项目,它让光不只仅做用在正对着光源的方向,还成几率地做用在周围。也就是一个扩散。
不知道说到Distribution你们想到什么。我想到了高斯分布、高斯卷积核、高斯滤波。我一年多之前曾经发过一篇博客[1],讲的是卷积,但愿你们还记得那只模糊的Saber。当每一点都产生了一个形状的扩散的时候,事实上就是一个卷积或者一个滤波。结果就是模糊。
在实时渲染时,咱们经常会把纹理预先滤好波,而后放在不一样Level的Mipmap上。而后在画的时候,只要替换掉刚才的Fresnel Color,就能够作出不一样粗糙程度的环境贴图了。
[2] 龚敏敏讲金属和塑料的文章:https://zhuanlan.zhihu.com/p/...
[3] BRDF的详细推导:https://zhuanlan.zhihu.com/p/...
[4] 插图集中来源:Real Time Rendering
对,可是本文没有插图,由于我太懒了。