最近几年图形学社区对PBR的关注非常高,也许是由于Disney以及一些游戏引擎大厂的助推,也许是因为它可以被轻松集成进实时渲染的游戏引擎当中,也许是因为许多人发现现在只需要调几个参数就能实现具有非常精细细节的表面着色了。反正现在网络上随便一篇PBR的文章都可以引来大量的关注,不管你有没有讲清楚,也不管我有没有看明白(当然没有调侃谁的意思啦,它们大部分都还不错,而且这篇文章跟他们大部分讨论的内容都不一样)。

那么PBR是否已经足够完美,如果不是,那么它有哪些方面的缺点及限制,以及针对这些不足,它的下一步发展应该是什么?这些问题就是本文会聚焦的内容。对于一个知识点,解释它的基本思路和概念也许并不是最难的,最难的是你知道它的限制和不足在哪里,这部分的理解往往会比它的基本概念要困难一些,你必须更深刻地理解这种知识才能洞悉它的缺点,然后你便清楚它的下一步发展应该是什么。因此,本文其实不仅会讨论PBR的下一步发展,这里对PBR不足的一些分析也许能够让你更深刻地理解它的概念。不信?往下读一读试试!

本文主要分为三个部分,第一部分简要介绍PBR的基本概念,第二部分则分析PBR存在的问题,然后我们结合一些研究成果探讨PBR的下一步发展。

PBR基本概念

这里,我们从两个方面介绍PBR的基本概念:首先介绍它处于渲染中的什么流程或者说哪个环节,或者说它在整个渲染中具有什么样的作用;然后介绍它的基本原理和思路。在图形渲染中,如果架构抽象的比较好的,我们可以将整个渲染流程划分为四个相对比较独立的部分:

  • 光源表述(lighting):例如是点光源,面积光源或者其它形式的(例如将网格用作一个)光源,是使用辐射强度还是直接使用辐射亮度来表述光源发出的光照。
  • 光照传输(light transport):就是光在场景中是怎么传输的,例如离线渲染中的光线追踪算法,它能模拟比较真实的光子传输行为,就是说能覆盖全部光子传输路径(或空间),但是在实时渲染中使用的一些近似方法也是表述光照传输的,虽然它可能省略掉了一些不重要的路径,但是这仍然是一种光照传输算法。光栅化的整个过程也是模拟了直接光照的传输。
  • 着色模型(shading):就是光与表面相交时发生的光学交互,比如反射和折射等,所有着色相关的数据汇总成一个材质对象,每个物体表面都需要一个材质对象,以便决定光在经过物体表面时应该如何对物体表面进行着色。
  • 摄像机模型(camera):比如投影方式,对景深效果的实现方式,是否支持全景绘制,是否支持对时间采样实现运动模糊等。

其中,光源表述和摄像机模型是相对比较简单的,最耗时间的是光照传输,因为它要执行光线与场景的相交计算,复杂的着色模型也可能比较耗时,但着色模型的最重要作用是决定物体表面所能表述细节(details)的能力。

在术语上,PBR英文全称为Physically based rendering,它是指能够实现接近物理真实的整个渲染算法或过程。但是由于光照的传输算法通常是固定且内置于渲染引擎的(或者说已经具有比较稳定成熟的算法,例如离线渲染领域的路径追踪算法,或者实时渲染领域里的光栅化+其它全局光照算法),剩下对基于物理的渲染算法影响最大的其实是表面的着色(材质)模型。因此,人们通常在讨论或描述PBR时,更多的是指其使用的着色模型。基于物理的着色模型更准确的称呼应该是Physically based shading,但是通常并没有PBS的称谓。

那么物理材质是指什么,“材质”其实就是光在与某个特定表面交互时需要的所有光学交互计算的数据,例如法线,纹理,BRDF等,也就是说,材质定义了最终表面接受光照后的视觉结果。对于物体表面视觉特征的定义,根据尺寸粒度可以划分为三级:

  • 基于网格顶点的表述,这种就是只对网格顶点的着色进行描述,然后中间的表面像素则通过插值来计算。
  • 基于像素的纹理贴图,这就是最常见的各种贴图,它们能表述像素级别的视觉特征。
  • 基于微观粒子的微面元表述,这就是我们这里所关心的物理着色。

上述前两种视觉表述是比较常见的,也是早期使用的一些技术。然而这两种表述远远不能描述物体表面的视觉特征,这是因为一个像素的尺寸远远大于物体表面上微观粒子的尺寸,如下图所示,图像空间中间的黄色方块表示一个像素,下面灰色褶皱部分则是该像素对应的实际微观结构,而光实际上是作用在这些微观结构上的,所以基于像素的着色模型(如直接贴图)反应不出真实物体表面的微观细节,所以这些技术都可以称为不是基于物理的材质。

