GAMES202作业2旋转部分


写在前面

本文是写在做完GAMES202 高质量实时渲染作业2之后的总结。通过不严谨的数学公式,从球谐的旋转不变性出发,一步步推导出如何求旋转后的系数${c_l^m}^{\prime}$。

非常感谢闫老师和助教们的课程和代码框架!!!

效果展示:

(注:环境光为Cornell Box)

问题描述

定义在球面上的环境光 $L_i(\omega_i)$可以被展开成球谐基函数的线性组合:

假设现在有一个旋转矩阵 $R^{-1}$,现在有一个旋转矩阵,将环境光 $L_i(\omega_i)$进行了旋转,得到了 $L_i(R\omega_i)$。

注:将$y = x^2$向x轴正半轴方向移动了a个单位后,变为了$y = (x-a)^2$,而不是$y = (x+a)^2$,旋转也是这个道理。

问题来了如何求得 $L_i(R\omega_i)$ 的球谐系数${c_l^m}^{\prime}$?

最简单的想法,重新计算 $L_i(R\omega_i)$ 对每个球谐基函数的投影:

假如环境光源在每一帧都在旋转,那么每一帧渲染之前,都要进行这么一个积分,这是无法接受的。

回顾之前的内容,该积分使用的是黎曼和的形式求解,复杂度很高。

是否有更简单的方法计算${c_l^m}^{\prime}$ 呢?

比如,是否存在某个方法,可以直接从${c_l^m}$得到${c_l^m}^{\prime}$呢?

这就是本文探讨的话题。

什么是旋转不变性

对于某个球谐基函数$B_l^m(\omega_i)$,假设现在有一个旋转矩阵 $R^{-1}$ 将$B_l^m(\omega_i)$进行了旋转,

注:旋转应该是指,按照空间中过原点的某一个轴旋转了某个角度,由于环境光是无限远的,所以转轴虽然在空间中任意位置,但可以视作在原点。

那么旋转后的函数的表达式为$B_l^m(R^{}\omega_i)$。

旋转不变性指的是,$B_l^m(R\omega_i)$可以被拆分成同阶(band)的其他基函数的线性组合,而与其他阶的基函数无关,即:

从旋转不变性出发,开始推导

根据球谐展开的概念,对环境光 $L_i(\omega_i)$,我们有:

在这篇文章里,我们关注 $l = 1$的情况,忽略其他阶,则上式可以写成:

在继续进行之前,要先达成一个共识(我不确定这是否需要证明):

  • 考虑这么一件事情:如果将 $L_i(R\omega_i)$在 $B_l^m(R\omega_i)$上进行分解,所得到的球谐系数是多少呢?

  • 由于我们将光源和球谐基函数同时用 $R$ 进行了旋转,那么它们之间的相对关系应该是不会发生变化的,也就是球谐系数仍然是 $c_l^m$:

有了这个共识,我们就可以直接获得 $L_i(R\omega_i)$在 $B_l^m(R\omega_i)$上进行分解的球谐系数,就是${c_l^m}$(同样只关注 第1阶):

有了公式(2)后,借助球谐函数的旋转不变性(式1),我们可以将$B_l^m(R\omega_i)$ 表示为同band其他基函数的线性组合:

假设 $x_k,y_k, z_k$全部已知,那将上面的式子代入式(2),有:

进行一下合并同类项:

令 ${c_1^{-1}}^{\prime} = (c_1^{-1}x_{-1} + c_1^{0}y_{-1} + c_1^{1}z_{-1})$

${c_1^{0}}^{\prime} = (c_1^{-1}x_{0} + c_1^{0}y_{0} + c_1^{1}z_{0})$

${c_1^{1}}^{\prime} = (c_1^{-1}x_{1} + c_1^{0}y_{1} + c_1^{1}z_{1})$

则上式被重写成:

这样,我们就得到了旋转之后,各个球谐基函数的系数${c_l^m}^{\prime}$了。


