glTF(二):PBR

glTF

glTF是一个优秀的三维数据规范,其中有很多细节都值得我们学习,按照我的理解,可以分为三大块:

  • Accessor数据访问机制 一套访问二进制数据的规范,将逻辑层和数据层隔离 同传输和读取以及存储灵活性上都有上佳表现
  • 针对OpenGL渲染进行的数据结构优化 封装:Mesh与Primitive中的Vertex Buffer, Index Buffer,Vertex Array,还有Texture与State Management,在灵活和易用上都有不错的设计 压缩: 针对3D Geometry的Draco压缩#6191
  • Scene& Node 节点间的依赖和位置关系 实例化设计

glTF2.0

相比1.0,glTF2.0的改变可以用“一增一删修修补补”来概括,主要有:

  • 新增PBR(Physically-Based Rendering )材质 本文重点,稍后继续
  • 删除Technique和Shader 个人理解:剥离渲染部分,glTF规范更专注数据层面 更好的融入Web体系
  • 其他 明确两个非重点:不支持流媒体,结构以JSON格式呈现,原始数据在可读性上并不友好 兼容性:2.*之间版本向下兼容,但不保证2.0的数据在1.0的Parser的兼容性(Cesium目前解析1.0的代码时,会自动升级为2.0) 顶点索引支持UNSIGNED_INT 字节对齐,Accessors Bounds,实例化设计(MorphTarget) 3D Geometry Compression: Draco

Light and material interaction

下面,正式进入本文的重点。

计算模型的反射是渲染的核心,这牵扯到物体光照和缓冲期纹理的像素颜色。当前的反射模型分为两类,实用型和理论型。比如我们常见的ADS光照模型属于前者,计算效率高,但在(物理)理论角度的正确性不足,实际上,这类模型的目的是在物体表面提供亮光,让物体具备立体效果,这也是为什么,我们看到游戏场景绚丽,但缺少真实感,因为违背大脑对自然规律的认知(比如能量守恒)。理论型模型则牵扯到大量的实验数据和计算量,但更有真实感,比如Disney的动画,就具备高度的真实性,很大的因素就是他们采用物理渲染引擎和对应的材质。PBR技术在使用上不难,在Web上,Cesium,Three等都已经支持,但要理解,里面的知识点好多。

首先,光落在你脸上有千百种效果,但结果只有两个:折射和反射。初中物理告诉我们他们符合该公式:

。N表示不同介质见的折射率,根据能量守恒定律,一束光的能量等于反射光和折射光总和。

如下是一个完整的示意图:一部分能量转化为反射光,绿色部分(specular);一部分能量折射穿透表面,要么被吸收(转化为热能),要么被溅射出来,红色部分(diffuse)。当然,完整的光照模型还需要考虑另外两种独立的光源:环境光(ambient)和自发光(emissive)。

传统的光照模型遵守该自然规律,但有两个问题,第一,反射光和折射光的计算各自独立,没有考虑能量守恒(energy conservation);第二,偏重考虑光和物体表面的交互(光线),但材质属性上的考虑不足,如下图roughness(1),subsurface scattering(2)以及fresnel(3),在传统模型中都没有针对性的考虑。

1. Energy conservation:反射越强(白点),漫反射就约弱(黑色区域),能量和不变

2.Roughness:光的反射计算时,我们通过normal map来反映该物体的orientation,这由物体的形状来决定。但在真实世界,物体表面粗糙程度各不相同,而该属性无法通过normal来体现

3. subsurface scattering:半透明,透明,厚度等材质对折射的影响

4. Fresnel:边缘的反射率会变大

举个例子,杨过学打狗棒法,洪七公教了招式,这算是传统光照模型的程度,有模有样,但黄蓉传授心法后,杨过才能心领神会,运用自如。这个心法,就是如下的数学模型:

  • L(P,V)是经过P点反射(diffuse或specular)后进入视点V的光
  • L(P,-V)是从-V方向射入P点的光
  • R是对应的BRDF函数,会考虑上述各种物理现象

