立即下载
EN
中文
一篇文章搞懂 PBR 渲染原理!
2024.11.01 by 不捣药的玉兔
游戏 教程

Cocs Creator 3.x 开始,PBR 就作为了标准材质,本文和大家一起学习一下 PBR的 渲染

unsetunset为什么会出现PBR?unsetunset

从古至今,每一个新东西的出现,一定伴随着它的存在价值。要么是为了提高产能,要么是为了解决某个问题,PBR 渲染也是如此。

PBR 全称 Physically Based Rendering,基于物理的渲染。

长期以来,图形学一直信奉着一句话:“如果看起来是对的,那么就是对的”,这是因为当时的技术有限。

在 PBR 出现之前,主流的是 Blinn-Phong 这类传统光照模型属于经验模型,美术人员一般是凭感觉来调整参数,制作贴图,行业内并没有一个固定的标准。

(暴雪使用传统光照模型开发的游戏《魔兽世界》)

那如果制作出来的美术效果符合 A 的审美,但不符合 B 的审美,又该如何处理呢?这就产生了第一个问题:没有统一的美术标准。

由于制作出来的贴图是固定的,当光照位置变化或者视线调整的时候,就需要重新制作贴图,这会产生第二个问题:游戏开发工作效率低下。

传统光照模型毕竟是由“人为经验”产生的,它并不符合真实的物理原则,渲染出来的效果也差强人意,因此产生了第三个问题:渲染缺乏真实感。

与此同时,硬件技术也在不断发展,人们开始不满足于当前的画面表现,开始追求更加真实的渲染,于是 PBR 渲染应运而生。

unsetunset迪士尼白皮书创造统一标准unsetunset

2012年,迪士尼发布PBR 白皮书(《Physically Based Shading at Disney》),为行业创造了一个共同的标准。

Disney PBR 提供了一组标准化的材质参数,通过调整 subsurface, metallic, specular, roughness, sheen 等参数的值,就能控制物体的材质效果。

这给行业提供了一个共同的使用框架,让美术调节起来更加方便。

然而,虽然有了固定的标准,但 Disney PBR 却不一定符合物理规则。但白皮书的发布推动了 PBR 在游戏开发、电影制作等领域的广泛应用。

发展到我们现在使用的 PBR,它模拟的就是真实世界中光线和材质之间的相互作用,以呈现出更加真实的效果。

需要注意的是,这里基于物理的渲染,依然是对现实世界的近似,只是它更加贴近我们真实的物理世界。

PBR 的主要核心有两个:

  • 基于物理的光照
  • 基于物理的材质

通过模拟光照和材质的物理特性,就可以渲染出更加逼真的图形效果。

unsetunsetPBR的两套工作流unsetunset

在谈光照和材质之前,我们先来了解 PBR 的工作流。

PBR 有两套工作流:

  • Metallic-Roughness Workflow(金属度-粗糙度工作流):

通过调整 Metallic 和 Roughness 的值来调整材质,Metallic 和 Roughness 是一个0~1之间的值。

  • Specular-Glossiness Workflow(反射率-光泽度工作流):

通过调整 Specular(高光)和 Glossiness(光泽度)的值来调整材质。Specular 用 RGBA 颜色来表示 ,Glossiness 是一个0~1之间的值。

主流游戏引擎如 Cocos 等用的 Metallic-Roughness 工作流;而有一些引擎则同时支持 Specular-Glossiness 工作流和 Metallic-Roughness 工作流。

这两种工作流都是用来定义材质表现的,区别是两者用于处理材质的参数不同。

(两种工作流)

从上图中可以看到,在 Specular-Glossiness 工作流中, Specular 是通过调整 RGBA 颜色来控制的,而在 Metallic-Roughness 中,只需要调整 0~1 的值。

相比起来,Specular-Glossiness 不够简捷方便。因此在实际中,用的更多的还是 Metallic-Roughness 这一套工作流。

unsetunsetPBR 几个理论unsetunset

PBR 遵循几个基本理论:

