PBR理论(一)

openGL高级光照部分目录 见 openGL高级光照部分目录

PBR,或者更常见的基于物理的渲染,是一组渲染技术的集合,这些渲染技术或多或少基于与物理世界更接近的基本理论。由于基于物理的渲染旨在以一种物理上合理的方式模拟光,因此与我们的原始照明算法(如Phong和Blinn-Phong)相比,它通常看起来更真实。它不仅看起来更好,因为它非常接近实际物理,我们(尤其是艺术家)可以根据物理参数编写表面材料,而不必求助于廉价的技巧和调整来使灯光看起来正确。基于物理参数编写材质的一个更大的优点是,无论照明条件如何,这些材质都会看起来正确;有些在非PBR管线中则是不正确的。

尽管如此,基于物理的渲染仍然是对现实的近似(基于物理原理),这就是为什么它不被称为物理着色,而是基于物理的着色。对于考虑物理基础的PBR照明模型,它必须满足以下3个条件(别担心,我们很快就会找到):

基于微面模型。

能量守恒。

使用基于物理的BRDF。

在接下来的PBR章节中,我们将重点关注PBR方法,它最初由迪斯尼探索,并被Epic游戏用于实时显示。他们的方法,基于金属工作流程,有很好的文档记录,在大多数流行的引擎上被广泛采用,在视觉上看起来令人惊叹。在这些章节的末尾,我们将看到如下内容:

请记住,这些章节中的主题相当高级,因此建议您对OpenGL和着色器照明有一个很好的了解。本系列需要的一些更高级的知识是:帧缓冲区、cubemaps、gamma校正、HDR和法线映射。我们还将学习一些高等数学,但我会尽我所能把概念解释得尽可能清楚。

微表面模型

所有的PBR技术都是基于微区理论的。这一理论描述了任何微观尺度的表面都可以被称为微区的微小完美反射镜所描述。根据表面粗糙度的不同,这些小镜子的排列方式会有很大不同:

表面越粗糙,每个微面沿表面的排列就越混乱。这些微小的镜像排列的效果是,当具体谈到镜面照明/反射时,入射光线更有可能沿着完全不同的方向在粗糙表面上散射,从而导致更广泛的镜面反射。相比之下,在光滑的表面上,光线更可能以大致相同的方向反射,从而使我们的反射更小、更清晰:

在微观层面上,没有表面是完全光滑的,但是由于这些微面足够小,我们无法在每像素的基础上区分它们,所以我们在给定粗糙度参数的情况下,从统计学上近似表面的微表面粗糙度。根据表面的粗糙度,我们可以计算出大致与某个向量h对齐的微空间的比率。这个向量h是位于光l和视图v向量之间的中间向量。我们在“高级照明”一章中已经讨论过中间向量,它的计算方法是l和v之和除以其长度:

微区与中间矢量对齐得越多,镜面反射就越清晰和强烈。加上在0和1之间变化的粗糙度参数,我们可以从统计学上近似微区的排列:

我们可以看到,较高的粗糙度值显示的镜面反射形状要大得多,而平滑曲面的镜面反射形状则要小得多。

能量守恒

microface近似采用了一种能量守恒的形式:传出的光能决不能超过入射的光能(不包括发射表面)。从上面的图像我们可以看到镜面反射面积增加,但其亮度也随着粗糙度的增加而降低。如果每个像素处的镜面反射强度相同(不管镜面反射形状的大小),粗糙的表面将发射更多的能量,这违反了能量守恒原理。这就是为什么我们在光滑的表面上看到的镜面反射更强烈,而在粗糙的表面上则更模糊。

为了保持能量守恒,我们需要明确区分漫反射光和镜面反射光。光线照射到表面的那一刻,它就被分成折射部分和反射部分。反射部分是直接被反射而不进入表面的光;这就是我们所知道的镜面反射光。折射部分是进入表面并被吸收的剩余光;这就是我们所知道的漫反射光。

这里有一些细微的差别,因为折射的光不会通过接触表面立即被吸收。从物理学中,我们知道光可以被建模为一束不断向前移动直到失去所有能量的光束;光束失去能量的方式是碰撞。在下面的图像中,每一个微小的粒子都会与光发生碰撞。粒子在每次碰撞时吸收部分或全部的光能量,这些能量转化为热量。

一般来说,并不是所有的能量都被吸收了,光将继续以一个(主要是)随机的方向散射,在这个方向上它与其他粒子碰撞,直到能量耗尽或再次离开表面。从表面重新出现的光线有助于表面的观察(漫反射)颜色。然而,在基于物理的渲染中,我们简化了这样的假设,即所有折射的光都会在很小的碰撞区域被吸收和散射,而忽略了在一定距离内离开曲面的散射光线的影响。有些技术考虑到了这个问题,考虑到这一点的特定明暗器技术称为次表面散射技术,它可以显著提高皮肤、大理石或蜡等材质的视觉质量,但代价是性能。

当涉及到反射和折射时,另一个微妙之处是金属表面。与非金属表面(也称为电介质)相比,金属表面对光的反应不同。金属表面遵循相同的反射和折射原理,但是所有的折射光都直接被吸收而不散射。这意味着金属表面只留下反射光或镜面反射光;金属表面不显示漫反射颜色。由于金属和电介质之间的明显区别,它们在PBR管道中的处理方式不同,我们将在下一章深入研究。

反射光和折射光之间的区别让我们看到另一个关于能量守恒的观察:它们是相互排斥的。无论何种光线,被反射都不会再被材料本身吸收。因此,作为折射光进入表面的能量就是我们考虑反射后产生的能量。

我们通过首先计算入射光能量被反射的百分比的镜面反射分数来保持这种能量守恒关系。然后根据镜面反射分数直接计算折射光的分数,如下所示:

float kS = calculateSpecularComponent(...); // reflection/specular fraction
float kD = 1.0 - kS;                        // refraction/diffuse  fraction

这样我们既知道入射光反射的量,也知道入射光折射的量,同时又遵循能量守恒原理。使用这种方法,折射/漫反射和反射/镜面反射贡献都不可能超过1.0,从而确保它们的能量总和永远不会超过入射光能量。在前面的照明章节中我们没有考虑到。

猜你喜欢

转载自blog.csdn.net/tiao_god/article/details/107326734
PBR