不难理解,对各个方向的光源积分,就可以得到对应点P的结果。我们先侧重理解,文末会给出BRDF的专门介绍。

上图是针对100种材质,采用5种常见的材质的效果对比,可见Cook-Torrance(BRDF的一种)在实验中相对有较好的表现,而glTF2.0就是采用 Cook-Torrance Model。

PBR

首先,如果模型采用PBR材质,最少需要两个两张纹理:albedo和metalRoughness。Albedo对应该模型的纹理,就是我们常用的的diffuseColor。metalRoughness对应rgba的g和b两位,范围是[0,1],对应模型的g(roughness)和b(metallic)。Roughness之前介绍过,这个metallic属性,用来描述该模型对应P点在绝缘体和金属之间的一个度,金属的反射率相对较高,该系数用来调整diffuse和specular的能量分配。如下是diffuseColor,metallic和roughness对应模型的效果。原图效果,后两张算是灰度图,值越大越白,越偏金属(图2),也越粗糙(图3)。

这里,glTF的采用的是Disney给出的BRDF公式:

,diffuse采用的是Lambert模型:

,C是漫反射光的颜色Color,这里认为该点微观上是一个平面,漫反射以一个半圆180°均匀反射,所以除以π,当然还有其他的模型(Oren-Nayar)。如上的模型,对应的diffuse效果如下,在点光源下,对应metallic纹理,塑料材质会有较多的漫反射,而金属材质下,大部分能量则转化为镜面反射:

Specular就有点复杂D,F,G是三个函数,应用角度看,我们并不需要理解它们,直接套公式即可,感兴趣的同学仔细看一下下面这张图以及右侧对应的具体参数。

套用该公式,我们获取的specular效果如下,右侧是diffuse+specular的效果:

接下来,是对环境光的考虑,所谓环境光,就是来自四面八方的光,做一遍如上的计算,然后求和,就是前面对应的BRDF的积分公式,可想而知计算量很大。这里数学可证,能够将该积分近似拆分为两部分:Environment Map和BRDF lookup table。前者根据不同的Roughness,计算对应光源的平均像素值。后者根据Roughness和视角计算出对应颜色的调整系数(scale和bias)。虽然两部分的计算量比较大,但都可以预处理,通常Cube Texture都是固定的,我们可以预先获取对应的Environment Map,根据Roughness构建MipMap;后者只跟Roughness和视角V的cos有关,一旦确定了BRDF模型,计算公式是固定的,也可以预先生成U(Roughness) V(cosV)对应的 Texture:

Cook-TorranceModel对应的LUT

这样,我们可以获取环境光的计算公式如下:

finalColor += PrefilteredColor * ( SpecularColor* EnvBRDF.x + EnvBRDF.y );对应的效果如下,在这个基础上,我们在添加对应的Ambient Occlusion Texture,Emissive Texture,就是右侧效果。

上面是PBR渲染的完整思路,整个过程其实和传统的ADS并没有差别,只是每一部分采用不同的计算公式,考虑更全面,计算量也随之复杂,因此,为了保证real time的效率,通过预处理的方式来简化计算量。

BRDF

BRDF是Bidirectional reflectance distribution function的缩写,下面介绍一下该数学模型对应的F,G,D函数,以及积分求和,而这,也是PBR中最核心,但也最难理解的部分。

首先,光是可逆的,上面也提到,要遵守能量守恒,因此要满足两个条件:

在我阅读的论文里,最常见的BRDF模型就是Cook-Torrance specular BRDF和Lambert diffuse BRDF:

(F)resnel reflectance

既然是Fresnel,不难理解,该函数主要是用来计算不同介质之间光的折射,简化后的Schlick公式可以取得近似值,公式如下,在中心点时l和h为零度角,cos=1.为F(0),为该材质的base reflectivity,在45°时,还基本不变,但接近90°时,则反射率则迅速提升到1,符合之前Fresnel的变化曲线

Normal (d)istribution term

该函数用来描述材质的roughness,在能量守恒下,控制物体在反射与折射间的分配,glTF中采用的是Trowbridge-Reitz GGX公式,其中α是唯一参数,而h可以通过粗糙度α和法线n求解:

(G)eometric term

表示从L光源能够到达V视角的概率,这里glTF采用的是GGX,而Cesium则是Schlick模型:

最后考虑到能量守恒,需要在diffuse和specular之间添加参数,控制两者的比例,这里也有多种方式,比如前面提到的Disney给出的公式(glTF和Cesium中都采用该公式),也有论文里提到的diffuse Fresnel term:

Importance sampling

上面给出了一个点光源的计算,对于环境光,就有一个求和的过程,这里,对该积分做了如下两步近似求解:

正是因为如上的近似推导,证明我们可以通过EnvironmentMap和BRDF lookup table两张纹理,对Sum求和的过程预处理,减少real time下的计算量。具体的代码在论文中,不妨阅读理解一下,要展开说细节太多了,我仅把个人觉得有意思的几点放到others中,都可以在论文中找到更详细的解释。

Others

Sampling

Ray Tracing时,需要对光源进行采样,其大概的思路是通过采样算法,创建一个均匀分布的二维点集合,然后映射到对应的光源,但不同材质下分布并不均匀,因此还需要通过PDF(probability density function)给出其对应的权重。这个过程下,主要有三个知识点:Hammersley,ImportanceSampleGGX,pdf。

Gamma correction

同样一张图片,为何不同显示器下效果会有差别,这下终于找到原因了。也算是历史遗留问题,算是CRT显示器的产物。

因为BRDF的过程需要对原始Color进行计算,需要将纹理颜色解析成真实的颜色,计算后再编码成Gamma对应的颜色。

Rational Approximation

类似泰勒公式,但泰勒公式仅对X(0)原点附近的精度有保证,同时,我们对应的F,D,G函数也并不容易求出N阶导数,以及能够创建满足先决条件的泰勒展开式,比如D正态分布,要求展开式积分为1。

因此,在论文中给出了Rational Approximation的算法,比如真实的Fresnel函数如下,通过该算法才得以简化,实用,就问你服不服。

原文发布于微信公众号 - LET(LET0-0)

原文发表时间:2018-03-31

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏大数据挖掘DT机器学习

用R进行网站评论文本挖掘聚类

对于非结构化的网站中文评论信息,r的中文词频包可能是用来挖掘其潜在信息的好工具,要分析文本内容,最常见的分析方法是提取文本中的词语,并统计频率。频率能反映词语在...

2656
来自专栏北京马哥教育

实战 | 用 Python 选股票,据说可以多挣个20%

本文将使用Python来可视化股票数据,比如绘制K线图,并且探究各项指标的含义和关系,最后使用移动平均线方法初探投资策略。 数据导入 这里将股票数据存储在sto...

4276
来自专栏智能算法

机器人算法专题介绍

算法 算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制。也就是说,能够对一定规...

3586
来自专栏数据派THU

独家 | 教你实现数据集多维可视化(附代码)

翻译:张媛 校对:卢苗苗 用代码将你的数据集进行多维可视化! 介绍 描述性分析是与数据科学或特定研究相关的任何分析生命周期中的核心组成部分之一。数据聚合,汇总...

8909
来自专栏数据魔术师

干货|迭代局部搜索算法(Iterated local search)探幽(附C++代码及注释)

4305
来自专栏机器之心

资源 | Richard Sutton经典教材《强化学习》第二版公布(附PDF下载)

2598
来自专栏量化投资与机器学习

机器学习的前期入门汇总

机器学习机器学习是近20多年兴起的一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。机器学习理论主要是设计和分析一些让计算机可以...

2185
来自专栏PPV课数据科学社区

【学习】趣味数据挖掘——借水浒传故事,释决策树思路

决策树(又称判定树,DecisionTree)是硕、博士生数据挖掘课程要点和难点,教学实践表明,这一章需要数学基础知识多,难得有趣。明知是难点,偏向难点行,再难...

3424
来自专栏大数据文摘

拓扑学——探寻大数据的内在模式

1925
来自专栏大数据文摘

快讯 | Facebook开源语音识别工具包wav2letter

2106

扫码关注云+社区