1. 微平面理论

在微观下,没有任何平面是完全光滑的,表面都有小凹凸。越粗糙的物体,微表面的凹凸越多,越光滑的物体,微表面的凹凸越少,这个很好理解。

2. 能量守恒

能量守恒规定,在不考虑自发光的情况下,出射光线的能量永远不能超过入射光线的能量。

换句话说,当一束光照射到物体表面后,要么产生了能量损耗,要么没有。

即:反射光的能量 ≤ 入射光的能量

这就可以解释我们平时看到的一些现象。

比如当物体表面的粗糙度比较高时,由于微表面的凹凸不平,镜面反射形成的高光区域会变大;但为了保持能量守恒,镜面反射的亮度就会下降。而粗糙度低的时候,则刚好相反。

所以我们可以看到,表面越光滑的物体,镜面反射越强烈,而表面越粗糙的物体,反射却越昏暗。

3. 菲涅尔反射

菲涅尔反射也比较好理解。

当我们看一潭水时,看离视线越近的地方,水面反射越弱,容易看到水底;而看离视线越远的地方,水面反射越强,越看不到水底。

这就是菲涅尔反射,它和光线的入射角度以及物体的材质有关。

基于物理的贴图
unset

上面提到,一个物体要渲染出真实感,离不开 PBR 材质 和 PBR 光照

而 PBR 材质,通常依赖于 PBR 贴图。

(通过PBR贴图渲染的闹钟)

PBR 贴图可以描述材质的各种属性。通过 PBR 贴图,就可以模拟物体的基础颜色、金属度、粗糙度、法线方向、环境遮蔽等。

对于不同的工作流,需要用到的 PBR 贴图也有所不同。

  • Metallic-Roughness Workflow:

BaseColor + Roughness + Metallic + Ambient Occlusion + Nomal + Height

  • Specular-Glossiness Workflow:

Diffuse + Glossiness + Specular +  Ambient Occlusion + Normal + Height

两种工作流在贴图制作中,主要是前三张图不同,如 Ambient Occlusion、Normal、Height 贴图是可以共用的。

unsetunset基于物理的光照unsetunset

在聊光照之前,首先我们要明确一个概念,无论是经验光照模型 Blinn-Phong,还是基于物理的光照 PBR,都遵循最基本的光照模型:

物体最终颜色 = Ambient(环境光)+ Diffuse(漫反射)+ Specular(高光反射)+ Emissive(自发光)

只是不同模型在处理这四个部分的计算时,采用的方法不同。

(不包含自发光的 Blinn-phong 光照模型)

PBR则使用了 渲染方程 来计算物体的最终颜色。

渲染方程是目前用来模拟光和材质的交互表现时,视觉效果最好的模型。

渲染方程的公式如下图所示。

它使用的是数学建模的方式来处理光照中的四个组成部分 —— Ambient、Diffuse、Specular 和 Emissive。

使用数学的方式可以让渲染的画面更加贴近真实的物理世界,PBR 渲染做的就是这么一件事。

渲染方程不需要我们自己计算,游戏引擎会帮我们做好一切,自动计算好 Ambient、Diffuse 和 Specualr 的光照,然后根据引擎内置的公式,分配给 Roughness, Metallic 等参数。

因此,我们在调整 PBR 材质时,可以通过调整这几个值,来调整材质的参数,从而实现想要的材质效果。

而 Emissive 被认为是物体主动发出的光,所以在游戏引擎中通常单独计算。

各个游戏引擎都提供了一种方式来独立配置和处理自发光,它不会与其他光照项混合,而是单独影响物体的外观。我们也可以在材质的属性中自行设置自发光的颜色和强度。

虽然说渲染方程不需要我们自己手动计算,但玉兔还是觉得有必要介绍它的含义。不想看数学的朋友,理解到这里就够了,可以直接划到文章的“写在最后”。

unsetunset渲染方程与BRDFunsetunset

渲染方程看上去好像有点复杂,但是不要慌,下面玉兔就带大家来理解这个方程。

