基于胡诌的物理光照模型

前言

在实时渲染的领域里,所有的东西都是胡诌的,只有相对胡诌和没那么胡诌的区别。PBR材质就是相对没那么胡诌的那个,当中还是有大量的东西是很随便的。

材质参数

我们都知道经典的Phong材质控制五个参数,除去Ambient之外,有:

  • Diffuse Intensity

  • Diffuse Color

  • Specular Intensity

  • Specular Color

  • Specular Hardness

反正就是这五个自由量了,我们把它转换成另外的一些参数:

  • Albedo Color:反照颜色

  • Metalness:金属性,或导电性

  • 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,只不过我们在简化它的时候不精确地简化成了漫反射而已。

BRDF和微表面理论

讲完了胡诌的Albedo,就是没那么胡诌的BRDF了。讲数学、讲物理,我是怎么都不够那些大神来的了。大家在读这一节的时候,记得要跟龚敏敏的文章和Real Time Rendering一起看。

BRDF(双向反射分布函数)是仅仅对表面反射的度量,表面以下的散射情况是不考虑的。它是一个描述“从某个方向射入的光线,从哪些方向上反射出去了呢?”的分布,或者“从某个方向看到了一束光线,它可能是由哪些方向射进来的光线的反射光组成的呢?”的分布,这是它“双向”的意义所在。分布是Solid Angle空间上的,也就是弧度角的三维版,不过我们大可不去关心它。

BRDF虽然度量所有的反射光线,但是没有规律可循的反射,我们刚才放在Albedo里一起算了。所以现在算的就只有有规律可循的,也就是镜面反射的。所以我们引进了微表面模型来度量镜面反射。总结来说,我们对射出光线的三种分类:

*次表面散射(SSS)漫反射(Diffuse)镜面反射(Specular)
实时渲染AlbedoAlbedoMicrofacet
简化模型0AlbedoMicrofacet
物理度量BSSDFBRDFBRDF

微表面模型的核心是假设了物体由很多微小的__完美镜面__组成,并且创造出“宏观法线”和“微观法线”的概念。所谓宏观法线,就是在描述物体形状时计算出来的法线,或者法线贴图中采出来的法线。而微观法线,是用来衡量物体微观、微表面下的粗糙程度用的,它对材质的光学性质有很大影响,但是不描述物体的几何性质。

两个法线是有一定联系的,毕竟宏观是由微观组成的。微表面大多数还是和宏观表面同向,但是呈现一定的概率分布。对于粗糙的表面来说,貌合神离,很多微表面朝向其它方向;对于光滑的表面来说,众志成城,大家都向反射同一个方向的光。

微表面度量镜面反射,抛弃所有无法将光线反射到人眼中的微表面。没有被抛弃的那些微表面,拥有Half Vector,它们是光源和人眼之间的完美镜面。Half Vector是什么?记不记得以前算Specular是怎么算的,用视线和光线之和,跟法线求点积。对,现在你知道Half Vector是什么了。

$$
h = \text{normalize}(v + l)
$$

Cook-Torrance Model

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): 菲涅耳反射项。解决的是颜色和反射强度的光学问题。

Distribution

单纯按照一个表面的法线未必能把光源的光反射给你,但是它下面的一个微表面或许可以。显然,这样的微表面的法线与宏观表面越是接近,出现的机率就越大。这很容易用一个概率密度函数去表达。只要是围绕一个中心分布,你喜欢的话可以用正态分布、学生氏分布 —— 但是在图形学里我们更喜欢Beckmann分布,它更有物理背景。

$$
\alpha = \text{Roughness}^2 \\
D(n, h) = \frac{\alpha^2}{\pi((n \cdot h)^2 (\alpha^2 - 1) + 1)^2}
$$

Geometry

这个因子在考虑光线的射入和射出可能会被遮挡的问题。

$$
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方程,它描述了反射光强度和反射角度的关系。

不知道大家以前学大学物理光学的时候,有没有接触过偏振光。一束自然光里常常会有两种偏振态的偏振光,两种的电场方向相互垂直。电场方向与反射介质平面的夹角越是小的一方,就越容易被反射。以前做过相关练习题,到现在还有印象。大家也可以试着回忆一下以前物理老师讲过的偏振原理。

根据物理测量,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,就可以做出不同粗糙程度的环境贴图了。

参考资料

对,但是本文没有插图,因为我太懒了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值