Home Forums GAMES在线课程(现代计算机图形学入门)讨论区 HW3 framework 研究,法线向量为何会乘以(view*model)^-1^T

Viewing 1 reply thread
  • Author
    Posts
    • #5837 Score: 0
      赵春光
      Participant
      4 pts

      我正在研究HW3中的framework,其中rasterizer::draw定义的时候为什么要把法线normal乘以(view*model)^-1^T呢?
      换句话说,我理解顶点t乘以(view*model)。但不理解下面法线部分n[]的定义为什么会乘以inv_trans?

      下面这段代码是我说的运算所在的函数:
      void rst::rasterizer::draw(std::vector<Triangle *> &TriangleList) {

      float f1 = (50 – 0.1) / 2.0;
      float f2 = (50 + 0.1) / 2.0;

      Eigen::Matrix4f mvp = projection * view * model;
      for (const auto& t:TriangleList)
      {
      Triangle newtri = *t;

      std::array<Eigen::Vector4f, 3> mm {
      (view * model * t->v[0]),
      (view * model * t->v[1]),
      (view * model * t->v[2])
      };

      std::array<Eigen::Vector3f, 3> viewspace_pos;

      std::transform(mm.begin(), mm.end(), viewspace_pos.begin(), [](auto& v) {
      return v.template head<3>();
      });

      Eigen::Vector4f v[] = {
      mvp * t->v[0],
      mvp * t->v[1],
      mvp * t->v[2]
      };
      //Homogeneous division
      for (auto& vec : v) {
      vec.x()/=vec.w();
      vec.y()/=vec.w();
      vec.z()/=vec.w();
      }

      Eigen::Matrix4f inv_trans = (view * model).inverse().transpose();
      Eigen::Vector4f n[] = {
      inv_trans * to_vec4(t->normal[0], 0.0f),
      inv_trans * to_vec4(t->normal[1], 0.0f),
      inv_trans * to_vec4(t->normal[2], 0.0f)
      };

      //Viewport transformation
      for (auto & vert : v)
      {
      vert.x() = 0.5*width*(vert.x()+1.0);
      vert.y() = 0.5*height*(vert.y()+1.0);
      vert.z() = vert.z() * f1 + f2;
      }

      for (int i = 0; i < 3; ++i)
      {
      //screen space coordinates
      newtri.setVertex(i, v[i]);
      }

      for (int i = 0; i < 3; ++i)
      {
      //view space normal
      newtri.setNormal(i, n[i].head<3>());
      }

      newtri.setColor(0, 148,121.0,92.0);
      newtri.setColor(1, 148,121.0,92.0);
      newtri.setColor(2, 148,121.0,92.0);

      // Also pass view space vertice position
      rasterize_triangle(newtri, viewspace_pos);
      }
      }

      谢谢你的关注与帮助!

    • #5893 Score: 0
      windsmoon
      Participant
      1 pt

      法线的坐标转换略微特殊,当有非统一缩放的时候,普通顶点乘以 model 矩阵就可以变换到世界空间,但是法线就得乘以 model矩阵的逆转置才行,当然全是统一缩放也可以这么做,但是就没必要了,统一缩放指 xyz 三个轴的缩放都一致。
      至于为什么,几何上理解就是当三角形出现非统一缩放的时候,还按照顶点的转换方式,法线的方向会偏向与实际应该的方向相反的地方,建议网上搜一下,这个应该很多,就搜 法线向量的抓换 就可以。

      • #6028 Score: 0
        赵春光
        Participant
        4 pts

        谢谢你的帮忙!
        根绝你的建议,我找到了一篇介绍原理。

        https://blog.csdn.net/u010006851/article/details/52929100
        看上去还挺简介明了的,介绍为什么法线的转换,是坐标变换的逆矩阵了。

        我的理解就是
        给定任一个向量V,
        1. 因为法线定义是N*V=0;
        2. 对于做了坐标变换M后的向量V’=M*V
        3. 我们想找矩阵X使得,N’=N*X
        新法线的定义N’*V’=0,带入等式2,等式3,有N*X*M*V=0,
        故,X=M^-1

Viewing 1 reply thread
  • You must be logged in to reply to this topic.