物体表面微观结构的尺度远远小于一个像素的尺度

那么,要怎么表述这么微小的微观结构的光学交互行为呢?显然我们不可能像纹理那样对每个微观粒子使用一个纹素进行表述,那样我们的计算机内存将远远不够存储这种级别的纹理,所以人们提出了Microfacet BRDF理论,它使用一个法线概率分布函数,来模拟微观粒子的法线分布特征,这样就能够表述物体表面的微观特征,从而接近物理真实,所以称为基于物理的材质表述。

Microfacet BRDF表现出来的视觉特征是什么呢?那就是对于每个固定方向的入射光,我们可以有多个对该入射光的观察方向;或者反过来说,对于某个固定的观察方向,我们可以从一个像素观察到来自多个方向的入射光照。如果没有Microfacet BRDF,一个像素只被当做一个平面,对于固定的观察/入射方向,它只对应一个入射/观察方向。在Microfacet BRDF中,我们所能观察入射方向的方向范围,被参数化为一个粗糙度参数,如下图所示。这种着色模型使得我们能够表现比像素更小尺寸的表面细节。

反射光的范围大小取决于物体表面的粗糙度,物体表面越粗糙,它越能接收更大范围的光照

在渲染中,我们有许多模型来近似真实物体的微观法线分布,例如Normalized Blinn-Phong,Beckmann,GGX模型等等,这些模型具有不同的近似度和计算复杂度。由于这些模型都是对真实物理特征的近似,因此它们很可能不会遵循真实的物理分布,因此正性(positivity),互换性(reciprocity)以及能量守恒(energy conservation)被用来衡量一个BRDF模型是否是基于物理真实的,注意它们不是BRDF的属性哦,而是对BRDF是否满足物理真实的要求,因为你根据一些测量数据提出一个近似的BRDF模型很可能不是物理真实的,这些条件只是用来检验BRDF模型的物理真实性。

© DreamWorks Animation 2017

顶点和像素级别的纹理可以存储在一张纹理图片中,这种基于物理的材质表述怎么存储呢?前面已经说过这个级别的表述是无法精确定义和存储的,所以我们将这个概率密度分布直接写进shader中,因为shader也是材质的一部分。

这也是为什么近几年实时渲染的游戏品质有了很大提升,实时渲染与离线渲染的最大不同在于光照的传输过程,实时渲染省略或者近似了很多路径,但是在光与表面的交互上,它只涉及一个公式的计算,并不会对性能造成太大影响,所以可以很容易地集成进来。不过实践中,实时渲染使用的概率密度分布函数要比影视中使用的计算量要简单一些,这只是在质量上稍有差异,但是不影响它表述微观粒子视觉特征的能力。

PBR的限制

有了上述Microfacet BRDF理论,物理着色的世界是否就完美了呢?换句话说你是否就能够通过几个神奇的参数表述任意细节的物理材质呢?

如果你仔细观察通过上述那些Microfacet BRDF模型渲染出的图像,你会发现虽然它们能够表述粗糙度,但是它们都太过平滑或者说模糊,例如下边右边的图。

右图:传统的Microfacet BRDF模型太过于平滑(图片来自【10】)
 

传统的Microfacet BRDF模型渲染不出上图中左图那种划痕的效果。这是为什么,这是因为出于计算效率,传统的Microfacet BRDF模型都是对真实BRDF分布的一个粗略近似,这些近似往往都非常平滑,如下图所示,右图表示一个比较真实的BRDF分布,而左图表示一个传统的Microfacet BRDF模型,左图可以看做是对右图的一个(非常)平滑的结果,这是因为我们需要计算效率足够高的着色计算,复杂的BRDF分布会大大增加采样的计算时间。这种平滑的结果使得传统的Microfacet BRDF模型只能渲染出一定距离范围之外的表面着色,你可以理解为距离越远着色越模糊,当然这里实际上不是指实际物体离摄像机的距离,而是说这种模型永远只能渲染出类似于超出这个距离的表面粗糙度,即使拉近摄像机的距离,它们看起来仍然是很平滑的,因为它们所使用的BRDF已经被严重的平滑了,也就是上面右图中的效果,那些更细微的细节被下面左图这样类似的BRDF分布给平滑掉了。

左:传统的Microfacet BRDF模型:右:真实的BRDF分布(图片来自【5】)
 

