Home Forums GAMES在线课程(现代计算机图形学入门)讨论区 作业2 三角形在屏幕中的位置不对

Viewing 7 reply threads
  • Author
    Posts
    • #7795 Score: 0
      orange
      Participant

      写完跑起来后得到的结果和预期不太一样。第一是整体向右移动了半个屏幕,感觉像是model变换除了问题。第二个问题是蓝色的三角形罩住了黄色的三角形?代码如下

      // 判断点是否在三角形内

      bool is_point_inside_triangle(Eigen::Vector3f point, Eigen::Vector4f p1, Eigen::Vector4f p2, Eigen::Vector4f p3) {
      // do three dot products and check if symbols are the same. if so, return true, else false
      Eigen::Vector3f _p1(p1.x(), p1.y(), 0);
      Eigen::Vector3f _p2(p2.x(), p2.y(), 0);
      Eigen::Vector3f _p3(p3.x(), p3.y(), 0);

      Eigen::Vector3f v12 = _p2 – _p1;
      Eigen::Vector3f v23 = _p3 – _p2;
      Eigen::Vector3f v31 = _p1 – _p3;

      Eigen::Vector3f v1p = point – _p1;
      Eigen::Vector3f v2p = point – _p2;
      Eigen::Vector3f v3p = point – _p3;

      auto a = v12.cross(v1p);
      auto b = v23.cross(v2p);
      auto c = v31.cross(v3p);

      if(a.dot(b) < 0 || b.dot(c) < 0 || c.dot(a) < 0 ) {
      return false;
      } else {
      return true;
      }
      }

      // rasterize_triangle

      auto v = t.toVector4();
      Eigen::Vector4f p1 = v[0];
      Eigen::Vector4f p2 = v[1];
      Eigen::Vector4f p3 = v[2];
      int minX = std::floor(std::min(std::min(p1.x(), p2.x()), p3.x()));
      int minY = std::floor(std::min(std::min(p1.y(), p2.y()), p3.y()));
      int maxX = std::ceil(std::max(std::max(p1.x(), p2.x()), p3.x()));
      int maxY = std::ceil(std::max(std::max(p1.y(), p2.y()), p3.y()));

      for(int i = minY; i < maxY; i++) {
      for(int j = minX; j < maxX; j++) {
      float cx = j + 0.5;
      float cy = i + 0.5;
      Eigen::Vector3f currentPoint(cx, cy, 0.0);

      bool inside = is_point_inside_triangle(currentPoint, p1, p2, p3);
      if(inside) {
      auto[alpha, beta, gamma] = computeBarycentric2D(cx, cy, t.v);
      float w_reciprocal = 1.0/(alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w());
      float z_interpolated = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w();
      z_interpolated *= w_reciprocal;
      int currentBufferIndex = get_index(j, i);
      if(depth_buf[currentBufferIndex] > z_interpolated) {
      depth_buf[currentBufferIndex] = z_interpolated;
      set_pixel(Eigen::Vector3f(cx, cy, 0.0), t.getColor());
      }
      }
      }
      }

      // get_projection_matrix 感觉问题可能出在这里?但是作业一好像没发现有什么问题

      Eigen::Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio, float zNear, float zFar)
      { // Students will implement this function

      Eigen::Matrix4f projection = Eigen::Matrix4f::Identity();

      // TODO: Implement this function
      // Create the projection matrix for the given parameters.
      // Then return it.
      float fov = eye_fov * M_PI / 180.0;
      float t = std::abs(zNear) * std::tan(fov / 2.0);
      float b = -t;
      float r = t * aspect_ratio;
      float l = -r;
      float n = zNear;
      float f = zFar;

      // perspective to orthographic matrix;
      Eigen::Matrix4f Mp2o;
      // orthographic projection matrix
      Eigen::Matrix4f Moscale;

      Eigen::Matrix4f Motranslation;

      Mp2o << n, 0.0, 0.0, 0.0, 0.0, n, 0.0, 0.0, 0.0, 0.0, n + f, -n * f, 0.0, 0.0, 1.0, 0.0;

      Moscale << 2.0/(r – l), 0.0, 0.0, 0.0, 0.0, 2.0/(t – b), 0.0, 0.0, 0.0, 0.0, 2.0/(f-n), 0.0, 0.0, 0.0, 0.0, 1.0;
      Motranslation << 1.0, 0.0, 0.0, -(r+l)/2.0, 0.0, 1.0, 0.0, -(t+b)/2.0, 0.0, 0.0, 1.0, -(n+f)/2.0, 0.0, 0.0, 0.0, 1.0;

      Eigen::Matrix4f Mortho = Moscale * Motranslation;

      Eigen::Matrix4f Mprojection = Mortho * Mp2o;

      return Mprojection;
      }

    • #7796 Score: 0
      orange
      Participant

      截图在这里

      Attachments:
      You must be logged in to view attached files.
    • #8179 Score: 0
      两只黑眼圈
      Participant

      depth_buf没初始化值得话,有问题

    • #8180 Score: 0
      两只黑眼圈
      Participant

      而且,每帧结束要自己去清空或重置depth_buf的值

    • #8411 Score: 0
      Vicky W
      Participant

      if(depth_buf[currentBufferIndex] > z_interpolated
      这句反咯,应该是小于。

      另外请问是否解决了右移的bug?因为我也出现了这样的问题,摸不着头脑,很头痛。

    • #8498 Score: 0
      MIABlackLL1
      Participant
      1 pt

      我也遇到了同样的问题,因为我是在Windows下自己配的环境,没用虚拟机,不知道是不是不同平台的库的问题。
      现在我在set_pixel里面把index的偏移了-350强行移到中间。

    • #8499 Score: 1
      MIABlackLL1
      Participant
      1 pt

      我真的是裂开,找到原因了:
      算包围盒和遍历像素的时候要用int,用float会有偏移。。。
      坑了我一天,气死了,做MSAA的时候也是一直出问题,搞了半天才发现是float的问题,我吐了

      This post has received 1 vote up.
      • #8511 Score: 0
        Vicky W
        Participant

        感谢你的分享,我回过头检查,也发现是调用set_pixel上色的时候,坐标参数给错了。纠正之后得到正确结果了。
        感觉我们作业进度相仿,不知你是否愿意互换联系方式?日后可以彼此讨论作业bug 🙂
        我的邮箱是kingsonthree@sina.com。

        Attachments:
        You must be logged in to view attached files.
    • #8513 Score: 0
      Vicky W
      Participant

      ps:

      我使用了 “rgb” 方法排查右移问题。
      在遍历包围盒时,判断像素点是否在三角形内,若返回否,则执行下列语句:

      Eigen::Vector3f OutsidePix {x,y,0};
      Eigen::Vector3f OutsideCol {x,y,1};
      set_Pixel(OutsidePix, OutsideCol);

      得到结果如附图所示。
      我不确定这是否表示包围盒相关步骤,或更早的步骤中存在问题。如有朋友遇到类似问题,欢迎交流。
      日后如果理清思路,我也会补充分享。

      Attachments:
      You must be logged in to view attached files.
Viewing 7 reply threads
  • You must be logged in to reply to this topic.