7b348ae84190f8edab7ff4724f4eb39c.png
前阵子忙于考试和学习ML知识停更了几个月。

常见的环境映射技术有三 Cube Mapping, Spherical Environment Mapping 和 Dual Paraboloid Environment Mapping。

Cube Mapping 是如今最常见的环境映射方法,后续会写一些关于其应用的文章。

Dual Paraboloid Environment Mapping 双抛物面环境映射之前已经写过了。

Jeffrey Zhuang:详解双抛物面环境映射​zhuanlan.zhihu.com
c1498ae701eb58bb4806b9ef518399db.png

今天聊聊 Spherical Environment Mapping。

a29ab6017da359dfaf2808f1e3b00650.png
图1

Spherical Environment Mapping 又称作 Sphere Mapping,是一项非常早期的环境映射技术。它采用单张贴图表示整个环境(没错,是整个环境除了一个点,后面会讲到)。

b81eafc28c50fb1e6b9b623207a4b80c.png
图2 其中蓝色线为球面的法线

上图中有一个球,我们假设这个球能够反射环境,球的右侧有点C,想象点C处有一个相机给球拍照。由于球表面能反射环境,我们通过球面能够得到一张关于环境的照片,但是不包含图中灰色区域。因为灰色区域中的光线无法通过球面反射达到点C处的相机。

确保理解上述过程后,我们接着想象一下点C处的相机不断右移,并且焦距不断变长,最终趋近于正交相机。

d17ceddfa036a49ce8e96e175b6243c8.png
图3

结果会如上图所示。观察上图可以注意到点C不见了,因为它跑到无穷远处了,而从相机指向球面的射线变得平行(原理和用方向光近似太阳的直接光照一样)。如此一来,给球面拍照能够比图2中获得更多的环境信息(灰色区域覆盖的角度范围变小)。

确保理解上述过程后,我们接着想象。想象球体不断缩小,直到趋近于无穷小,同时假设相机的分辨率可以任意高。当球体趋于无穷小后,灰色区域覆盖的环境也会越来越小,最终产生一个盲点,也就是说前文中提到的,单张贴图表示整个环境,除了一个点。

838abfa01192d6fe80682ff689ec36b9.png

如此一来,再看下维基百科对于 Sphere Mapping 的解释:

In computer graphics, sphere mapping (or spherical environment mapping) is a type of reflection mapping that approximates reflective surfaces by considering the environment to be an infinitely far-away spherical wall. This environment is stored as a texture depicting what a mirrored sphere would look like if it were placed into the environment, using an orthographic projection (as opposed to one with perspective). This texture contains reflective data for the entire environment, except for the spot directly behind the sphere. (For one example of such an object, see Escher's drawing Hand with Reflecting Sphere.)

概念模型讲完后,再来看看采样的公式:

r为反射向量。

虽然不复杂,并不是一眼望穿,下面说明公式的由来。

fc4b73eb431a0a6150da96d3a489380f.png

以上图所示讲解,假象的反射球表面法线为n,视角方向v,反射向量r。

要理解此处的公式,正确理解视角方向v非常重要。概念模型中,相机最终处于无限远,且正交投影,因此以OpenGL的视口坐标系为例(相机看向-Z轴),此处的v恒定为(0, 0, 1)。

根据反射的原理可以知道,对于没有归一化的法线 n = v + r 。

对于采样而言,r为已知量,

,令其为单位向量。

带入 v 和 r 可得 n =

然后求 n 的模

我们得到归一化的法线

到这一步,问题变成了已知球面法线坐标,如何获得球面坐标?

这个问题对于位于原点的球面而言非常简单,球面坐标数值等同于法线向量的数值。

例如球面有一点

,该点的法线向量即

更进一步的讲,对于半径为1的球面坐标数值和归一化法线向量的数值相等。

回过头来再看归一化法线n',它的三个分量即单位球体表面的坐标值。

我们最终要采样的是二维图,因此z分量就可以抛掉了,只需要x、y分量:

但是这里有个坐标范围的问题,

的取值范围是
,然而贴图的采样坐标是
。要解决这个问题,只需一个函数将取值范围[-1,1]的输入映射为
的输出。通过
变换就可以满足条件,将-1和1分别带入就知道结果正确与否了。

由此我们获得最终的公式:

再令分母中的

就得到了一开始给出的公式:


讲到这里,公式只讲了一半,我们知道了如何通过反射向量求采样uv坐标。接下来推导一下根据采样坐标求反射向量。

根据前文,

以及
变换后可得:

以及

我们已知单位向量

单位向量的模为1,将

代入
得到

(式1)

已知

将根号中的平方展开

由于反射向量为单位向量(作为已知量r的假设条件),可知

平方后

,带入到
中,得
(式2)

(式2)代入(式1)

化简

进一步化简

继续

再继续

最后整理得到:

(式3)

解决了

后,还剩下
,之前已经得知

变换后

这里未知变量只有

,根据
(式2)

代入

(式3)便可得
,合并常数
,从右边根号下再提出一个
与外面的
合并得到

综上可得

至此,

都已求得,下面列到一起以备参考:


概念和公式都讲完了,说说优缺点。

优点是只需要一张贴图。

但问题也很明显,首先环境反射的视点固定,也就是说转动或移动虚拟相机后需要重新生成sphere map才能保证正确。精度非常不均匀,我们称假象球朝向拍摄相机一侧为正面的话,正面的精度高,位于贴图中心区域,背面精度低,位于贴图上圆形靠外侧区域。关于精度这块的研究总结有一片非常棒的paper,但是忘记名字了,下回看到的时候再补上。

由于映射非线性,采样时线性过滤的结果有误差。如下图所示:

bf44ad80674fa7af32b0e9768c99785e.png

如今应用场景比较常见的是MatCap,在MatCap的应用中法线是已知量,直接采用view space的normal计算即可


参考

Wikipedia - Sphere Mapping

Programming with OpenGL: Advanced Rendering - Sphere Mapping

Environment mapping and mirroring

reflections-based-on-local-cubemaps-in-unity

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