所以这里可以总结出传统的Microfacet BRDF模型具有哪些不足。首先,传统的Microfacet BRDF太过平滑,不能表现小于一个像素的几何级的细节,这些细节的尺寸介于像素和微观粒子之间,如文章封面左图中的划痕,后面会分析更多例子。

其次,物理材质的着色计算“表述”在像素着色器(shader)中,而物体表面的宏观结构往往通过网格顶点或者像素级别的法线贴图来表述,这两种几何表述是分离的,并且随着表面离摄像机距离的改变,一个像素的尺寸和一个纹理中的纹素的尺寸之间的相对关系发生着变化,当物体表面离摄像机足够远时,实际上物体的宏观法线贴图或几何结构其实变成了该像素的“微观结构”,然而,通常法线贴图或几何结构与BRDF都是独立的,例如法线贴图首先被过滤到最模糊的级别,然后用于Microfacet BRDF的计算,这就使得artifacts非常严重,例如下图中三种不同的距离下,近处的水波细节在远距离下产生较大的artifacts。

或者如下图中,光盘上的划痕,在远距离下直接被模糊掉了。

在远距离下,由于几何级的法线数据首先被过滤,然后作用与BRDF,因此这种细节丢失,物体表面的细节随着距离摄像机的距离改变而改变(图片来自【13】)
 

PBR的下一步发展在哪里?

上述的描述其实可以总结为两个方面:

  • 传统Microfacet BRDF对微观结构的表述精确度不足
  • 传统的Microfacet BRDF与宏观的(如法线)贴图或几何结构不相容,或者说不能相互协调工作

这是两个独立的问题,例如单提高BRDF的精确度不能解决第二个问题,因为对于远处的物体,我们需要将几何级的结构视作像素的微观结构(例如微面元),否则我们需要很高的采样才能消除artifact,而这对于远处的物体较高的采样显然是比较浪费的;其次,让宏观的几何结构与BRDF相协调对于近处物体的细节表述是没有什么意义的。当然如下所述,如果高分辨率的法线贴图被视作几何结构,那么第二个问题的确能改善第一个问题。

首先,对于微观结构的表述,出于计算效率的考虑,目前我们还不可能使用非常复杂的Microfacet BRDF近似模型,因为比较精确的模型可能需要上百倍的计算时间。当前的研究主要是集中于使用高分辨率的法线贴图(或者其它一些特殊的高分辨率几何结构)来表述这种介于像素和微观粒子之间的几何结构,然后将每个像素对应的这种几何级的数据与BRDF相融合,得出一种能够适应这些几何结构的Microfacet BRDF模型。这种模型能够表述更微观的几何细节,例如下图所示,光盘和地板上那种细节在传统的BRDF上是表现不出来的,因为它们会完全被平滑掉。

Microfacet BRDF与高分辨率贴图结合产生更多细节(图片来自【10】)
 

通过结合传统的Microfacet BRDF模型与贴图,两种着色技术被结合起来,使得我们不必使用更复杂的Microfacet BRDF模型就可以表述更精细的微观结构。

除了将高分辨率的贴图融入进Microfacet BRDF模型中,对于远处的表面,我们还需要能够直接将宏观的表面几何结构融入进Microfacet BRDF模型中,即这些宏观几何结构成为一个像素中的微面元本身。

在传统的Microfacet BRDF模型中,针对每一个像素,我们首先根据法线贴图或其它方式得到一个当前像素的法线,然后代入进Microfacet BRDF模型中计算出射光照。然而我们说过,Microfacet BRDF模型发生于像素尺寸,而法线采样发生于纹理尺寸,这两个尺寸通常是不对等且随着表面到摄像机的距离变化而变化的,例如对于比较近的表面,假如像素与纹理尺寸是一比一的,那么这个法线采样会比较准确,它可以直接被用于Microfacet BRDF模型中进行计算;然后对于远处的表面,一个像素尺寸可能等于多个纹素尺寸,这时对法线贴图的直接采用就会导致比较大的方差,我们需要花很多的样本才能把这些方差平均下来,因此传统的做法就是首先对法线贴图进行过滤,也就是从一个Mipmap中得到对应距离的法线值。这种做法虽然使用平滑的偏差带来了方差的减小,但是它又平滑了这种几何级的细节,所以我们仍然需要非常高的采样率来填补这些细节。

