PowerVR平台与物理渲染技术(二)

作者:Tom Lewis

上一篇:《PowerVR平台基于物理渲染技术(一)——模型》

几周前我们介绍了基于物理的渲染和基于图像的PowerVR照明技术,相关内容已经发布在doc.imgtec.com网站上,该文档是对PowerVR SDK demo “基于图像光照技术”的一个指导手册,这个demo采用了带有图像光照技术(IBL)的物理渲染(PBR),如果你不太了解这些专业术语,可以查看这个博客系列的第一部分,其中介绍了PBR和IBL的基础知识以及这个demo中用到的其他资源。

今天我们将介绍一些更复杂的部分,这些资源我们必须自己来操作生成:双向反射分布功能(BRDF)查找纹理、环境映射图、辐射照度映射图以及预过滤发射映射图。

这些对于基于图像光照技术而言非常的重要,如果你还记得上次的内容IBL使用一系列的图像来近似的模拟场景中的所有光(全局光照),这些图像将来自真实世界场景中的光强度进行编码,下面让我们从第一张图像开始吧:环境映射图。

环境映射图

环境映射图存储了来自真实场景的光照能量,对于基于图像光照技术(IBL)我们使用了HDRI Haven提供的未剪切的HDR图片,这张照片展示了一个物体周围360度的景象,因此它捕捉了光照强度以及光照方向信息,这非常棒,因此我们就可以在运行时对纹理信息进行采样从而确定光照向物体的详细情况。

我们对该图像进行了一些处理,以使其为这个demo做好准备,包括将其转换为cubemap、转换为PVRTC压缩图像格式,最后保存为PVR纹理。这在“基于物理的渲染和基于图像的PowerVR照明技术”这篇文章中有更详细的介绍,我觉得大家都应该下载PVRTexTool这个开发工具(它避免了很多麻烦!)。


因此我们得到了光照射物体的更多信息,接下来我们需要了解一些物理学知识来弄清楚物体表面是如何与入射光相互作用的。

BRDF和漫反射

简单来说,双向反射分布功能(BRDF)决定了光线如何从表面反射。更具体地说,这个功能告诉你从一个(入射)方向照射到表面的光在另一个(观察)方向反射的比例。

最简单的BRDF模型是一个常数。这是漫反射(朗伯反射率)的一种情况,其中表面的反射强度在各个方向都是相同的。


对于BRDF,在上图这个情况可以简单的定义为:


其中ρ是反射率

我们在前一篇文章中提到了反照率。在PBR中,反射率被认为是物体的基础色,或者是正常白光的颜色。从表面某一点反射的漫反射光量为:


其中两个矢量是表面上点的法向量以及入射光的强度和方向

所以,计算一个特定像素在物体表面的漫反射颜色应该很简单,你只需要对环境映射图进行采样,并将各个方向的光线汇总。然而不幸的是由于我们试图模拟全局照明,环境映射图上半球上的每个像素都可以作为光源来给物体上单个像素的颜色。因为基于图像光照技术(IBL)中使用的环境贴图分辨率是2048×1024,所以要采样的纹理很多。更糟糕的是,我们必须为物体上的每个点采样整个环境映射图,这在实时情况下是不切实际的。

相反,我们预先进行计算并将结果存储在一个照度映射贴图的纹理资源中。像环境映射图一样,这张映射图被转换成cubemap——下面的图像显示了不同角度的情况。




关于这个映射图是如何预先计算的更多信息在该文档中有介绍,辐射映射图可以简单的在运行时使用特定像素的表面法线(来自法线贴图)进行采样,从而确定对该像素颜色的漫反射程度。

BRDF和镜面反射

我们已经了解了漫反射而且会带来一些不错效果,甚至模型照明。这很好,但还是有些不足,比如没有考虑到我们在前一篇文章中提到的材质纹理。为此我们需要镜面反射和更复杂的BRDF技术。我们可以假设表面是完全光滑的,就像一面镜子,所以光线只会简单地在表面正常反射而不是扩散。


然而,大多数物体都比完美的镜子粗糙。我们需要一个可以根据表面粗糙度修改镜面反射的BRDF技术。在基于图像光照技术(IBL)中,我们使用了Cook-Torrance微平面镜面模型。我们今天不会讨论这个模型的具体细节(因为已经有很多不错的在线资源),但是简而言之,这个模型只是基于一个想法,即粗糙的表面可以近似为一系列的微观细节。这些可以被认为是表面上非常小的凸起和凹痕,它们像镜子一样能够完美地反射光线到局部表面法线。每个微平面的表面法线方向会有所不同,这意味着入射光线会根据它们照射到微平面的方向而略有不同。


这会导致镜面反射稍微的扩散,形成一个波束同时光照强度会变得很多或模糊。


