前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >glTF(2.1): PBR

glTF(2.1): PBR

作者头像
Peter Lu
发布2019-03-18 11:58:10
2.1K0
发布2019-03-18 11:58:10
举报
文章被收录于专栏:LETLET

去年针对glTF的PBR材质,写过一篇文章。但重读这篇文章,觉得自己没讲到点子上。今天终于有时间,想着重新梳,重写一下。

Rasterization的不足

如上图,给你一个画布,任务是绘制这个多面体,你会怎么画呢?相信所有正常的人都是先绘制顶点,然后构成一个个的三角面,填充其中的颜色。

假如有100个物体呢,逻辑上并没有不同,一个一个的画就可以了。通常我们说的Rasterization也是这个思路。如图2,为了在屏幕上渲染物体,Rasterization有两个循环:

  • Loop objects
  • Loop pixels

Rasterization的好处是性能高,能够满足实时性的要求。它的首要问题是如何把一个3D的物体渲染到2D的平面,更擅长处理物体的几何形状,但在渲染效果上并不真实。比如一个鸟巢的模型,固然很好看,但一眼就能看出来是假的,相比一个倾斜摄影的模型,可能数据粗糙,但能看出来是真的。这里强调一下,不是说渲染的效果不好,而是不真实,是否真实的标准就是照片,Photorealism。

PBR的优势

我们之所以能看见一个物体,最大的功劳并不是物体本身,而是看不见的光。相机提供了一套系统的光学模型来捕捉光子成像,这是保证照片真实的理论基础。因此,为了更真实的渲染物体,于是便有了 ray tracing的渲染算法,也就是Physically based rendering(PBR)渲染模型。

Whitted最早的一篇论文《An Improved Illumination Model for Shaded Display》提供了第一版ray tracing algorithm,相信任何一个高中或初中生都能看懂,但想法很不简单。Whitted本来是研究原子弹的,正是这个基础,他能看到凡人看不到的光,并且还玩的很溜,在他的眼里,光就是由光子形成的射线,要想真实的渲染物体,我们要做的就是trace ray。

如上图,我们假设眼睛会放光,射线打到桌子上,然后在该点寻找光源,此处有两个光源,左侧的被苹果挡住了,所以不会有光,但右侧的光源是可见的,因此,该点是可见的,但强度略低。我们对可见范围内的每一个点都发送一条射线,然后判断是否和物体相交,如果相交,交点和光源之间是否有遮盖。这就是Ray tracing的简单原理,这个流程和Rasterization正好正好相反:

  • Loop pixels
  • Loop objects

PBR和Rasterization最大的不同,在于前者提供了一种可以量化光的算法和策略,而Rasterization只是对光的模拟,这个灯光满足这个场景,换一个场景就很难有同样的效果。

Light Equation

然而,Whitted-style ray tracing并不完美,出于性能的考虑,只考虑了一次漫反射,好比泰勒展开式,只考虑了第一阶导数,高阶导数忽略不计,所幸算法本身是客观的。现在,我们的任务就是更上一层楼,找到这个完美的光学公式。

如上图,假设在这个屋子里有一盏灯,不停的向四面发射光子,光子打在窗户上,可能折射出去了,也可能反射到墙壁,墙壁上可能也会有漫反射,可能会被吸收(热量)。图片中的任意一点主要有光源(incoming),一个是自发光,,一个是来自灯泡的direct ray或其他物体的indirect ray,可能是反射,也可能是折射的形式。而我们能看到这一点,就是它本身反射了一条指向相机的光线(outcoming),you cannot see it, but you can feel it. 于是,上面的这一段话,还有这张图片,最终不过就是如下的一个公式。

这里,L是光照的强度,G是Geometry的意思,比如是否有遮挡,光源和点x的夹角等。f是bidirectional reflectance distribution function,从ω(i)点射入的irradiance和反射到ω(0)方向的radiance之间的比例系数。请大家自行理解radiance和irradiance。

Image based light

简单回顾一下,首先,我们提到了Rasterization在渲染上的不足,PBR的优势,以及基于PBR推导出的光学公式。主要是针对理论上的阐述。但作为工程师,我不关心这是怎么来的,我只想知道是怎么用的。

何为Image based light,简单说就是有一张cube Mapping的纹理作为Skybox,每一个像素点的颜色,都算是一处光源。Rasterization无法量化光的强度,那就直接用照片预处理后的结果。光源的问题解决了,这积分符号,我看着别扭,整个人的心情都不好了,不着急,我们先举个例子。

还是屋子里有盏灯的例子,假设现在屋子漆黑一片,然后我们打开这盏灯,如果我们的相机足够快,能够比光速还快的那种快,我们就能监控到灯亮照亮整个屋子的这一刹那,灯泡随机的,均匀的向四面八方发射光子,光子打在墙上,随机的反射,折射或被吸收,请自行脑补这个瞬间。我们关灯,再开灯,继续重复这个过程,因为每一次都是随机的,所以这个过程每一次都不同,但只要有足够的积累,都会照亮这个屋子,结果是一致的。随机的不同,但在统计上趋于相同。

同样的道理,只要我们有足够的,随机的光线来模拟,最终的结果也是接近真实的,这就是Monte Carlo method。如因此我们可以推导出如下的公式,这里稍有不同的是分母中多了一个PDF(probability density function)的概念,用来做IS(Importance Sampling),作用是提高概率高的光线的权重,目的是在用尽可能少的N来获取尽可能正确的结果,reduce variance。

BRDF

上面的光学公式就剩下f这个函数的定义了,glTF里采用的是Disney提供的Microfacet(显微镜) model,简单说,就是这个材质可以模拟各种光学现象,fragment的朝向差别较大,漫反射;如果均匀一致,镜面反射;不均匀但相似,则是glossy。此处就不深入讨论这个函数了,之前那篇PBR谈到的energy conservation,roughness和fresnel等相关概念。

至于BRDF函数,有三点基本的准则。首先,f>0,能量必须为正吗,f(l,v) = f(v,l),光线可逆,最重要的是能量要守恒(曲面积分小于1)。

Environment Maps

至此,我们就可以通过采样的方式,获取每一个点对应的光照强度,然后结合材质的颜色和环境光的颜色,在fragment中计算每一个像素对应的颜色。但glTF基于《Unreal Engine's course notes on real-time PBR》进行了预处理,优化性能。

这个预处理的依据就是如上的公式。如果你的Cube Mapping的纹理是已知的,那前半部分的求和只跟roughness和cos(v)有关,而后半部分可以转化为一个kx+b的线性函数,这里,只有x未知,而k,b只跟roughness和cos(v)有关。而且roughness和cos(v)都在[0,1]之间,所以,我们可以生产一张如下的纹理,建立一张映射表,通过roughness和cos直接找到对应的k,b值,省去中间大量的采样计算。当然,纹理越大,越精确,但毕竟只是[0,1]之间的插值,所以是近似值。

总结

PBR材质是Rasterization和Ray tracing之间的一个很好的结合,严谨的数学推导以及实践中巧妙的近似。

天亮了,晚安

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-03-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 LET 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Rasterization的不足
  • PBR的优势
  • Light Equation
  • Image based light
  • BRDF
  • Environment Maps
  • 总结
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档