我们要观察到某个物体,需要以下几个动作:

  1. 有光照:没有光照,物体看上去是黑的。
  2. 用眼睛看:有看的方向。
  3. 要看到物体:有物体的颜色表现。

整个渲染方程,做的就是一件事 —— 计算人眼在某个观察点上,看到的物体的颜色。

整个方程由3个部分组成,等号左边 1 个,等号右边 2 个。

  • 等号左边:Lo(v) ,表示到达观察点的总光照。
  • 等号右边第一项:Le(v),表示物体的自发光
  • 等号右边第二项:∫ fr(ωi, v)(Li(p,ωi)(n·ωi)) dωi,表示物体表面真正接收到的,来自各个入射方向上的入射光线。

直接解释可能不太好理解,我们再回顾一下刚刚上面提到的光照模型公式:

物体最终颜色 = Ambient(环境光)+ Diffuse(漫反射)+ Specular(高光反射)+ Emissive(自发光)

我们可以把渲染方程中的各项,和光照模型对应起来:

  • Lo(v)  -->  物体最终颜色

  • Le(v)  -->  Emissive

  • ∫ fr(ωi, v)(Li(p,ωi)(n·ωi)) dωi  -->  Ambient + Diffuse + Specular

其中,比较难理解的是积分部分 ∫ fr(ωi, v)(Li(p,ωi)(n·ωi)) dωi,我们把积分拆成三个部分,来具体理解:

  1. 内项1:fr(ωi, v)
  2. 内项2:Li(p,ωi)(n·ωi)
  3. 积分项:∫ ( 内项1 * 内项2) dωi

先来看 Li(p,ωi)(n·ωi)。

Li(p,ωi),表示来自方向ωi的入射光线的光照

由于入射光线的方向不同,物体表面接收到的能量也不同。当光线和物体法线的夹角呈 θ 角时,物体表面的受光其实是 光照 * cosθ,写成点积的形式,即:n·ωi

因此,Li(p,ωi)(n·ωi) 表示:物体表面真实接收到的,来自ωi方向上的入射光线。

而 fr(ωi, v)表示:表面反射模型

什么是表面反射模型呢?

不同的材质,对光线的反射程度不同,而表面反射模型,考虑是材质表面如何反射光线,应该反射多少。

(不同的材质对光线的反射程度不同)

fr(ωi, v) 描述的是:来自入射方向ωi的光,有多少反射到了出射方向v上。这就是大名鼎鼎的 BRDF(Bidirectional Reflectance Distribution Function)—— 双向反射分布函数。

最后在入射光所形成的半球 Ω 上,对所有可能的入射方向 ωi 进行积分求和,就可以计算出最终的出射光光照。

∫ fr(ωi, v)(Li(p,ωi)(n·ωi)) dωi 表示的就是:物体表面真正接收到的,来自各个入射方向上的入射光线。

物体接受到的来自外部的光线(∫fr(ωi, v)(Li(p,ωi)(n·ωi))dωi) + 物体的自发光(Le(v)),就可以计算出到达观察点的总光照(Lo(v))。

这就是渲染方程。

今天的目的是科普扫盲,不再给大家细讲具体的公式计算,因为还需要补充辐射度量学的知识,文字太多,不方便大家消化,玉兔把这部分放在了 知识星球 里。

不同的游戏引擎可能使用不同的 BRDF 模型,来计算 Diffuse,Specular 和 Ambient,这里不多加赘述。

渲染方程不需要我们自己计算,大家了解即可,游戏引擎通常会帮我们做好一切,自动计算光照。我们在材质中,调节 Metallic, Roughness 等值,就能实现想要的材质效果。

(Metallic = 1.0, Roughness = 0.0~1.0时的材质表现)

看到这里,你有没有感觉,数学其实也没那么难。

unsetunset写在最后unsetunset

想要更深入体会 PBR 与传统光照模型的区别,建议大家看一下我之前的视频:基础光照,可以在玉兔的 视频号:-不捣药的玉兔-,复习回顾。