前面两篇文章我们介绍了PBS实现的数学和理论基础,和standard shader的原理和实现,还有一些其他的渲染相关的unity技术。其中有些概念和技术没有讲的很详细,现在对这些重要的概念进行更深入地解释。
一、什么是全局光照
全局光照对得到真实的渲染结果有着举足轻重的作用,全局光照指的就是模拟光线是如何在场景中传播的。他不仅会考虑那些直接光照的结果,还会计算光线被不同的物体表面反射产生的间接光照。在使用基于物理的着色技术时,当渲染表面上一点时,我们需要计算该点的半球范围内所有会反射到观察方向的入射光线的光照结果,这些入射光线中就包含了直接光照和间接光照。
通常来讲这些间接光照的计算是非常耗时间的,通常不会用在实时渲染中。一个传统的方法是使用光线追踪,来追踪场景中每一条重要的光线的传播路径。使用光线追踪能得到非常出色的画面效果,因此被大量应用在电影制作中。但是这种方法往往需要大量的时间才能得到一帧,并不能满足实时的要求。
Unity采用了Enlighten解决方案来让全局光照能够在各种平台有不错的性能表现。事实上,Enlighten也已经被集成在虚幻引擎中,它已经在很多3A大作中展现了自身强大的渲染能力。总体来讲,Unity使用了实时+预计算的方法来模拟场景中的光照。其中,实时光照用于计算那些直接光源对场景的影响,当物体移动时,光照也会随之发生变化。但正如我们之前所说,实时光照无法模拟光线被多次反射的效果。为了得到更加真实的渲染效果,unity引入了预计算光照的方法,使得全局光照甚至在一些高端的移动设备上也可以达到实时的要求。
预计算包含了我们常见的光照烘焙,也就是指我们把光源对场景中静态物体的光照效果提前烘焙到一张光照纹理中,然后把这张光照纹理直接贴在这些物体的表面,来得到光照效果。这些纹理不仅存储了这些光照效果,还包含了那些由物体反射得到的间接光照。但是这些光照纹理无法在游戏运行时不断更新,也就是说他们是静态的。不过这种方法的确为移动平台的复杂光照模拟提供了一个有效途径。
由于静态的光照烘焙无法在光照条件改变时更新物体的光照效果。因此unity使用了预计算实时全局光照(Precomputed Realtime GI)为我们提供了一个解决途径,来动态地为场景实时更新复杂的光照结果。使用这种技术我们可以让场景中的物体包含丰富的全局光照效果,例如多次反射等,并且这些计算都是实时的,可以随着光源和物体的移动而发生变化,这是使用之前的实时光照或烘焙光照所无法实现的。
这些是如何实现的?它们实际上都利用了一个事实——一旦物体和光源的位置被固定了,这些物体对光线的反弹路径以及漫反射光照(我们假设漫反射光照在各个方向的分布是相同的)也是固定的,也就是说和摄像机无关。因此我们使用预计算方法来把这些物体之间的关系提前计算出来,而在实时运行时,只要光源的位置(光源的颜色可以实时变化的)不变,即便改变了光源的颜色和强度、物体材质属性(漫反射和自发光相关属性),这些信息就一直有效,不需要实时更新。在预计算阶段中,Enlighten会在由所有静态物体组成的场景上,进行简化的“光线追踪”过程,这个过程中Enlighten会自动把场景分割成很多个子系统,他并不是为了得到精确的光照效果,而是为了得到场景中物体之间的关系。需要注意这些预计算都是在静态物体上进行的,因此为了利用上述预计算方法,至少要把一个物体标识为Static&#x