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

COCOS

共 3697字,需浏览 8分钟

 ·

2021-04-30 21:07

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 如何实现,为定制渲染管线打好学习基础。

 

往期精彩


浏览 78
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报