Home Forums Games202-高质量实时渲染 【作业2】环境光球谐旋转推导

Viewing 3 reply threads
  • Author
    Posts
    • #8281 Score: 0
      cmc233
      Participant
      6 pts

      没看懂为什么旋转不变性就是R(f(x)) =f(R(x)), 将球面函数f(x)旋转R得到的应该是f(R^(-1) x)吧

      球谐函数的旋转不变性不是指”任意l阶的某一球谐函数在r’的取值,可以由其同阶的球谐函数在r的取值线性组合表示,系数由r到r’的旋转矩阵决定”,从而,“f(x)用球谐函数展开后,旋转f(x), 新的球谐系数可以表示成原来同阶的系数的线性组合”吗?

      流程中的第三步应该是原sh系数*M,而不是M*原sh系数?

      我自己推导了一下(如图),得到的结果是M = [P R^(-1)n] A^(-1)

      还有,感觉tools.js的mat4Matrix2mathMatrix函数有问题,mat4是按列优先存储的,math.matrix() 是按行构造的,r.push(rotationMatrix[i*4+j])最后得到的矩阵是原矩阵的转置。因为mat4Matrix2mathMatrix返回的就是R^(-1),所以按作业文档里用M = [PRn]A^(-1)才恰好得到正确结果

      Attachments:
      You must be logged in to view attached files.
    • #8283 Score: 0
      cmc233
      Participant
      6 pts

      图片第5行有个笔误,等式左边不应该是一个P(R^(-1) w),而是应该像右边一样是所有l阶SH的vector

    • #8284 Score: 0
      JZZ
      Keymaster
      2 pts

      第一个问题:R^{-1}
      首先,文档中列举的第一个性质和推导本身并无关系,推导过程立足的其实是性质二。。。。
      说清楚一些,就是我们任意选择的{n_i},其实可以看作是到环境贴图上的dir vector,然后旋转环境光就是对这些向量的旋转,也就是R(n_i)。然后把R(n_i)重新用SH拟合,这样得到的新的SH系数应该等于原来SH系数的一个线性变化,这个才是算法设计的立足点。(性质一讲的旋转其实是一种旋转操作,R在等式两边不是一样的意思),文档提供的算法设计是没有问题的。

      然后,你的推导过程说实话我没有怎么看懂。。。。比如第一句的应该是f(R^{-1}(x)),这里的“应该是”三个字感觉没有那么显然。。。。不过在这确实扫除了一个小坑,也有可能你的理解是对的,但是表述上没有讲的很详细很清楚。[Hint: 实时端天空盒的旋转矩阵和SH系数的旋转矩阵之间传递时确实要好好想一下。]

      • #8286 Score: 0
        cmc233
        Participant
        6 pts

        天空盒子原来的方程是f(w),将整个盒子旋转R后的新盒子,相当于在w处的取值是原来R^(-1)*w处的取值,得到的新方程就是f(R*w)啊
        我的推导只是将f(w)用球谐函数展开了啊,P就是球谐函数,lamda就是对应系数,为什么看不懂?我的推导也是基于文档中的性质二(而且这个性质才应该是球谐函数的旋转不变性,参见https://en.wikipedia.org/wiki/Spherical_harmonics#Rotations)
        然后,我其实没看懂文档中列的第一个性质是什么意思

        • #8287 Score: 0
          JZZ
          Keymaster
          2 pts

          这样就算讲明白了,因为框架中我们提供的是环境光旋转矩阵,传给SH系数旋转的旋转矩阵应该是查询方向的旋转矩阵,两者在这里有个取逆的关系。这个“逆”的关系不是在推导中使用,而是在传入之前完成的。

          问题发现的超级好,但是”应该是”三个字应该是解释的重点,这样其他同学参考帖子的时候会轻松一些。

          • This reply was modified 2 years, 11 months ago by JZZ.
          • This reply was modified 2 years, 11 months ago by JZZ.
          • #8291 Score: 0
            cmc233
            Participant
            6 pts

            感觉文档在写推导公式的时候有点混淆SH系数和SH函数。框架提供的SHEval(x,y,z)返回的值是前l阶所有SH函数在w=(x,y,z)处的取值,但是推导过程中P指的是SH系数?这也是为什么第三步中不应该是M*原SH系数,而应该是原SH系数*M

    • #8288 Score: 0
      JZZ
      Keymaster
      2 pts

      问题二:不同库的矩阵存储方式
      文档中提供的转换函数是没有问题的,读的时候是按行读的,然后传递给一个行优先的矩阵。可以打印一下转换前后的矩阵看看有没有错。

      但是在实现SH旋转过程中确实需要注意到math.js的行优先存储,在合适的地方进行转置操作。

      • #8292 Score: 0
        cmc233
        Participant
        6 pts

        打印出来的确是没有问题的。
        但是这是为什么啊,i*4+j是按行在读取,可glmatrix的文档里写mat4是按列存储的

        Attachments:
        You must be logged in to view attached files.
      • #8294 Score: 0
        cmc233
        Participant
        6 pts

        不对,打印下来结果不对,例如取
        let v = mat4.create();
        mat4.fromRotation(v, math.pi / 6, [0, 1, 0]);
        let v_ = mat4Matrix2mathMatrix(v);
        console.log(v_);得到

        0.8660253882408142, 0, -0.5, 0
        0, 1, 0, 0
        0.5, 0, 0.8660253882408142, 0
        0, 0, 0, 1

        但是实际旋转矩阵应该是
        0.8660253882408142, 0, 0.5, 0
        0, 1, 0, 0
        -0.5, 0, 0.8660253882408142, 0
        0, 0, 0, 1

        • #8643 Score: 0
          misskanagi
          Participant

          “mat4Matrix2mathMatrix”这个函数确实是“误打误撞”用对了,这个函数把列优先存储的矩阵转换成了行优先存储的矩阵,这样相当于对矩阵做了一次转置,而旋转矩阵是一个正交矩阵,对旋转矩阵转置相当于求出了该旋转矩阵的逆矩阵

          正确的“mat4Matrix2mathMatrix”函数的实现应该是把最后的return math.matrix(mathMatrix);变成return math.transpose(math.matrix(mathMatrix));

          另外#8284回复最后的Hint确实需要仔细琢磨一下。

          • #8644 Score: 0
            misskanagi
            Participant

            正确的“mat4Matrix2mathMatrix”函数的实现应该是把最后的return math.matrix(mathMatrix);变成return math.transpose(math.matrix(mathMatrix));

            这句话错了,请无视。

Viewing 3 reply threads
  • You must be logged in to reply to this topic.