Cocos Creator 3.0 基于 PBR 的物理渲染详解

Cocos Creator 3.0 的出现,使 Cocos Creator 升级成为全新的 2D/3D 游戏引擎,让 2D 和 3D 游戏的开发更加便捷。目前已更新到 v3.0.1 ,戳链接了解更新详情。

通常 3D 游戏对画面效果和渲染管线的定制有很高的需求,PBR 美术工作流作为次世代主流的解决方案,今天我们来详细地分析一下基于 Cocos Creator 的 PBR 物理渲染。

01

计算机是如何显示颜色的

在讨论这个问题之前,我们先来分析一下人眼是如何看到世界的。人眼看到物体的颜色,就是看到物体的自发光与反射周围环境光的叠加。

物体自发光,是指物体自己发出来的光线,一般自然界的物体很少会自己发光,都是反射光源(太阳光)的光。

比如黑暗的房间中有一本书(没有光源),我们无法看到这本书,把灯打开后,我们能看到书了,这是因为书本反射灯光到我们的眼睛,成像到视网膜上人眼看到的物体都是反射光源的光,为什么有些物体看上去是红色,有些物体是蓝色呢?

那是因为不同物体表面的材质可以吸收一些光谱,比如某个物体,如果它吸收掉蓝色与绿色,就会反射出红色光。如果它可以吸掉收红色与蓝色,则反射出绿色的光。这些我们称为物体的“本色”(baseColor/Diffuse/albedo)。物体反射光源的光叫做直接反射,反射其他物体表面反射过来的光叫做间接反射,如图:

自然界之所以真实, 是因为由非常复杂的反射叠加而成。

3D 游戏引擎是如何处理颜色成像到摄像机的呢?其实就是模拟真实世界,并做一些取舍:

  1. 物体自发光的模拟,一般给一个自发光颜色或一个自发光贴图。
  2. 对物体本色的模拟,就是一个物体本来颜色的贴图(BaseColor 或 Diffuse 或 Albedo)
  3. 对物体反射的模拟, 只模拟反射光源的光(直接反射),不考虑间接反射。
  4. 模拟挡住光的反射(瓶子底部反射光,被挡住), 使用环境遮挡贴图 (oclussion)。

计算机显示的颜色就是经过这个过程计算以后得到的颜色值。

02

基于经验模型与 PBR 物理渲染

上述 4 个过程中,只有第 3 条涉及的反射光照是最难的,也是最影响渲染效果的,同时也是计算机图形学里面重点研究的对象。光的反射,包含两种方式,一种是镜面反射,一种是漫反射。如图:

模拟光的反射,主流游戏开发中有两种方向,一种是基于经验模型,另一种是基于物理 PBR 的。

先说基于经验模型,其实就是处理反射的时候,通过计算公式来计算光照颜色, 这个公式基于经验得来。如处理漫反射,可以采用兰伯特光照模型(公式)。处理镜面反射可以采用冯模型与布林冯模型(这块也是面试的时候经常被问的,比如定制卡通渲染风格的渲染管线经常用经验模型,而不是基于物理 PBR)。

基于 PBR 物理渲染主要是基于物理原理来模拟真实世界光的反射,双向反射分布函数(BRDF),遵守能量守恒等,这样渲染出来的物体效果接近于真实的世界,同时这些算法相对成熟,也不用我们去研究,写 Shader 的时候代入公式就可以了。

03

法线与法线贴图,高度贴图

法线是非常重要的一个数据,光的反射计算中需要用到法线,如图:

我们的 3D 模型是由三角形的面组成,面是由线组成,线是由顶点组成,每个顶点除了有坐标以外还有会有法线。如图:

我们在着色的时候,利用法线来做光的反射。如上图,三角形面上的每个点都要反射光,每个点都要法线,而模型里面只有顶点有法线,那面上任意一点的法线如何得来呢?这个我们可以采用插值来做,如下图:

黄色的法线是由两个蓝色法线插值而来,蓝色法线由绿色的顶点法线插值而来。这样面上每个点的法线就出来了。

我们再来讲高模与低模。

为了获得更好的物体的细节,我们建模的时候用的面数越多,细节表达就越好,光照就越细腻。但是面数越多,计算量越大,性能越差,如何能够在面数不增加的情况下获得更好的光照细节呢?

常用的技术就是法线贴图,美术会建一个高精度模型,原来的一个三角面内,在高模下有更多的三角形面,就有更多的顶点的法线。

把这些法线数据存到纹理贴图里面,这样低模下三角面的每个点在获取法线的时候,就不用通过插值,而是从高模的法线贴图里面获得法线数据,这样可获得更好的光照细节。

法线贴图技术也是次世代的标配。除了法线以外,为了让细节更有层次感,还有类似原理的高度贴图。下图是同一模型法线贴图和高度贴图的效果对比:

左图(普通);中间(法线贴图);右图(法线贴图+高度贴图)

04

环境遮挡贴图

什么是环境遮挡?举个例子就明白了。

如下图有一个陶瓷瓶,我们从瓶口看下去,由于瓶口小,会遮挡底部的部分反光,我们从上往下看,看不到底的感觉才更真实(左右图的瓶底对比,右边看不到底部,比左边更真实)。

下图就是这个瓶子的环境遮挡贴图:

05

基于 PBR 的美术工作流

铺垫了这么多,终于可以讲解 PBR 的美术工作流了。PBR 的算法定了,算法+数据=效果,那么剩下的就是调数据就可以了。

根据上面的铺垫,我们一起来看下 PBR 调效果的几个部分的数据:

  1. 自发光,这个控制就是一个发光的颜色或是一个自发光的贴图;
  2. 物体的本色,一个本来的颜色或一个本色的贴图(Albedo/Diffuse);
  3. 反射,包含镜面反射+漫反射控制;
  4. 环境遮挡,使用一个环境遮挡的贴图;
  5. 细节增强,使用法线贴图与高度贴图。

上面 5 个点的数据,美术的工作流程和导出除了反射以外其他基本都定下来了,接下来我们看下如何调整反射效果。

我们把反射分成了镜面反射与漫反射,PBR 有两种方式来调反射的效果,一种是基于金属度+粗糙度,另一种是反射度与光泽度。这两种方式的数据还可以相互转换,就像一个颜色可以使用 RGB 基于颜色分量来调,也可以使用 YUV 来调亮度和色彩值,调好后它们之间还可以相互转化。

金属度 + 粗糙度控制方式,就是通过物体的金属度来控制物体的反射率。如果物体表面材质单一,那么用一个数值表示就可以了,金属度越高,反射率就越强。非金属则用 0 来表示。

如果物体表面材质比较复杂(一个角色,戴了一个金属盔甲),这个时候就没有办法用一个数值来表示了,需要把表面的金属度存到一个贴图里面(金属贴图)。粗糙度控制物体表面的光滑程度,如下:

对于表面材质单一的物体,粗糙度也可以是一个数值,复杂物体表面的粗糙度也存在贴图里面。

如果粗糙度与金属度都是一个数值,可以只使用一个颜色分量(RGBA 通道)来存, 这样就可以把金属度与粗糙度合并到一个纹理里面,节约内存。

反射+光泽度控制方式,通过调整反射与物体表面的光泽度来控制,这样调整出来的效果更接近于我们真实世界的情况,控制也更加灵活。

在游戏开发中通常使用哪种模式来控制呢?我们先列举一下两种模式的优缺点(面试经常被问到)。

金属度+粗糙度工作流

优点:

  1. 更容易创作,因为各个贴图是独立分开的
  2. 纹理占用内存少(单通道,可合并)
  3. 使用更广泛

缺点:边缘的伪像更明显

反射与光泽度工作流

优点:

  1. 边缘伪影不明显
  2. 控制灵活

缺点:

  1. 灵活控制可能导致不遵守能量守恒破坏 PBR 原则

  2. RGB 贴图多,占用内存多

在游戏开发中我们大部分用金属度与粗糙度工作流,工作流确定下来后,还需实现 Shader,根据数据,把最终的效果渲染出来。这个 Shader 可以自己编写定制,也可以使用内置的 Shader。Cocos Creator 内置了金属度与粗糙度工作流的 Shader。

06

Cocos PBR Shader 参数详解

经过上面的讲解,一个 PBR 的物理渲染需要的数据如下:

  1. 自发光与自发光贴图;
  2. 物体本来的颜色,baseColor/Diffuse/Albedo 贴图
  3. 金属度、粗糙度的数值与贴图(可选),如果有贴图,一般可以合并到一个贴图里面
  4. 法线贴图,高度贴图
  5. 环境遮挡贴图

了解完这些以后,我们再来看 Cocos PBR Shader 参数,就很简单了,见下图。

法线贴图:

物体本来颜色:

金属度与粗糙度贴图:

金属度+粗糙度+环境遮挡合并的贴图:

自发光贴图:

环境遮挡贴图:

物体本来颜色:

遮挡系数调节:

金属度与粗糙度数值:

自发光颜色:

最后给出一下官方 Shader 计算的数据的说明图:

美术导图的时候,根据这个说明来制作对应的贴图,就可以配合 Cocos PBR Shader 来开发了。同时 Cocos 开源也可以学习 PBR Shader 如何实现,为定制渲染管线打好学习基础。

戳【阅读原文】前往公众号查看原文噢~

11赞

为啥不是blake老师自己发到论坛尼

mark!!!

这么干的货,评论这么少~~你们是飘了.

请问高度贴图怎么放进去

真正的干货学习了。

幫忙支援
圖解PBR光源的L、E、I、Φ到底是什麼東西?
https://gpnnotes.blogspot.com/2022/03/radiance.html

马克一下111