颜色
在现实的世界中有无数钟颜色,每一个物体都有自己的本身颜色。在计算机中,我们需要吧使用(有限的)数字来模拟真实世界中的无限颜色,我们可以依靠使用数字来表示许多颜色,并且可以让人类的眼睛感觉不到任何的差异(在上篇文章提过概念)。颜色可以有RGB,Green,Blue三个分量组成,他们被缩写为RGB。
我门现实世界中看到莫一物体的颜色并不是这个物体的真实颜色,而是他所反射(Reflected)的颜色,换句话说,那些不能被物体吸收(Absorb)的颜色(被反射的颜色)就是我们能够感知到的物体颜色。例如,太阳光被认为是有许多的不同的颜色组成的白色光。入股哟我们将白光照在一个黄色的玩具上,这个黄色的玩具会吸收所有白光中除黄色以外的所有颜色,不被吸收的的黄光反射到我们的眼睛,是我们看到了一个黄色的玩具,下图显示一个珊瑚红的玩具,它以不同强度的方式反射了几种不同的颜色。
我们定义一个光源和珊瑚红正方体颜色
lightingShader.setVec3("objectColor", 1.0f, 0.5f, 0.31f);
lightingShader.setVec3("lightColor", 0.1f, 0.1f, 0.1f);
最终的颜色为:
光照基础
现实世界的光照是极其复杂的,而且会受到诸多因素的影响,这是以目前我们所拥有的处理能力无法模拟的。因此,现代计算机中我们大多数光照是用了简化的模型并基于对现实的估计来进行模拟,这样处理方便,看起来人眼也是不好察觉出差别的。这些光照模型都是基于我们对光的物理特性的理解。其中一种为(Phong Lighting Model)冯氏光照,冯氏光照模型主要是由3个元素构成,(环境)Ambient,(漫反射)Diffuse,和镜面(Specular)光照。
环境光照(Ambient Lighting):即使在黑暗的情况下,世界上也仍然有一些光亮(月亮、一个来自远处的光),所以物体永远不会是完全黑暗的。我们使用环境光照来模拟这种情况,也就是无论如何永远都给物体一些颜色。
漫反射光照(Diffuse Lighting):模拟一个发光物对物体的方向性影响(Directional Impact)。它是冯氏光照模型最显著的组成部分。面向光源的一面比其他面会更亮。
镜面光照(Specular Lighting):模拟有光泽物体上面出现的亮点。镜面光照的颜色,相比于物体的颜色更倾向于光的颜色。
环境光照
光通常都不是来自于同一个光源,而是来自散落在我们周围的光源,即使他们可能并不是那么显而易见。光的一个属性是,它可以向喝多方向发散和反弹,所以光最后到达的地点可能并不是他所临近的直射方向;光能够想这样反射到其他表面,一个物体的光照可能受到来自一个非直射的光源影响。考虑到这种情况的算法叫做全局光照算法,但是这种的开销非常的昂贵有及其复杂。
我们使用的是一个简化的全局光照,叫做环境照明。我们使用一个很小的数值常量(光颜色)添加到物体的片段的最终颜色里。
漫反射光照
环境本身不提供最明显的光照效果,但是漫反射(Diffuse Lighting)会对物体产生显著的视觉影响,漫反射光使物体上与光线排布越近的片段月能从光源·出获取更多的亮度。下图:
图左上放有个光源,他所发出的光线落在物体的片段上。我们需要测量这个光线与所接触的片段之间的角度。如果光线垂直与物体的表面,这束光对物体的影响会最大化。为了测量光线与片段的角度,我们使用法向量,它垂直于片段的表面的一种向量。
如果模型矩阵执行了不等比缩放,法向量就不再垂直于表面了,顶点就会以这种方式被改变了。因此,我们不能用这样的模型矩阵去乘以法向量。下面的图展示了应用了不等比缩放的矩阵对法向量的影响:
不论何时当我们提交一个不等比的缩放,法向量就不会在垂直于他妈的表面了,这样光照就会被扭曲。
修复这个行为的方法就是为法向量专门定制的模型矩阵。这个矩阵称之为正规矩阵(Normal Matrix),他是进行一点给线性操作的移除了对法线错误的缩放的效果。
镜面光照
和环境光照一样,镜面光照同样依据光的方向向量和物体的法向量,但是这次依据观察方向,如果我们想象物体表面像一个镜子一样,那么,无论我们从哪里去看这个表面所反射的光,镜面光照达到最大化,下图所示:
我们通过反射法向量周围光的方向计算反射向量。然后我们计算反射向量和视线方向的角度,如果之间的角度越小,那么镜面光的作用越大。他的作用效果就是,当我们去看光被物体所反射的那个方向的时候,我们会看到一个高光。
基于物理的渲染
PBR,是一种模拟真实渲染技术它们或多或少基于物理世界中的一些基础理论。由于基于物理的渲染指在以物理上合理的方式模拟光线,因此与我们的原始光照算法(phong和blinn-phong)相比,它通常看起来更真实。一些美工,通常根据物理参数来调整创作表面材质,使这个对象看起来更真实。
基于物理的渲染是对现实的近似(基于物理原理),这使它称为物理着色的原因,它必须满足3个条件:
1 基于微平面表面模型
2 能量守恒
3 使用基于物理的BRDF
微面模型
所有的PBR技术基于微平面理论,该描述了微尺度的任何表面都可以用微小的完美反射镜来描述,称为微面,根据表面的粗糙度,这些微小的小镜子的对齐方式可能又很大的差异:
表面越粗糙,每个微面将沿着表面排列得越混乱。这些微小的镜子排列的效果是,当专门谈论镜面照明/反射时,入射光线更有可能分散在更粗糙的表面上沿着完全不同的方向,导致更广泛的镜面反射。相比之下,在光滑的表面上,光线更有可能沿大致相同的方向反射,从而产生更小、更清晰的反射:
在微观层面上没有表面是完全光滑的,但是由于这些微面足够小,我们无法在每个像素的基础上区分它们,我们在统计上近似表面的微面粗糙度给定粗糙度范围。根据表面的粗糙度,我们可以计算出与某个向量大致对齐的微面的比率H这个向量H是个halfway vector它位于光l向量与视见V向量之间。
微平面与halfway vector对齐的越多,镜面反射就越清晰和越强。连同在 0 和 1 之间变化的粗糙度参数,我们可以在统计上近似微面的对齐方式:
我们可以看到,较高的粗糙度值显示出更大的镜面反射形状,而光滑表面的镜面反射形状则更小更锐利。
能量守恒
微面近似采用能量守恒:出射光能不应超过入射光能(不包括发射表面)。查看上面的图像,我们看到镜面反射区域增加,但随着粗糙度的增加,其亮度也会降低。如果每个像素的镜面强度相同(无论镜面形状的大小),较粗糙的表面会发出更多的能量,这违反了能量守恒原理。这就是为什么我们在光滑表面上看到镜面反射更强烈而在粗糙表面上更暗淡的原因。
为了保持能量守恒,我们需要明确区分漫反射光和镜面反射光。光线照射到表面的那一刻,它会分裂成两个折射一部分和一个反射部分。反射部分是直接被反射而不进入表面的光;这就是我们所知的镜面光照。折射部分是进入表面并被吸收的剩余光;这就是我们所说的漫反射照明。
这里有一些细微差别,因为折射光不会通过接触表面立即被吸收。从物理学中,我们知道光可以被建模为一束不断向前移动直到失去所有能量的能量束。光束失去能量的方式是碰撞。每种材料都由微小的粒子组成,这些粒子可以与光线发生碰撞,如下图所示。粒子在每次碰撞时吸收部分或全部光能,然后转化为热能。
一般来说,不是所有的能量都被吸收,光会继续分散在(大部分)随机方向上,它与其他粒子碰撞,直到其能量耗尽或再次离开表面。从表面重新出现的光线有助于表面观察到(漫射)颜色。然而,在基于物理的渲染中,我们做了一个简化的假设,即所有折射光都在非常小的撞击区域被吸收和散射,忽略了在远处离开表面的散射光线的影响。考虑到这一点的特定着色器技术被称为次表面散射显着改善皮肤、大理石或蜡等材料的视觉质量的技术,但是以性能为代价的。
当涉及到反射和折射时,另一个微妙之处是表面金属的. 与非金属表面相比,金属表面对光的反应不同(也称为电介质)。金属表面遵循相同的反射和折射原理,但所有折射光都被直接吸收而不会散射。这意味着金属表面只留下反射光或镜面光;金属表面不显示漫反射颜色。由于金属和电介质之间的明显区别,它们在 PBR 管道中的处理方式不同。
反射光和折射光之间的这种区别使我们看到了关于能量保存的另一个观察结果:它们是相互排斥的。任何被反射的光能都将不再被材料本身吸收。因此,作为折射光进入表面的能量直接是我们考虑反射后产生的能量。
我们通过首先计算反射入射光能量百分比的镜面反射分数来保持这种能量守恒关系。然后直接从镜面反射部分计算折射光的部分:
这样我们既知道入射光的反射量,也知道入射光的折射量,同时遵守能量守恒原理。鉴于这种方法,折射/漫射和反射/镜面反射的贡献不可能超过1.0,从而确保它们的能量总和永远不会超过入射光能量。
反射方程
这给我们带来了一个叫做渲染方程的东西,这是一些非常聪明的人提出的一个复杂的方程,它是目前我们用来模拟光的视觉效果的最佳模型。基于物理的渲染强烈遵循渲染方程的更专业版本,称为反射方程. 要正确理解 PBR,首先要对反射率方程有一个扎实的理解,这一点很重要:
正如之前我上篇日志光照学,辐射测量时电磁波的测量,包括可见光。我们可以使用几个辐射量来测量表面和方向上的光,我们只讨论与反射率相关的辐射量,称为辐射,这里表示为L,辐射量用于量化单个方向的光或强度。
辐射通量:辐射通量Φ是以瓦特为单位测量的光源的透射能量。光是多个不同波长的能量总和,每个波长与特定的(可见)颜色相关联。因此,光源的发射能量可以被认为是其所有不同波长的函数。390nm 到 700nm(纳米)之间的波长被认为是可见光谱的一部分,即人眼能够感知的波长。下面是每个日光波长不同能量的图像:
辐射通量测量不同波长的这个函数的总面积。直接将这种波长测量作为输入有点不切实际,因此我们经常简化表示辐射通量,不是作为不同波长强度的函数,而是作为编码为RGB(或者我们通常称之为:光颜色)。这种编码确实会丢失相当多的信息,但这对于视觉方面通常可以忽略不计。
立体角:立体角,记为ω,告诉我们投影到单位球体上的形状的大小或面积。投影到这个单位球面上的面积称为立体角; 您可以将立体角可视化为具有体积的方向:
想象成为这个单位球体中心的观察者,并朝形状的方向看;您从中制作的轮廓的大小是立体角。
辐射强度:辐射强度测量每个立体角的辐射通量,或光源在单位球体上投影面积上的强度。例如,给定一个在所有方向上均等辐射的全向光,辐射强度可以为我们提供它在特定区域(立体角)上的能量:
描述辐射强度的方程定义如下:
其中,I是辐射通量Φ除以立体角ω。
有了辐射通量、辐射强度和立体角的知识,我们终于可以描述辐射方程了。辐射度被描述为一个区域内观察到的总能量在立体角ω上的辐射强度Φ:
辐射度是一个区域内光量的辐射测量值,根据入射光与表面法线的夹角θ作为cosθ:径直辐射到表面的光最弱,直接垂直于表面的光最强。这类似于我们在Phong对漫反射照明的理解,cost θ直接对应于光的方向向量和表面法线之间的点积:
辐射方程很有用,因为它包含了我们感兴趣的大多数物理量。如果我们考虑立体角ω和区域A无限小的点,我们可以用辐射度来测量空间中某一点的单光通量。这种关系允许我们计算影响单个(碎片)点的单个光线的亮度;我们有效地将立体角ω转换为方向向量ω,并将a转换为点p。这样,我们可以直接在着色器中使用亮度来计算单个光线的每个碎片的贡献。
事实上,当谈到辐射时,我们通常关心所有入射到一个点上的光p,它是所有辐射的总和,称为辐照度. 有了辐射度和辐照度的知识,我们可以回到反射率方程:
我们现在知道渲染方程中的L代表了某个点p和某个入射的无极小立体角ωi的亮度ωi可以被认为是入射方向向量ωi。记住,进行缩放能量是光对表面入射角cos θ乘积,我们在反射方程中发现入射角为n⋅ωi。反射率方程计算一个点p在向观众输出方向ωo方向上的反射亮度Lo(p,ωo)之和。或者换句话说:Lo从ωo的角度测量光在点p上的反射和。
反射率方程是基于辐照度的,它是我们测量的所有入射辐照度的总和。不仅仅是一个入射光的方向,而是一个半球内所有入射光的方向Ω以点p为中心。一个半球可以被描述为一个半球体,并围绕一个表面的法线n排列:
为了计算一个区域或(在一个半球中)一个体积内的值的总和,我们使用一个称为积分的数学结构,在反射方程中表示为∫对半球 Ω内所有入射方向dωi进行积分。积分测量函数的面积,可以用解析法或数值法计算。由于渲染和反射方程都没有解析解,我们想要离散地数值解决积分。这转换为在半球Ω上获取反射方程的单位离散步长的结果,并在步长上平均它们的结果。这就是所谓的黎曼和,我们可以用代码大致表示如下:
通过将步长按dW缩放,求和将等于积分函数的总面积或体积。 在反射方程中,每个离散步骤的比例dW可以被认为是dωi。 在数学上,dωi是我们计算积分的连续符号,虽然它在代码中与dW没有直接关系(因为这是黎曼和的一个离散步骤),但这样想会有所帮助。 请记住,采取离散步骤总能得到函数总面积的近似。
反射率方程汇总了整个半球所有入射光方向ωi的亮度Ω与击中点p的fr的比例,并返回在观察者方向上的反射光之和Lo。入射辐射可以来自我们熟悉的光源,也可以来自环境映射。
现在唯一未知的是fr符号,即BRDF或双向反射分布函数,它根据表面的材料属性缩放或衡量入射亮度。
BRDF
BRDF,即双向反射分布函数,是一个以入射(光)方向ωi,出射(视图)方向ωo,表面法向n,以及代表微表面粗糙度的表面参数a为输入的函数。BRDF近似计算了在给定材料性质的情况下,每一种单独的光线ωi对不透明表面的最终反射光的贡献。例如,如果表面非常光滑(像镜子一样),BRDF函数对所有入射光线ωi返回0.0,除了与出射光线ωo具有相同(反射)角度的那一束,函数返回1.0。
Cook-Torrance BRDF 包含了漫反射和镜面反射部分:
fr=kdflambert+ksfcook−torrance
kd 是前面提到的入射光能量被折射的比率,ks是被反射的比率。BRDF的左边表示方程的扩散部分,这里用flambert表示。这被称为Lambertian diffuse,类似于我们在diffuse shading中所使用的,它是一个常数因子,表示为:
flambert=cπ
c是反照率或表面颜色(想想漫反射表面纹理)。除以pi是为了将漫射光归一化,因为前面提到的包含BRDF的积分被π缩放了。
你可能想知道这个Lambertian漫反射和我们之前使用的漫反射光照有什么关系:表面颜色乘以表面法线方向和光方向之间的点积。点积仍然存在,但是移出了BRDF,因为在Lo积分的最后我们发现n⋅ωi。
对于BRDF的扩散部分存在不同的方程,它们看起来更真实,但计算成本也更高。Epic Games总结道,Lambertian漫反射对于大多数实时渲染来说已经足够了。
BRDF的镜面部分更为先进,描述为:
fCookTorrance=DFG4(ωo⋅n)(ωii⋅n)
Cook-Torrance反射方程式BRDF由三个函数和一个归一化因子组成。每一个D, F和G符号都代表一种近似于表面特定部分反射特性的函数。它们被定义为正态分布函数、菲涅耳方程和几何函数:
⋅ 正态分布函数:受表面粗糙度影响,近似表面microfacet对齐到半边矢量的数量;这是近似于microfacet的主要功能。
⋅ 几何函数:描述microfacet的自阴影特性。当表面相对粗糙时,表面的微刻面可以遮蔽其他微刻面,减少表面反射的光。
⋅ 菲涅耳方程:菲涅耳方程描述了不同表面角度下的表面反射比。
这些函数中的每一个都是它们的物理等价物的近似你会发现每个函数的不同版本都以不同的方式来近似基本的物理;有些更现实,有些更有效率。选择您想要使用的这些函数的近似版本是完全合适的。来自Epic Games的Brian Karis做了大量关于多种近似类型的研究。我们将选择Epic Game的虚幻引擎4所使用的相同功能,即Trowbridge-Reitz GGX用于D, Fresnel-Schlick近似用于F,以及Smith
正态分布函数
正态分布函数D统计近似的相对表面积microfacets完全一致(一半)向量h。有许多统计近似的无本金交割远期外汇交易的一般对齐microfacets一些粗糙度参数和我们将使用被称为Trowbridge-Reitz GGX:
NDFGGXTR(n,h,α)=α2π((n⋅h)2(α2−1)+1)2 这里h是测量表面microfacet的中间向量,a是测量表面粗糙度的值。如果我们取h作为表面法线和光方向在不同粗糙度参数上的中间向量,我们得到以下视觉结果:
当粗糙度较低时(因此表面是光滑的),高度集中的microfacet数在一个小半径上对齐到半边向量。由于这种高浓度,NDF显示出一个非常亮的点。然而,在粗糙的表面上,microfacet以更随机的方向排列,你会发现大量的中间向量h多少与microfacet对齐(但不那么集中),给我们更多的灰色结果。
在GLSL中,Trowbridge-Reitz GGX正态分布函数转换为以下代码:
几何函数
该几何函数在统计上近似于相对表面积,其表面微细节相互遮挡,导致光线被遮挡。
与NDF类似,Geometry函数以材料的粗糙度参数作为输入,较粗糙的表面有更高的可能性遮挡microfacet。我们将使用的几何函数是GGX和Schlick-Beckmann近似的组合,称为Schlick-GGX:
GSchlickGGX(n,v,k)=n⋅v(n⋅v)(1−k)+k
这里k是α的映射,基于我们是否使用几何函数用于直接照明或IBL(基于图像照明)照明:
kdirect=(α+1)28 kIBL=α22
注意α的值可能会根据你的引擎如何将粗糙度转换为α而不同。在接下来我们将详细讨论如何以及在哪里重新映射变得相关。
为了有效地逼近几何体,我们需要同时考虑视图方向(几何体遮挡)和光方向向量(几何体阴影)。我们可以使用史密斯的方法将两者都考虑进去:
G(n,v,l,k)=Gsub(n,v,k)Gsub(n,l,k)
使用Smith的方法,将Schlick-GGX作为Gsub,在不同的粗糙度R上得到以下视觉效果:
几何函数是一个乘数之间的[0.0,1.0]与1.0(或白色)测量没有microfacet阴影,和0.0(或黑色)完整的microfacet阴影。
在GLSL中,几何函数转换为以下代码:
菲涅耳方程
菲涅耳方程描述了被反射的光与被折射的光的比率,这个比率随着我们观察物体表面的角度而变化。光线照射到表面的瞬间,根据表面对视角的角度,菲涅耳方程告诉我们被反射的光的百分比。根据这个反射比和能量守恒原理,我们可以直接得到光的折射部分.
每一个表面或材料在直视其表面时都有一定程度的基本反射率,但当从一个角度看表面时,所有的反射都比表面的基本反射率更明显。你可以自己看看你的(大概)木制/金属桌子,从垂直角度看,它有一定程度的反射,但从将近90度的角度看你的桌子,反射会变得更明显。从完美的90度角度看,所有表面理论上都能完全反射光线。这种现象被称为菲涅耳现象,用菲涅耳方程来描述。
菲涅耳方程是一个相当复杂的方程,但幸运的是,菲涅耳方程可以使用Fresnel- schlick近似:
FSchlick(h,v,F0)=F0+(1−F0)(1−(h⋅v))5
F0表示表面的基本反射率,我们使用折射率或IOR来计算。正如你在球体表面所看到的,我们越朝表面的掠射角看(半视角达到90度),菲涅耳反射就越强,因此反射:
菲涅耳方程有一些微妙之处。其一,菲涅耳-施立克近似只适用于介电或非金属表面。对于导体表面(金属),用折射率计算基本反射率是不正确的,我们需要使用完全不同的导体菲涅耳方程。由于这不便,我们进一步通过预计算表面在0度角法向入射(F0)下的响应来近似,就像直接观察表面一样。我们根据视角来插值这个值,按照菲涅耳-施立克近似,这样我们就可以对金属和非金属使用相同的方程。
表面在正常入射下的响应,或基本反射率,可以在这样的大型数据库中找到,下面列出了一些更常见的值
这里值得注意的是,对于所有介质表面,基本反射率从未超过0.17,这是例外而不是规律,而对于导体,基本反射率开始时要高得多,(主要)在0.5和1.0之间变化。此外,对于导体(或金属表面),基底反射率是着色的。这就是为什么F0被表示为RGB三重态(在正常入射时,每个波长的反射率可以变化);这是我们只在金属表面看到的东西。
与介电表面相比,金属表面的这些特殊属性产生了所谓的金属工作流。在金属工作流中,我们编写了一个额外参数称为金属度的表面材料,该参数描述一个表面是金属还是非金属表面。
从理论上讲,材料的金属性是二元的:它要么是金属,要么不是;不可能两者都是。然而,大多数渲染管道允许在0.0和1.0之间线性配置表面的金属性。这主要是因为材质纹理精度不够。例如,在金属表面上有小(非金属)灰尘/沙粒/划痕的表面很难用二元金属值渲染。
通过预计算介质和导体的F0,我们可以对两种类型的表面使用相同的菲涅耳-施力克近似,但如果我们有金属表面,我们必须对基本反射率进行着色。我们一般是这样做的:
我们定义了一个基本的反射率,与大多数介质表面近似。这是另一个近似,因为F0是在最常见的介质周围取平均值。0.04的基本反射率适用于大多数介质,并产生物理上合理的结果,而无需编写额外的表面参数。然后,基于一个表面的金属性,我们要么取介电基反射率,要么取F0作为表面颜色。由于金属表面吸收了所有的折射光,所以没有漫反射,我们可以直接利用表面的颜色纹理作为其基础。
在代码中,Fresnel Schlick近似转化为:
cos是曲面的法向n和半向h(或者视图v)方向的点积。
Cook-Torrance反射率方程
描述了Cook-Torrance BRDF的每个组成部分后,我们可以将基于物理的BRDF包括到现在最终的反射率方程中:
Lo(p,ωo)=∫Ω
(kdcπ+ksDFG4(ωo⋅n)(ωi⋅n))Li(p,ωii)n⋅ωiidωii
然而,这个方程在数学上并不完全正确。你可能还记得菲涅耳项F表示的是在一个表面上反射的光的比例。这实际上是我们的比值ks,意味着反射率方程的镜面部分(BRDF)隐含地包含了反射率比值ks。因此,我们最终的反射方程为:
Lo(p,ωo)=∫Ω
(kdcπ+DFG4(ωo⋅n)(ωii⋅n))Li(p,ωii)n⋅ωiidωii
这个等式现在完全描述了一个基于物理的渲染模型,它通常被认为是我们通常理解的基于物理的渲染,或PBR。如果您还没有完全理解我们将需要如何在代码中将所有讨论的数学组合在一起,也不要担心。在接下来的章节中,我们将探索如何利用反射方程在我们的渲染照明中获得更多的物理上可信的结果,所有的小块和小块应该慢慢地开始组合在一起。
创作PBR材料
有了PBR的基础数学模型的知识,我们将通过描述艺术家通常如何编写一个表面的物理属性来完成讨论,我们可以直接将其输入到PBR方程。我们需要一个PBR管道的每个表面参数都可以通过纹理来定义或建模。使用纹理可以让我们控制每个特定的表面点对光线的反应:这个点是金属的、粗糙的还是光滑的,或者表面对不同波长的光的反应。
下面你会看到一个纹理列表,如果提供给PBR渲染器,你会经常在PBR管道中找到它的视觉输出:
Albedo:反照纹理为每个贴图指定表面的颜色,如果贴图是金属材质,则指定基本反射率。这在很大程度上类似于我们之前使用的漫反射纹理,但所有的照明信息都是从纹理中提取的。漫射纹理通常在图像内部有轻微的阴影或黑暗的裂缝,这是你不想在反照纹理中看到的东西;它应该只包含表面的颜色(或折射吸收系数)。
Normal:法线贴图纹理和我们之前在法线贴图一章中使用的一样。法线贴图允许我们指定,每个碎片,一个独特的法线,给一个表面比它的平面更颠簸的错觉。
Metallic: 金属贴图指定每个texel是否是金属的。基于PBR引擎的设置,艺术家可以将金属元素作为灰度值或二进制黑色或白色。
Roughness:粗糙度映射指定了一个表面在每个像素基础上的粗糙度。采样粗糙度值的粗糙度影响统计microfacet方向的表面。粗糙的表面得到更宽和模糊的反射,而光滑的表面得到聚焦和清晰的反射。有些PBR引擎希望使用平滑贴图,而不是粗糙贴图,因为美术人员认为粗糙贴图更直观。然后这些值被转换(1.0 -平滑度)为粗糙的瞬间,他们被采样。
AO:环境遮挡或AO贴图指定了一个额外的表面和潜在的周围几何图形的着色因子。例如,如果我们有一个砖的表面,反照率纹理应该没有在砖的裂缝内的阴影信息。然而,AO地图明确指出了这些暗边,因为光线更难逃逸。在照明阶段结束时考虑环境遮挡可以显著提高场景的视觉质量。网格/表面的环境遮挡贴图是手动生成的,或者是在3D建模程序中预先计算的。
美工根据每个贴图设置和调整这些物理输入值,并根据现实世界材料的物理表面属性设置纹理值。这是PBR渲染管道的最大优势之一,因为表面的这些物理属性保持不变,不管环境或照明设置,使艺术家更容易获得物理上可信的结果。在PBR管道中创作的表面可以很容易地在不同的PBR渲染引擎之间共享,将看起来正确,无论他们在环境中,并作为一个结果看起来更自然。
我们现在知道了大部分的情况,但还有一个很大的未知是我们如何准确地表示辐照度,即场景的总亮度L。我们知道,辐射L(在计算机图形领域中解释)测量其中n的辐射通量ϕ或光源在给定立体角ω上的光能。在我们的例子中,我们假设立体角ω无限小,在这种情况下,辐射测量光源在单一光线或方向向量上的通量。
有了这些知识,假设我们有一个单点光源(一个向各个方向都同样明亮的光源),辐射通量为(23.47,21.31,20.79),转换为RGB三元组。这个光源的辐射强度等于它在所有出射方向上的辐射通量。然而,当在一个表面上对一个特定的点p进行着色时,在其半球Ω上所有可能的入射光方向中,只有一个入射方向矢量wi直接来自点光源。由于我们的场景中只有一个光源,假设它是空间中的一个点,所以在表面点p上观察到的所有其他可能的入射光方向都是零亮度:
如果首先,我们假设光衰减(光线随距离变暗)不影响点光源,那么无论我们将光线放置在何处,入射光线的亮度都是相同的(不包括以入射角成本θ来缩放亮度)。这是因为,不管我们从哪个角度看,点光的辐射强度都是相同的,有效地将其辐射强度建模为辐射通量:一个恒定的矢量(23.47,21.31,20.79)。
然而,辐亮度也以位置p作为输入,并且任何实际的点光源都会考虑到光的衰减,点光源的辐射强度是通过点p与光源之间的距离的某种度量来衡量的。然后,从原始辐射方程中提取,结果按表面法向量n与入射光方向wi的点积进行缩放。
把这个更实际的术语:对于直接点光源辐射函数L措施浅色,减弱其距离p和n⋅wi缩放,但只有在单一光线wi撞到p等于光的方向矢量p。这个转化为代码:
除了不同的术语外,这段代码对你来说应该非常熟悉:这正是我们目前所做的漫反射照明。当涉及到直接照明时,亮度的计算方法与我们之前计算光照的方法类似,因为只有一个光方向向量有助于表面的亮度。
【请注意,这个假设是成立的点光无限小,只有一个单一的点在空间。如果我们要模拟一个有面积或体积的光,它的亮度将在多个入射光方向上是非零的。】
对于来自单一点的其他类型光源,我们用类似的方法计算辐射度。例如,定向光源具有恒定的wi而没有衰减因子。聚光灯的辐射强度不是恒定的,而是由聚光灯的向前方向向量决定的。
这也让我们回到积分∫地表半球Ω。由于我们事先知道所有贡献光源的单一位置,而着色一个单一的表面点,它不需要尝试和解决积分。我们可以直接取(已知)光源的数量并计算它们的总辐照度,假设每个光源只有一个影响表面辐射的光方向。这使得直接光源上的PBR相对简单,因为我们实际上只需要在贡献光源上进行循环。当我们在IBL中考虑到环境照明时,我们必须把这个积分考虑进去,因为光线可以来自任何方向。
一个PBR表面模型
让我们从编写一个片段着色器开始,它实现了前面描述的PBR模型。
Reference: