Chapter 10 – Local Illumination 局部光照

10.4 环境映射贴图

将一个spherical function记录在一张图像或者多张图像中,该技术被称为environment mapping(环境映射贴图)。其是最为有用且最常用的环境光照的技术。相较于其他的spherical function,该技术将会消耗更多的内存但是其更简便且在实时渲染中解码速度更快。此外,只要增加贴图的分辨率,相应的准确性就会越高;同时增加texel中每个通道的位数就能更准确地反应出环境光的radiance。但是,这些准确性都是有代价的。不同于存储在贴图中的其他着色或者颜色属性,environment map中的radiance通常需要一个更高的动态范围。每个texel拥有更多的位数也意味着environment map相较于其他贴图会占据更多的空间,而其读取速度也会更慢。

对于任何全局的spherical function,我们都有一个基本的假设:入射的radiance Li只取决于方向。也就是说物体与被反射的光距离足够远,反射物并不会反射自身。

environment map这一着色技术的特点并不在于其表现出环境光照而在于我们需要如何将其与对应的材质进行结合。也就是说,对于BRDF我们要进行何种模拟或者何种假设,来使其与environment map相结合呢?Reflection mapping是environment mapping中最基本的一种情况,此时我们将BRDF假设为一个完美的镜面。一个光学意义上平整的平面或者镜面将会一反射方向ri来反射入射光线。一个方向上射出的radiance包括入射radiance,我们以反射视野向量r来表示。该向量的计算方式与ri9.5小节)相同:

因此,镜面的反射率等式将被简化为:

上述等式中的F就是菲涅尔项(9.5小节)。需要注意的是,不同于half-vector-based BRDF中的菲涅尔项(其使用half vector v与向量l或者v的夹角),我们直接使用了表面的法线向量n与反射向量r的夹角。

由于入射的radiance Li只取决于方向,因此我们可以将其存储在一个二维的列表中。这也使得我们能够对任意形状的镜面表面使用入射的radiance。我们只需要为向量r计算每一个点,并且在列表中查询对应的radiance即可,如下图所示。

反射的映射算法:

  • 生成或者读取环境贴图。
  • 对于每一个像素,如果其包含了一个被反射的物体,那么计算像素所对应的物体表面的法线向量n
  • 基于视野向量v与法线向量n,计算出反射视野向量r
  • 通过反射视野向量r来计算出environment map中的索引,其表示反射视野方向上的入射radiance。
  • 使用environment map中的texel数据作为上述等式中的入射radiance Li(r)。

一般来说,平面并不适合使用environment map,这是因为对平面来说,其反射出的射线通常都位于一个较小的角度范围内(例如,反射视野向量都簇拥在某一个向量的周围)。这将会造成一个问题,就是environment map的一小部分被映射在一个相对较大的表面。如果environment map还能使用所射出的radiance的位置信息作为参考,那么这样能大大改善效果(我们将在下一章学习)。同样,如果我们假设完全平整的表面,那么还会使用实时渲染中的平面反射技术(我们将在下一章学习)。

使用贴图数据作为场景的光照,其也被称为image-based lighting(IBL)。一般来说,我们会使用照相机去捕捉360°的全景照片,一次作为environment map,且贴图的格式为HDR。

environment map技术中将反射视野向量转换为贴图坐标的过程就是所谓的projector function(投影函数)。我们将在之后的几个小节学习其中的一些常用技术,并了解每一种技术的优势。

10.4.1 Latitude-Longitude Mapping

Blinn与Newell在1976年第一次提出了environment mapping算法。他们所使用的映射技术类似于地图上的经度/纬度系统,因此这一技术也被称为latitude-longitude mapping或者lat-long mapping。我们可以将地球表面的信息映射到地球仪或者地图上,同样的环境内的一个点也能被映射到贴图上。当我们为物体表面上某一点计算了反射视野向量,那么该向量需要被转换为球体坐标(ρ,Ф)。其中,Ф等同于经度,变化范围是0到2π。而ρ等同于纬度,变化范围是0到π。通过下列等式,我们计算出(ρ,Ф),其中r=(rx,ry,rz)是标准化后的反射视野向量,且+z表示上方:

之后我们使用这些值来读取environment map中的texel。需要注意的是latitude-longitude mapping并不能等同于Mecator投影(制作地图所使用的技术)。latitude-longitude mapping中纬度线的距离保持不变,而Mercator中极点处的距离是无限的。

当我们将球体表面“展开”为一个平面时,一般都会造成某些变形,尤其是我们无法对球体表面进行“切割”。而每一种投影都尤其优劣,主要在于保持区域性,距离以及局部的角度。而latitude-longitude mapping的问题在于environment map中的“信息密度”不再是均匀的。如下图所示的地图,顶部与底部将会有非常严重的拉伸,也就是说极点处的点将会接受更多的texel,相较于赤道处的点。这将会导致两个问题,首先是导致encoding较为低效,其次硬件在进行texture filtering时会造成显示的错误,尤其是采样点位于极点附近时。kernel filtering由于不遵从贴图的拉伸,因此其能够有效地缩减texel密度较高的区域。此外,虽然上述转换方程看上去很简单,但是其并不高效,因为arccosine在GPU上开销较高。

10.4.2 Sphere Mapping

该技术最先由Williams提出,之后又由Miller与Hoffman改进,而sphere mapping是商用显卡所支持的第一个environment mapping技术。该技术所使用的贴图图像源自于一个完美的反射球体所反射的正焦画面,因此该贴图也被成为sphere map。制作一张真实环境的sphere map的方法就是拍摄一张反射球的照片。如下图所示,左侧为sphere map而右侧为latitude-longitude map。

这张圆形的图像也被称为light probe,因为其捕捉了球体所在位置的光照环境。即使我们使用其他的encoding技术,sphere map这种捕捉image-based光照的方法都是非常高效的。一般来说,只要我们所捕捉的光照环境的分辨率足够高,我们就能在球形投影与其他形式的投影之间自由转换,例如,之后需要学习的cube mapping。

一个反射球只会展示其前方的整个环境。其会将每一个反射视野向量映射为二维sphere map上的一个点。而我们现在要做的就是基于sphere map上的一个点去反推出其对应的反射视野向量。首先,我们需要拿到sphere map上该点所对应的物体表面上的一点的法线向量,之后再生成反射视野向量。所以,为了反转这一过程并且基于反射视野向量去拿到球体上的这一坐标点,我们需要先求出球体上的表面法线,再通过法线求出(u,v)作为读取sphere map的参数。

球体的法线是反射视野向量r与原始视野向量v(在sphere map空间中表示为(0,0,1))之间的半角向量。如下图所示。

因此,法线向量n是原始视野向量与反射视野向量之间相加的和,也就是(rx,ry,rz+1)。之后我们需要对该向量进行标准化:

如果球体位于原点且半径为1,那么法线的坐标也是h在球体上的坐标位置。我们并不需要hz,因为(hx,hy)已经能表示球体上的一个点,而该坐标点的范围为[-1,1]。为了将该坐标映射至[0,1)以此作为sphere map的贴图坐标,我们需要进行以下运算:

与之前的latitude-longitude mapping不同,sphere mapping的运算更简单且更具有统一性。但是其限制也是存在的,因为sphere map的贴图只能捕捉一个视野方向上的环境。如果该贴图能够捕捉整个环境,那么很有可能我需要在另一个视野方向上计算新的贴图坐标。但是,这么做也会造成显示错误,sphere map上的一小部分将会被放大。实践中,sphere map通常会“跟随”camera,并且在视野空间内进行。

由于sphere map定义在一个固定的视野方向上,sphere map上的每一个点不但定义了反射方向还定义了物体表面的法线向量。那么一个同向的BRDF的计算结果可以存储在一个sphere map中。该BRDF包含了,漫反射,镜面反射,回射以及其他项。只要光照以及视野向量保持不变,sphere map就是正确的。

此外,我们还能对两个sphere map进行索引,其中一个使用反射向量,另一个使用表面的法线向量,以此模拟环境的漫反射效果与镜面反射效果。

10.4.3 Cube Mapping

Greene于1986年提出了cubic environment map,其也被称为cube map。该技术也是现在最为常用的技术,其投影运算通常直接由GPU负责。为了创建一个cube map,我们需要将周边的环境投影到cube的每一个面上,而cube的中心点就是camera所处的位置。之后cube上每一个面的图像将被用作environment map。如下图所示。

如果我们将cube map展开到一个平面上,那么一般来说,其都是一个“十字形”。但是,在硬件中,cube map将被存储在6张正方形的贴图中,并不是存储在单张的矩形贴图中,因此其并不会造成存储空间的浪费。

此外,我们还能够使用camera实时渲染一个场景6次以创建cube map。如下图所示。为了从现实的环境中生成cube map,通常我们需要全景照相机。

Cubic environment mapping不同于sphere mapping,其不会与视野的方向相关联。而且相较于latitude-longitude mapping,其采样点的分布更为统一,不会在极点或者边界处产生过量采样。Wan提出了一种isocube的映射技术,其采样率虽然低于cube mapping,仍然能够利用硬件对于cube mapping贴图的性能优化。

对于cube map的读取较为直接。任何向量都能直接作为一个三元的贴图坐标,以此读取该方向上的数据。所以,对于反射来说,我们能够直接将反射视野向量r传入GPU,并不需要对其进行标准化。在较早的GPU平台上,cube map的bilinear filtering可能会在cube每一个面的边缘处生成缝隙。为了缓解这一问题,我们可以将视野投影设置得更宽,这样每个面将会包含周边的texel。不过所有现代的GPU都已经能够正确地执行filtering,所以这些做法已经不再需要了。

10.4.4 其他投影

现在cube map是用于表现环境光照的最为常用的手段,因为现代的GPU对于cube map执行效率更高,且cube map本身所具有的功能也较多,准确性也较高。不过,本小节中我们也会学习一些其他的投影方式。

Heidrich与Seidel提出了使用两张贴图来进行dual paraboloid environment mapping(双重抛物面环境映射贴图)。其原理类似于sphere mapping,但是我们并不会将球体所反射的环境生成为贴图,而是使用两次抛物面投影。每一个抛物面将会创建一个圆形贴图,其类似于sphere map,且会覆盖环境的半球范围。

与sphere mapping相同,该方法也会基于贴图的空间来计算反射视野向量。向量中z值的正负将用来决定读取那一张贴图。读取函数为:

上述等式适用于map中的正面图像,如果需要读取背面图像,那么需要为rz加上负号。

parabolic map相较于sphere map与cube map,其对于环境的采样更为均匀统一。但是,对其其中两个贴图的缝隙处的采样点,我们需要进行额外的操作,这也使得读取dual paraboloid map的开销更高。

Octahedral mapping(八面体映射贴图)是另一种值得我们学习的投影方式。其并不会将周围球形的环境投影到cube上,而是将其映射到一个八面体,如下图所示(左侧部分为cube map而右侧部分则是octahedral map)。

如果我们将octahedral map平铺为贴图,那么我们可以看到其是由8个三角形所组成的平面。而该平面可能是正方形也可能是矩形。如果我们使用正方形的版本,那么读取octahedral map将会非常高效。基于反射方向r,我们计算出:

如果ry是正数,那么正方形贴图对应的贴图坐标为:

如果为负数,那么函数将变为:

Octahedral mapping并不存在dual paraboloid mapping所存在的filtering问题。在数学意义上,这一类投影可能略微包含更多的步骤,但是其实践中的效率更高。其造成的变形也类似于cube map,因此如果硬件不支持cube map贴图,那么我们可以选择octahedral map。这类投影的另一个用处就是通过二维的向量来表示一个三维空间内的法线方向。

留下评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据