下一节定义了 $M_R$, 利用 $M_R$可以将 ${c_1^{-1}}^{\prime},{c_1^{0}}^{\prime},{c_1^{1}}^{\prime} $用矩阵乘法表示:

求解

之前,我们假设 $x_k,y_k, z_k$全部已知,但是它们其实是未知的,接下来我们来求解它们。

以式(3)为例,在这里,我们要求的是 $x_{-1}, x_0, x_1$,如何求解呢?

其实很简单,3个未知数,需要3个方程,我们只需要随便找3个 $n_0, n_1, n_2$代入,得到三元一次方程组。因为 $B_l^m(R\omega_i)$是已知的函数,所以上述方程组可以很简单的解出来:

同样的,对于 $y_k$ 和 $z_k$,也带入 $n_0, n_1, n_2$,可以解出$y_k$ 和 $z_k$。(求解$y_k$ 和 $z_k$ 时,选取的 $n_0, n_1, n_2$不一定要是一样的,但是选一样的接下来比较方便)。

式(5)就是求解 $x_k,y_k, z_k$ 的核心。本节剩下的内容就是对其进行向量化,变成矩阵运算的形式,这样一来我们可以少写一些循环语句,二来运算也会快一些。


为了求解 $x_k,y_k, z_k$,我们用到了3个三元一次方程组,每个方程组3个方程,这9个方程可以被写成更简洁的矩阵形式(前提是,三个方程组所用的$n_0, n_1, n_2$是一致的):

为了表述方便,这里定义了 $P(\omega_i)$ (有的地方也称之为对$\omega_i$的投影)和$M_R$:

利用新定义的符号,可以继续写成更简洁的形式:

再记 $S = [P(Rn_0) \quad P(Rn_1) \quad P(Rn_2)] $ , $A = [P(n_0) \quad P(n_1) \quad P(n_2) ]$ :

注:这里 $S, M_R, A$ 都是3x3的方阵。如果我们在处理2阶球谐函数的时候, $S M_R A$ 都变为了5x5的方阵,3阶则7x7,以此类推。

至此, $M_R$ (即$x_k,y_k, z_k$的矩阵形式)的解变得更加一目了然了:

式(6)和式(5)其实是一样的,只是变成了矩阵的形式。

具体的算法

根据 $M_R = S A^{-1}$,要求 $M_R$ 我们只需算出 $S$ 和 $A$即可。所以有了下面的算法:

  1. 随机选3个向量,这里选择 $n_0 = [0,0,1], n_1 = [0,1,0], n_2 = [1,0,0]$
  2. 代入 $P(\omega_i)$求得 $A$,并得到 $A^{-1}$
  3. 利用旋转矩阵,求得 $Rn_k$,并带入 $P(\omega_i)$求得 $S$
  4. $M_R = S A^{-1}$
  5. 给定空间中任意一渲染点的坐标 $p$ 的在未旋转光源下的系数 $c = ({c_1^{-1}}^{},{c_1^{0}}^{},{c_1^{1}}^{})^T $, $c^{\prime} = {M_R}^T c$。

更具体的例子可以参考[1][1]文章尾部的示例一节。

其他

关于这部分,有几个问题我也没完全搞懂。

  1. 乘以 $M_R$还是 ${M_R}^T$?[1][1]和作业2的任务书里面都是乘以 $M_R$,但是我上面的推导的结果是${M_R}^T$,我实现的时候对比了一下,乘以${M_R}^T$的结果才是对的,乘以${M_R}$的结果会使得渲染的结果与模型的旋转方向相反。

  2. 不同轴,如果使用同一个RotationMatrix进行模型的旋转和球谐系数的计算,会使得它们在绕不同轴旋转。。。这我暂时不能理解。

参考资料

[1]一种简易的旋转球谐函数系数的方法


文章作者: GeT Left
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 GeT Left !
  目录