Real-time Physical-Based Material
PBR:Physical-Based Render,基于物理的渲染,渲染中的任何事都应该是基于物理的,包括材质、光照、相机(透镜成像)、光线传播等。由于性能限制,RTR中说的PBR严格来说并不一定是PBR。
RTR中的PBR材质:
- 对于表面而言:大多数是微表面模型(有时候不是PBR的)和迪士尼原则的BRDF(对艺术家友好但是不是PBR,可以用在离线渲染中和实时渲染中)
- 对于体积而言:基于体积上定义的材质,多数关注的是光线在这些体积中作用一次和多次的方法,快速地、大概地计算单独散射和多重散射。
- 并没有多少新理论,但是有很多奇技淫巧
- 性能是第一要考虑的问题
微表面BRDF
回顾:在宏观上看是平的,但微观上看表面是凹凸不平的微表面,微表面法线的分布的不规则导致的渲染出的结果的差异。
微表面BRDF中有三部分:菲涅尔项
菲涅尔项
有多少能量被反射取决于入射光的角度,当入射方向接近掠射角度的时候,光线是被反射的最多的。根据导体与绝缘体的区别,反射率随视角的变化有很大不同。
菲涅尔项要综合考虑光线的s极化和p极化,为此需要知道两种介质的折射率以及入射角和折射角。实时渲染中常常用Schlick近似来近似表述菲涅尔项。
法线分布
法线分布函数(Normal Distribution Function,NDF)通过法线分布来描述不同微表面的法线朝向,从而描述微表面是否光滑。当法线分布比较集中,则会得到更Glossy的结果;如果法线分布比较分散,则会得到更Diffuse的表面。有常用的一些模型来描述法线分布(Beckmann模型、GGX模型、其他模型等)
主要介绍Beckmann和GGX两个模型。
- Beckmann NDF
作为NDF函数,自然描述的是微表面法线分布的集中程度,描述微表面上法线为(
宏观上为入射光和出射光的半程向量)方向的概率的函数,
可以是半球上任意方向(取决于宏观的入射光和出射光),描述这一方向对应的值是多少,需要NDF计算。
这个函数描述了表面的粗糙程度。表面越粗糙,NDF的积分瓣就越分散;表面越光滑,NDF的积分瓣就越击中。Beckmann 参数为半程向量
为什么用
- GGX NDF
与Beckmann形状类似,但是与Beckmann相比有个明显的优点,GGX更加长尾,比Beckmann高光更柔和。
GGX公式为:
GGX与Beckmann对比效果,明显相同粗糙度下GGX更加自然。
- GGX的拓展:GTR
GTR相比于GGX,添加了参数
几何项
另一个名称是Shadowing Masking项。解决的是微表面的自遮挡问题,尤其在视角越靠近掠射角度下,自遮挡项越关键。
自遮挡可以分为两种情况:挡住入射光线,被称为阴影(Shadowing);挡住出射光线,被称为遮蔽(Masking)。
几何项很关键的另一个原因是,BRDF函数中,分母有法线与入射方向和出射方向的点乘,而挡在掠射角度下,这两个量接近于零,因此整体结果会急剧变大,导致掠射
位置会异常发亮。几何项的存在可以避免这种情况的出现,在掠射角度让BRDF变小。
- 常用的几何项
一种常用的几何项是Smith几何项,它将阴影和遮蔽拆分,在入射时计算阴影,在出射时计算遮蔽,在垂直入射的情况下不起作用,只在掠射角度下起作用(
引入几何项后出现问题
由于没有考虑光线在表面上的多次弹射,只考虑了微表面遮挡的情况,当粗糙度越来越大的时候,能量是不守恒的,因此会出现粗糙度增大时,能量损失的情况(随粗糙度增大而整体变暗)。当表面越粗糙的时候,反射光更容易会被表面挡住,同时越粗糙的表面在表面之间弹射的次数越多,当只考虑一次弹射的时候,越粗糙的表面就损失的能量越多。
解决方法:将损失的能量补足。当光线不被遮挡的时候,这些光线会被看到;而当反射光线被微表面遮挡的时候,我们认为这些被挡住的光线经过后续弹射,直到被看到。
思路:设计一个BRDF,使得这个BRDF的积分近似为丢失的能量,这样原来的光照+补偿光照就不会损失能量了
Kulla-Conty估计方法
Kulla-Conty估计方法就是通过经验来补足多次反射丢失的能量。
我们可以计算着色点向正半球各方向发射出去的总能量
这里假设任何方向入射的光线亮度为1(也就是渲染方程的光线项为1),假设BRDF是各向同性的。最终积分结果的含义是,在所有的光线亮度均为1的情况下,经历了光线1次弹射后(也就是直接光照然后反射)射出的总能量是。那么丢失的能量就是
。
我们也可得知,不同出射方向积分得到的值是不同的,因此不同观察方向损失的能量就是。考虑BRDF的可逆性,除了考虑出射
方向,还要考虑入射的
方向(也就是要考虑入射丢失的和出射丢失的),同时乘归一化量
,得到我们需要设计的BRDF为
,要求将这个BRDF积分后,要等于恰好等于丢失的能量
。
这么设计BRDF的原因是因为简单直观,我们保留下需要求出来的积分值,并且考虑由于BRDF可逆性的另外半边的
,剩下的部分我们写成一个常数c不去管他,只要求BRDF积分恰好等于丢失能量即可,当然这个c是可以求出来的:
那么,我们就得到了损失能量的BRDF:
如果我们要检验一下我们得到的BRDF形式是否正确:
检验后发现所求的能量正好是消失的能量。Kulla-Conty的原理是希望设计一种可以交换输入输出方向的BRDF(也就是
但是,我们使用的
此时依然有问题出现
当单次反射的BRDF是有颜色的,意味着能量发生了吸收,能量消失是应该存在的,一次反射的能量与多次反射的能量积分不为1了。
Kulla-Conty方法也考虑这种情况:先考虑没有颜色的情况,然后再考虑由于颜色吸收引起的能量损失。为此需要定义平均菲涅尔项,表示了不考虑观察方向的情况下,菲涅尔项的平均值。等价于,不管入射角多大,平均每次反射会有多少能量反射。
考虑到,一次反射的光照并不会被吸收,被吸收的是补偿光照的一部分。每一次反射都会有
最终累加会得到颜色项,将这个颜色项乘到不考虑颜色的BRDF上,从而得到有颜色的时候除去吸收能量外应该补足的能量。
Linearly Transformed Cosines(LTC,线性变换余弦)
能帮助计算微表面下的着色问题,但是有条件:主要是GGX法线分布、不考虑阴影、统一亮度的多边形光源下。
多边形光源照明在理论上不难实现(采样方法),但这在实时渲染领域有两个挑战:首先,积分球面多边形上的分布是一件困难的事, 或有巨大开销,或不存在解析解;其次,基于物理的材质模型拥有一个复杂的分布,包含粗糙度、各向异性划痕和倾斜度等基于物理的特性。
主要思路:任意2D的BRDF积分瓣能被转换成余弦分布(一种新的球面分布),那么原本光源的形状也能会随之变化,变换后的光源照亮变换后的BRDF和变换前是等价的。
为什么这么做:对于任意的BRDF和任意的光源,计算渲染方程的积分不好计算,但经过变换后,问题转换成了在固定的余弦下对于任意的多边形光源进行积分的问题。这样的积分问题是有解析解的。
核心方法:
- 在固定入射方向后,我们将BRDF出射的积分瓣转变为一个余弦函数
-
变换矩阵M能使固定的cosine变换成BRDF,也能使积分域(光源方向)随之转换(通过M逆变换)
LTC.png -
完成换元,因为无法解积分,所以引入贾可比项
LTC公式.png
Disney Principle BRDF(迪士尼原则的BRDF)
原因:微表面模型无法描述更多的真实材质,微表面模型对艺术家不友好。
目的:并不要求物理上准确,但是对艺术家友好,但还会把迪士尼原则的BRDF认为成PBR
好处/坏处:好懂、好控制,参数空间大,能表现宽泛的材质模型,开源的实现,但不是基于物理的。
具体详见:毛星云《PBR白皮书》
Non-Photorealistic Rendering(NPR,非真实感渲染)
NPR=(快速地、可靠地)风格化。NPR的目的是为了制造一种艺术化的效果,从而使得渲染结果虽然远离真实感,但是有自己独特的风格和特点,且能够清晰地完成想要的表达。NPR通常是一些轻量级的处理,一般是在shader中做一些简单但是很聪明的处理从而完成风格化.。
从真实渲染出发->抽象->强化重要的部分
NPR在艺术、渲染可视化、指示说明、教育、娱乐等领域应用广泛。
最后总结:NPR最重要的过程是艺术风格分析的过程,是一个艺术翻译的过程。
简单介绍了一些效果的做法。
描边效果
首先为模型的各个边缘分类和定义。B是面的边缘,C是折痕,M材质交界,S要被多个面共享的C。
着色方法:
-
方法一是将法线与视线垂直的表面(掠射部分)加深。可以使用阈值,可以使用step function(阶梯函数,比如大于某个值为1,小于某个值为0)。
描边边缘着色.png -
方法二将模型扩大一圈然后渲染,就会有边缘描边效果。方法:正常渲染正面的面,将背向相机的面扩大一圈,然后渲染。(普遍采用的方法)
背面放大.png - 方法三是图像空间的后处理方法:使用Sobel算子方法提取边缘然后描边。除了在最后的渲染结果上进行图像处理,我们还可以在其他的图中进行处理,如法线图、深度图等。
大色块效果
- 方法一,硬着色,在着色过程中应用阈值(可以多阈值)
-
方法二,在后处理阶段应用阈值
colorblock.png
表面风格化
例如想要获得素描风格化效果,可以选择的步骤是:
- 设计不同笔触的纹理
-
为每个纹理生辰MipMap,达到搜索适配效果。
素描MipMap.png