对于非常光滑的表面,微平面的表面法线几乎都是对齐的,所以它们都会指向同一个方向。微平面法线的分布随表面粗糙度的变化而变化。表面越粗糙,表面法线的变化越大,镜面分量的扩散也越大。对于非常粗糙的表面镜面反射类似于漫射光。微观面模型模拟了大量微观面对镜面反射的累积效应。在运行时计算Cook-Torrance模型对于移动硬件平台通常是不切实际的,幸运的是,我们可以使用一种称为“分-合近似”的方法来将大部分计算放在离线状态下处理。

不出所料,这种方法将计算分成两部分来分别进行计算,然后相乘得到最终的镜面颜色。这两部分的结果可以存储在两种纹理资源中。从而避免了一系列复杂昂贵的计算操作,因为这些纹理可以简单地在运行时进行采样。正如我们在上一篇文章中提到的 Brian Karis提出的在Unreal 4引擎中使用真实阴影(见PDF文档),Brian Karis也建议使用这种“分-合近似”的方法来进行处理。

BRDF查找表

这种“分-合近似”处理方法的第一部分既不依赖于环境也不依赖于模型,因此对于任何实现都是一样的,相关信息存储在2D查找纹理中,如下图所示:


纹理编码粗糙度和视角(θv)可以修改F0的价值。F0是反射面在垂直入射时的反射率。这是一个很花哨的术语,指的是入射光垂直照射到物体表面时反射回来时反射光的比例,可以被认为是在等效的表面反照率在扩散的情况下,可以使用粗糙度和观察角度对查找表进行采样,从而确定F0偏向和刻度的具体情况,在着色器中会将F0乘以刻度然后加上偏移角度用于后续的计算。

预过滤反射映射图

这种“分-合近似”处理方法的第二部分利用环境映射图来模拟粗糙度增加对镜面反射的影响。正如我们之前提到的,随着粗糙度的增加镜面反射会变得越来越分散。这意味着光滑的表面能够完美地反映了周围的环境,而非常粗糙的表面会产生一个模糊(几乎是漫反射)的环境映射图。那么我们如何在纹理中捕捉这种行为呢?首先,我们假设粗糙度值范围在0.0到1.0之间,并将这些值输入数学模型中,它的输出会准确地告诉我们如何对每个粗糙度的环境映射图进行模糊处理,因此只需对环境映射图进行采样并适当地进行模糊处理。

下面的图像显示了在映射图的一个方向上这个过程的处理结果,但是实际的纹理资源将是以cubemap的形式存在。



这才是明智的方法,你可能会注意到随着粗糙度的增加,上面图像的分辨率会变得越来越小。是什么图形技术对逐步缩小的纹理版本进行的处理(提示)?是的,我们对不同的mipmap级别存储了不同的粗糙度,这是一个非常好的解决方案,因为在运行时我们可以使用粗糙度值作为详细参数来对这个纹理进行采样处理。当然使用这种方法可能会有一些问题,但是这些问题在主要文档中已经讨论过了。

融会贯通

所有这些处理好的纹理资源意味着在运行时着色器要做的事情包括:

  • 通过计算镜面反射率并应用来自BRDF查找表的比例和偏差来找到一个合集
  • 对预过滤的环境映射图进行采样从而获得第二个合集
  • 将这两者相乘得到镜面颜色值
  • 对辐照度映射图进行采样从而获得来自环境的漫射光
  • 将这个值乘以反射率得到反射的漫反射颜色值
  • 乘以与金属度相关的因子,金属度决定了漫反射和镜面反射之间的平衡,完全金属表面只会产生镜面反射,而完全非金属表面只会产生漫反射。您可以在前一篇文章主要文档中了解更多关于金属度的信息。
  • 添加漫反射颜色和高光颜色得到最终的像素颜色值

正如你所看到的在这些步骤中并没有过多的计算,大部分的工作已经通过预先烘焙的纹理计算阶段完成了,这使得即使在低端硬件平台上也可以实现PBR操作。

总结

这些就是大概全部内容,本文和上一篇文章(PowerVR平台基于物理渲染技术)对基于图像光照技术所使用到的资源做了非常简短的概述,然而如果你想要了解所有相关资源的创建和处理以及着色器是如何优化PowerVR GPU的,那么你需要查看“PowerVR平台基于物理渲染和基于图像光照技术”的具体内容,同时要了解PowerVR SDK中基于图像光照的具体demo。

最后…

我们新推的文档网站不仅仅有基于物理光照相关的文档,我们还提供了很多其他方面的文章,无论你的开发水平如何都可以访问查看,包括的内容有:

所以如果你感兴趣请访问我们的新网站,我们会定期进行更新

大家可以在我们的论坛网站上留下建议,还以在推特上关注@tom devtech获取开发者技术相信新闻,或关注@powervrinsider获取关于PowerVR的最新信息。

原文链接:https://www.imgtec.com/blog/physically-based-rendering-with-powervr-part-2/

声明:本文为原创文章,转载需注明作者、出处及原文链接,否则,本网站将保留追究其法律责任的权利。

最新文章