PBR基础理论通俗解释
今天给大家介绍PBR的基础理论, 不会涉及比较深的具体算法, 算是一篇扫盲的文章, 尽量尝试说人话, 让大家能够对PBR有基本的了解.
什么是PBR?
PBR是基于物理的渲染(Physically Based Rendering), 也就是说通过模拟物理世界的方式来渲染.
既然有基于物理的渲染, 那么肯定就有不是基于物理的渲染呗?
事实上的确是存在各种渲染方式, 比如早期的基于经验的渲染模型: Phong, Blinn-Phong, 基于非真实感的渲染: 卡通渲染等.
PBR基本上可以算作是现代的渲染技术, 比起传统的Phong之类基于经验的渲染技术, PBR的结果显得更加真实, 而且对于使用者(程序, 美术)来说更加简单(只是使用简单).
为什么这么说呢? 因为基于经验的渲染需要使用者根据自己的感受一点点调整渲染参数, 使结果看起来更真实, 而PBR可以使用现实世界物质的参数来调整效果, 天然就会显得更真实, 而且不受各种条件比如光照的限制. 当然, 因为要模拟现实物理世界, 计算量会显著增加, 对硬件的性能要求更高.
大家有时也会听到PBS, 即所谓基于物理的着色(Physically Based Shading), PBR是一个大的过程, 而PBS是其中最重要的部分, 也就是所谓的上色过程.
我们研究着色, 其实最主要就是研究光照与物体表面的交互, 最终呈现给大家看到的颜色而已.
当然, PBS也只是对物理世界的近似模拟, 所以叫基于物理的着色而不是物理着色, 其实质也不过是使其看起来真实而已, 在看不到的地方也不需要着色, 可以理解为只是一层虚假的外壳.
PBR有几个最重要的理论或者原则:
- 基于物理的光于表面交互理论
- 基于微表面理论的表面模型
- 能量守恒: 出射光线的能量不会超过入射光线的能量
- 渲染方程和反射方程: 根据各种条件, 求出某一点的颜色
- BXDF: 各种双向反射分布函数
下面我们会分别简单介绍, 当然, 不会太过深入.
光与物体表面的交互
在物理世界中, 光与物体的交互十分复杂, 为了在计算机中模拟这种交互, 我们不得不做特殊处理, 并且只考虑一些特殊情况, 让渲染结果"看起来"像是真的.
模拟光照时, 在考虑物体表面一个点时, 我们首先考虑它是完全光学光滑的(optically flat), 因为空气与物体的折射率(refractive index)不一样, 光线从空气穿过, 照射到物体表面时会大致分散成两个方向(这些都是初中的物理知识), 一个是在接触点被反射的反射方向, 一个是穿过接触点进入物体的折射方向.
我们先上一张图备用:
反射方向(Reflection)
在比较光滑的表面上, 截取一部分区域, 让光线照射到这个区域, 则反射光线大致会朝着同一个方向, 平行的入射光线, 出射光线基本也是平行的, 这种光线我们称为镜面反射高光(Specular Light), 这种光的特点是范围小, 亮度高.
同理, 在比较粗糙的表面上, 截取一部分区域, 让光线照射到这个区域, 则反射光线大致会朝着不同的方向反射, 这种光线我们称为漫反射光(Diffuse Light), 这种光的特点是范围大, 亮度低. 下面要介绍的次表面散射也通常被考虑是漫反射光的一部分.
两个术语都比较形象, 让人很容易理解. 也就是说镜面光是朝着某个方向反射, 而漫反射光是朝着各个方向上反射.
在物理世界中, 任意物体上, 基本都有镜面高光和漫反射光, 只是程度不一样.
折射方向(Refraction)
折射光线穿入物体内部, 一部分光被吸收(Absorbing)转化为其它形式的能量, 比如热能, 一部分发生所谓散射(Scattering), 也就是与粒子撞击后被改变了传播方向, 在物体内部四处继续传播, 有些再次被吸收, 有些从表面发射出去, 这些被发射出去的散射光被称为也是一种漫反射光, 根据出射点与入射点的距离可以进一步划分, 如果这个距离大于我们要绘制的像素大小, 那么要特殊处理这种漫反射, 我们称这种特殊的漫反射为次表面散射, 通俗理解就是被物体内部的表面散射之后的光.
最后, 如果再次散射出来的光处于物体的另一侧, 感觉像是光穿透了物体, 出现了透光现象, 这种就被称为透射(Transmittance).
次表面散射(Sub-Surface Scattering)
那么为什么需要在出射点与入射点的距离大于要绘制的像素大小才需要特殊考虑呢? 我个人觉得, 如果这个距离太短, 说明在很浅的地方就被散射出去, 让人看起来就是在接触点反射的光, 这种光当做普通的漫反射处理就行了, 而距离大了之后, 亮度被分散, 这是一种特殊的现象, 所以要区分开来看. 至于在实践过程中到底什么时候需要考虑, 从我个人的经验来讲, 更多的是美术同学的主观判断为主. 他们会制作渲染这种效果的材质, 就是所谓的SSS材质.
有些物质的密度比较大, 粒子之间关系比较紧密, 光线很难穿透, 或者只是在很浅的地方就被反射, 比如金属, 光照射在这类物体上时, 大部分被反射, 小部分折射后几乎都被吸收了, 很少会再次散射出来, 所以在这些物体上我们一般不考虑次表面散射现象.
有些物质密度比较小, 粒子之间存在明显的间隙, 比如皮肤, 牛奶, 玉石等, 特别是比较薄的地方, 光线照射后部分发生反射, 部分发射折射, 而且部分被吸收, 部分再次散射出来, 我们就需要考虑次表面散射, 这样才能显得比较真实.
上图是一些有无次表面散射渲染的对比, 可以明显的看出来有SSS的效果会更好.
基于微表面理论的表面模型
几乎所有的PBR技术都是基于微表面理论: 所有表面在微观层面都可以被划分成微小的凹凸不平, 不同朝向, 不同大小的完美反射的镜面, 即所谓微表面(microfacets).
微表面可以简单的近似认为是日常概念中的点, 这些点有不同的法线, 可以将入射光线朝着不同的方向反射. 那么我们可以把平面看作是无数点的集合, 而最终我们看到的物体颜色就可以认为是所有这些点对于入射光线的反射光线的集合. 当然, 这里没有考虑物体自发光, 只讨论反射.
当大部分微表面反射的光线朝向大致相同时, 表面看起来就越光滑, 反之显得越粗糙, 在微观层面, 每个微表面都是完美的镜面反射面, 我们通过定义粗糙度, 利用概率理论来计算微表面在着色区域的概率, 最终得出反射光线的贡献量, 把所有的反射光线合并起来就是我们最后看到的着色效果.
Cook-Torrance模型
基于微表面理论的表面模型各种各样, 其中最常用也是影响最大的模型是1982年发表在ACM Computer Graphics上的论文, 介绍了一种名为Cook-Torrance的模型. 也可以从这里查看原文. 现在很多引擎使用的多是这个模型的简化版本或者变体.
在这个模型提出来之前, 大部分材质模型都是基于几何光学, 比如:
- Lambert模型: 模拟理想漫反射的经验模型
- Phong模型: 利用余弦函数和指数函数模拟高光的经验模型
- Blinn-Phone: 在Phong的基础上, 优化了掠射角(grazing angle, 或者叫入射余角)的经验模型
这些模型基于几何光学和经验来模拟着色, 可以模拟一部分物理世界中的物质, 但是有很浓重的不真实感(塑料感很强), 无法很好的无法模拟表面粗糙的物体, 特别是高光的表现力不强, 而且极其受各种环境条件的影响, 如光照等.
而Cook-Torrance模型基于微表面理论, 将平面划分为无数的微表面, 通过粗糙度来操控反射方向, 既可以很好的模拟表面光滑的物体(比如塑料), 对表面粗糙的物体模拟效果也是极好的.
Cook-Torrance模型与传统模型的最大区别在高光项和漫反射项的处理, 增加了很多因素和条件来使得反射更加真实, 比如菲涅尔项(Fresnel), 微表面反射分布函数(也就是常说的BRDF之类的), 阴影遮挡项等.
传统模型使用单一的法线来定义表面的方向, 细节处理能力较弱, 而Cook-Torrance模型使用概率型的法线分布函数(D)来计算任意方向的微表面在着色区域存在的概率以便得到结果反射光的贡献量.
可以看到, 随着粗糙度的增加, 高光区域越来越大, 亮度越来越低. 因为加入了菲涅尔项, 第二和第三个球的出现了光晕现象, 显得更加真实.
能量守恒
能量守恒要求: 出射光线的总能量不能超过入射光线的总能量(自发光除外).
在现实世界中, 越光滑的物体, 高光范围就越小, 越亮, 越粗糙的物体, 高光的范围越大, 越暗, 甚至于看不出来. 还记得小时候我们用小镜子反射阳光到教室里的场景么, 在那个小范围内光线特别亮, 如果我们使用粗糙的物体就达不到类似的效果了. 这是因为越光滑的物体表面直接反射的光越多, 所以显得亮, 越粗糙的物体表面散射越多, 被吸收的能量越多才显得暗. 所以满足能量守恒的模拟才会显得比较真实.
按照上面的理解, 我们将出射光分为反射部分和折射部分, 通过两者能量在入射能量所占比例来计算两者, 遵循的能量守恒定律要求, 两者都不会超过1.
渲染方程和反射方程
渲染方程(The Rendering Equation)是用来描述光能在整个场景中的流程过程, 是整个光照模型抽象理论的数学表达.
现在大部分的渲染技术基本都是某种渲染方程的实现或者变体.
在这篇文章中, 我不会展开来介绍, 因为这基本上算是渲染劝退大部分人的地方, 也就是门槛所在, 各种理论和数学公式让人头皮发麻.
总之简单理解大体意思就是我们看到的光是由物体的自发光加上入射光在各个角度上的反射光的和, 其中由各个参数来描述反射光线.
要理解这些, 需要一些前置知识, 比如辐射度量学, 可以参考我的另外一篇文章, 后面也会另写文章更加详细的介绍.
这里简单的理解, 所谓渲染方程就是我们做渲染的理论基础, 所有的光照, 着色都是在这种方程的指导下实现的.
反射方程
在去除自发光部分后, 我们得到渲染方程的一个特例, 就是所谓反射方程(The Reflection Equation), 专注研究反射部分.
BXDF
BXDF描述入射光线经过某个平面反射后如何在各个出射方向上分布, 也就是入射光线的在各个方向的反射比例, 函数结果一般是一个[0, 1]的数值, 0代表没有反射, 1代表全部反射, 针对不同的渲染效果, 有不同的反射描述函数, 一般统称为BXDF.
其中的"X"代表各种变体. 可以是反射, 也可以是散射, 也可以是投射, 也可以是次表面散射等.
这里的"B"代表是双向, 说的是入射方向和观察方向. 也就是说BXDF函数描述的是入射方向的光线在观察方向反射的比例, 如果绕着表面法线旋转入射方向和观察方向, 不会改变BXDF的结果, 那么就说这个BXDF是各向同性的(isotropic), 反之则是各向异性的(anisotropic).
BXDF大致有以下变体:
- BRDF: 双向反射分布函数(Bidirectional Reflectance Distribution Function), 最常用的函数形式, 可以实现大部分不透明渲染效果, 主要描述常规的漫反射和高光反射
- BTDF: 双向透射分布函数(Bidirectional Transmittance Distribution Function), 用于描述透射的分布函数
- BSDF: 双向散射分布函数(Bidirectional Scattering Distribution Function), 是BRDF和BTDF的结合
- BSSRDF: 双向表面散射分布函数(Bidirectional Scattering-Surface Reflectance Distribution Function), 用于描述表面散射的分布函数, 在BRDF的基础上考虑了次表面散射效果, 次表面散射简单理解为出射点与入射点不在同一个位置, 而且这个位置差异可见
总结
今天给大家介绍了PBR中最重要, 同时也是最基础的一些概念, 大部分来自于各个教材和博客的二次加工, 基本上是我自己的理解, 当然, 也只是我的一家之言, 可能有些地方理解不到位, 大家按需获取就行了.
我也相信随着分享的文章越来越深入, 自己对于渲染的理解也会更加完善, 我也是和大家一样, 行走在学习的路上.
由于渲染相关的概念涉及到了大量的理论和多个领域的知识, 特别是基础的数学和物理理论, 很容易给大家造成劝退效果, 所以我分享的文章会尽量朝着比较容易理解的方向使劲. 不过为了保证完整性, 对于理论的介绍和数学公式的推到也会涉及一些, 还是老话, 大家按需理解吧.
好了, 今天就是这样, 还是希望对大家有些许帮助就好.