所以,如果我们能够将几何级的宏观结构也融入到Microfacet BRDF中,对于远距离的表面,宏观的几何结构直接集成于Microfacet BRDF中,就能够使用比较少的样本来得到远处表面的细节,例如下图中,使用传统的Microfacet BRDF,左图使用100个样本可以得到比较精细的细节,但是中图使用一个样本则比较模糊,因为较远的地方法线贴图的采样被过滤了,右图将几何结构融入Microfacet BRDF中,可以使用较少的样本得到远处的几何细节。

左图:传统的Microfacet BRDF,使用每像素100个样本;中图:传统的Microfacet BRDF,每像素一个样本;右图:将几何结构融入Microfacet BRDF中,每像素一个样本(图片来自【4】)
 
能够将几何级的贴图数据和Microfacet BRDF融合,许多的表面都可以得到更精细的表述。
图片来自【13】
 

当然,由于bump map或normal map都是对法线的fake,它们并不改变物体表面的几何结构,仅仅是直接给着色器传递一个假的的法线值,这个法线值可能导致物体表面的表面几何分布并不是一致的(consistent),因此这就破话了Microfacet BRDF的对称性和能量守恒。例如下图所示,由于表面的真实几何结构没有发生变化,然而着色使用了一个假的法线,因此使得一部分的方向被丢失,例如对于下图而言,左边半球与几何平面交叉的部分(红色箭头所示)和右图半球面下方的方向(红色箭头所示)都是不能被采样的,这造成了光照的泄露和丢失。

图片来自【11】

因此,开发更高效的Microfacet BRDF模型,使其能够与在bump/normal map的配合下能够呈现更真实的着色,也是Microfacet BRDF发展的话题,以下是Unity labs的一种解决方案。

图片来自【11】
 

总结

出于性能考虑,当前传统的Microfacet BRDF都采用比较模糊近似模型,这使得介于像素和微观粒子之间的微观结构被忽略。而实践上我们也不可能采用表述更精确的Microfacet BRDF模型,因为这往往需要较大的数据存储(例如一些基于数据驱动的Microfacet BRDF模型)或者较大的计算时间,不过实际上可能人眼也不可能分辨太过微观的细节,因此结合传统的(bump/Displacement/normal map等)贴图技术,通过高分辨率的贴图来展现比像素更微观的细节,并让这些贴图所表述的相对宏观的几何结构融入到Microfacet BRDF模型中,便成为比较简洁而有效的方法。此外,除了贴图级别的宏观几何结构,远处更大尺寸的如顶点级别的几何结构也是需要与Microfacet BRDF模型进行融合的。

对于理解Microfacet BRDF模型,表面表述的尺寸是一个非常关键的因素,仔细去理解每种尺寸下着色模型的选择,以及它们之间怎么联合起来对总的表面进行着色,这是让你透彻理解着色的关键。

参考引用或相关补充资源:
[1] 2010 LEAN Mapping
[2] 2013 Linear Efficient Antialiased Displacement and Re ectance Mapping
[3] 2014 Discrete Stochastic Microfacet Models
[4] 2014 Geometry into Shading
[5] 2014 Rendering Glints on High-resolution Normal-mapped Specular Surfaces
[6] 2014 Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs
[7] 2015 Multiple-Scattering Microfacet BSDFs with the Smith Model
[8] 2015 Skin Microstructure Deformation with Displacement Map Convolution
[9] 2016 Multi-Scale Rendering of Scratched Materials using a Structured SV-BRDF Model
[10] 2016 Position-Normal Distributions for Efficient Rendering of Specular Microstructure
[11] 2017 Microfacet-based Normal Mapping for Robust Monte Carlo Path Tracing
[12] 2017 Pixar's Foundation for Materials
[13] Racing for Realism

