Games101笔记:第一弹,透视投影矩阵推导

1. 透视投影矩阵推导

a. 将物体投射到我们的眼睛里需要经过一些变换。

a>正交投影 (Orthographic projection)

此图出自Games101课件
在这里插入图片描述
在这里插入图片描述
将物体中心先移动到坐标原点,然后缩放为(-1 ~ 1)1^3内的立方体中。

b>透视投影 (Perspective projection)

跟着闫老师推导了一遍,思路清晰:

  1. 首先有个性质,(1, 0, 0, 1) and (2, 0, 0, 2) both represent (1, 0, 0)
  2. 如何将远平面上的点变换到近平面上。在这里插入图片描述
    在这里插入图片描述
  3. 上图由远近平面的位置,计算出x -> x′ 、y -> y ′ 的比例值,由此可计算出x,y上的变化量。
    在这里插入图片描述
    在这里插入图片描述
  4. 如何计算第三行值呢?用到透视投影里我们发现:
    在近平面的任意一个点经过变换后位置不变,
    在远平面上的任意一个点经过变换后z轴的位置不变性,
    得出以下推导:
    在这里插入图片描述
    在这里插入图片描述
    5.然后接着算出第三行的值
    在这里插入图片描述
    外附上第一次作业代码:
Eigen::Matrix4f get_view_matrix(Eigen::Vector3f eye_pos)
{
    Eigen::Matrix4f view = Eigen::Matrix4f::Identity();

    Eigen::Matrix4f translate;
    translate << 1, 0, 0, -eye_pos[0],
                 0, 1, 0, -eye_pos[1],
                 0, 0, 1, -eye_pos[2],
                 0, 0, 0, 1;

    view = translate * view;

    return view;
}

Eigen::Matrix4f get_model_matrix(float rotation_angle)
{
    Eigen::Matrix4f model = Eigen::Matrix4f::Identity();

    // TODO: Implement this function
    // Create the model matrix for rotating the triangle around the Z axis.
    // Then return it.
    float angle = rotation_angle / 180 * MY_PI;

    Eigen::Matrix4f rotation;
    rotation << cos(angle), -sin(angle), 0, 0,
                sin(angle), cos(angle), 0, 0,
                0, 0, 1, 0,
                0, 0, 0, 1;

    model = rotation * model;

    return model;
}

Eigen::Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio,
                                      float zNear, float zFar)
{
    //aspect_ratio  高宽比
    // eye_fov 可视角度
    
    // Students will implement this function

    // TODO: Implement this function
    // Create the projection matrix for the given parameters.
    // Then return it

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


    Eigen::Matrix4f Mortho;

    double angle = eye_fov * MY_PI / 180;

    double n = zNear;
    double f = zFar;
    
    double t = abs(n) * tan(angle / 2);
    double b = -t;

    double r = t * aspect_ratio;
    double l = -r;

    Eigen::Matrix4f Mtranstale;
    Mtranstale << 1, 0, 0, -(l + r) / 2,
                  0, 1, 0, -(t + b) / 2,
                  0, 0, 1, -(n + f) / 2,
                  0, 0, 0, 1;

    Eigen::Matrix4f Mscale;

    Mscale << 2 /(r - l), 0, 0, 0,
              0, 2 / (t - b), 0, 0,
              0, 0, 2 / (n - f), 0,
              0, 0, 0, 1;

    Mortho = Mscale * Mtranstale;

    Eigen::Matrix4f Mpersp_ortho;

    Mpersp_ortho << n,0, 0, 0,
                    0, n, 0, 0,
                    0, 0, n+ f, -(n* f),
                    0, 0, 1, 0;
    
    projection = Mortho * Mpersp_ortho;

    return projection;
}

注意:部分同学会出现三角形上下颠倒问题,这是因为文中所讲的远近平面都为负值,代码中传入的值为正值。
自此全剧终

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值