More DETAILS! PBR的下一个发展在哪里?的更多相关文章

  1. Go将统治下一个10年?Go语言发展现状分析

    “本文是国内Go语言大中华区首席布道师——许式伟,在QCon2015上海站上的分享.他预测Go语言10年内一定会超过C和java,并且统治这一个10年. Go语言语法及标准库变化 Go从1.0版本到现 ...

  2. Cocos发展Visual Studio下一个libcurl图书馆开发环境的搭建

    我们解释win32在Visual Studio下一个libcurl图书馆开发环境的搭建.Cocos2d-x发动机实际上与Win32在访问libcurl库.Cocos2d-x 3.x在libcurl库文 ...

  3. 【网络】高性能网络编程--下一个10年,是时候考虑C10M并发问题了

    转载:http://www.52im.net/thread-568-1-1.html 1.前言 在本系列文章的上篇中我们回顾了过云的10年里,高性能网络编程领域著名的C10K问题及其成功的解决方案(上 ...

  4. NASA的下一个十年(译)

    原文 MICHAEL ROSTON (New York Times) 从左起:木卫二:土卫六:经过火星的水手谷星的合成图:金星的拼接图 大多数人已经从人类第一次近距离看到冥王星的兴奋中冷静下来.下一个 ...

  5. VR就是下一个浪潮_2016 (GMGC) 全球移动游戏大会观后感

    "VR就是下一个浪潮"  --2016 (GMGC) 全球移动游戏大会观后感   早在2014年参会Unity举办的一年一度的金立方盛典大会,就初次体验了VR头盔设备,于是印象深刻 ...

  6. 引爆公式让你的APP游戏成为下一个“爆款”

    在2014年的移动互联网领域,“魔漫相机”是一款值得关注的产品.虽然没有腾讯.百度或阿里巴巴等大资源的支持,但是这款应用一上线就在中国市场发展迅猛,日下载量超过80万次,最高一日达300万次.类似的成 ...

  7. Linux下一个简单的日志系统的设计及其C代码实现

    1.概述 在大型软件系统中,为了监测软件运行状况及排查软件故障,一般都会要求软件程序在运行的过程中产生日志文件.在日志文件中存放程序流程中的一些重要信息, 包括:变量名称及其值.消息结构定义.函数返回 ...

  8. Memcahce(MC)系列(两)Linux下一个Memcache安装

    Linux下一个memcache安装 memcache是高性能.分布式的内存对象缓存系统,用于在动态应用中降低数据库负载.提升訪问速度.眼下用memcache解决互联网上的大用户读取是很流行的一种使用 ...

  9. 分析RAC下一个SPFILE整合的三篇文章的文件更改

    大约RAC下一个spfile分析_整理在_2014.4.17 说明:文章来源于网络 第一篇:RAC下SPFILE文件改动 在RAC下spfile位置的改动与单节点环境不全然一致,有些地方须要特别注意, ...

随机推荐

  1. PHP--最常用--必背函数总结!php学习者收藏必备!

    一.PHP系统函数 函数 功能 用法 var_dump() 打印变量结构信息,包括类型和值.数组将递归展开值 var_dump ( $arg1...); echo():是语法结构 输出一个或者多个字符 ...

  2. Java微信公众平台开发_07_JSSDK图片上传

    一.本节要点 1.获取jsapi_ticket //2.获取getJsapiTicket的接口地址,有效期为7200秒 private static final String GET_JSAPITIC ...

  3. codefoces384A-Mafia心得

    题目描述:One day n friends gathered together to play "Mafia". During each round of the game so ...

  4. 数组去重+indexOf()应用

    说起数组去重大家都不陌生,去重也有好多种方法,这里介绍很好理解的两种. 第一种 首先说一下第一种的逻辑,就是先拿第一个去跟第二个比,再跟第三个比,再跟第四个比--只要发现有相等的,可以用splice( ...

  5. jenkins+docker 持续构建非docker in docker jenkins docker svn maven

    工欲善其事必先利其器,为了解脱程序员的,我们程序员本身发明了很多好用的工具,通过各种工具的组合来达到我们想要的结果 本文采用jenkins docker svn maven作为相关工具,项目sprin ...

  6. 怎样在一个HTML中嵌入另一个HTML页面(iframe标签用法)

    iframe 怎么 在一个网页中嵌入另一个网页呢,我们可以用html中的iframe标签搞定. iframe支持所有浏览器.下面来看语法: <iframe src="规定在 ifram ...

  7. Liunx初学指令

    今天又讲了一下Liunx操作系统,这个感觉比较简单一点了,多积极练练就好了,今天的课堂笔记重点如下: 1. 查看当做操作目录位置 > pwd 2. 查看(当前)目录里边的文件内容 > ls ...

  8. netty(三) 组件介绍

    netty各组件说明:channel ----- SocketEventLoop -------控制流,多线程处理,并发channelFuture ------- 异步通知 channel:主要是实现 ...

  9. Loadrunner web_url函数学习(转贴)

    http://blog.csdn.net/dfbrt56/article/details/3291461 ----------------------------------------------- ...

  10. websocket做手机页面聊天与PC页面聊天一对一的即时通讯

    当时要写这个需求的时候,很头痛,手机端页面的客服功能,相当于QQ这样一个一对一聊天室功能了,瞬间蒙蔽的我也不知道用什么去写这个东西,一开始用ajax,定时器去写,写着写着发现这尼玛不在同一个页面怎么做 ...