Games101-Chapter4-变换(模型、视图、投影)

知识补充:

在旋转里,旋转矩阵的逆矩阵就是这个矩阵的转置(这样的矩阵叫做正交矩阵)


3D(实际世界)到2D(我们视野)的变换的处理有三步:

模型变换(m),视图变换(v),投影变换(p)

  1. 模型变换(modeling tranformation):将一个物体自身进行变换(缩放、旋转、位移),上一节介绍了此变换方法。

特别的:三维空间中的旋转

记忆理解:绕着转的那个轴的值不会变,所以只考虑另外两个轴,这时候就变成了2D

                        

 注意绕y轴的旋转是特殊的

        2.视角变换(view tranformation):根据眼睛(相机)来判断物体的相对位置。

定义相机的三要素:相机位置position(向量e),相机面向方向gaze direction(单位向量g),相机上下方向up direction(单位向量t)。

为了方便计算,我们应设定相机处于原点(0,0,0),并让t指向Y轴方向,g指向-Z方向。如此,我们应该先进行相机平移;后进行相机的旋转:将单位向量g转到-Z轴方向,将单位向量t转到Y轴方向,那么顺理成章的 gXt即指向X轴方向。

我们要做的:

把相机移到原点:

接下来就是旋转

我们想: 

 但是把一个向量转到一个单位向量很难

逆向想:把一个单位向量转到一个已知的向量很简单

 那么

 

 就是上图矩阵的转置矩阵

3.投影变换

        (1)正交变换

          变换过程:把立方体的中心通过平移移到原点,再通过缩放将其压缩成每个边范围是[-1,1]的正则立方体(注意并不是1*1*1)

 (2)投影变换

        

相当于先压缩成上边正交变换这个待变换的立方体,再把其进行正交变换

先压缩远平面把frustum变成下图这个

 那么,怎么压缩呢?

 进行完persp-->ortho,再进行ortho的变换即可

最终推导出

[作业1] 

//逐个元素地构建模型变换矩阵并返回该矩阵。
//在此函数中,你只需要实现三维中绕 z 轴旋转的变换矩阵,
//而不用处理平移与缩放
Eigen::Matrix4f get_model_matrix(float rotation_angle)
{
    Eigen::Matrix4f model = Eigen::Matrix4f::Identity();
    float angle = rotation_angle * MY_PI / 180.0f;  //角度制转弧度制
    //绕z轴旋转的矩阵
    Matrix4f M_r;
    M_r<<
        cos(angle), sin(angle), 0, 0,
        -sin(angle), cos(angle), 0, 0,
        0, 0, 1, 0,
        0, 0, 0, 1;

    model = M_r * model;    //旋转
        
    return model;
}
//使用给定的参数逐个元素地构建透视投影矩阵并返回该矩阵
Eigen::Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio,
                                      float zNear, float zFar)
{
    Matrix4f projection = Matrix4f::Identity();     //要返回的透视投影矩阵
    Matrix4f orth = Matrix4f::Identity();           //正交矩阵
    Matrix4f ProjectToOrth = Matrix4f::Identity();  //透视投影到正交投影

    //求PToO
    float angle = (eye_fov / 2) * MY_PI / 180.0f;   //一半的eyeFov
    float n = -1.0 * zNear;
    float f = -1.0 * zFar;      //这里默认是朝-z看

    float t = f * tan(angle);
    float b = -1.0 * t;
    float r = aspect_ratio * t;
    float l = -1.0 * r;

    ProjectToOrth <<
        n, 0, 0, 0,
        0, n, 0, 0,
        0, 0, n + f, -1.0 * n * f,
        0, 0, 1,0;
    //只需负责缩放
    orth <<
        2.0 / r - l, 0, 0, 0,
        0, 2.0 / t - b, 0, 0,
        0, 0, 2.0 / f - n, 0,
        0, 0, 0, 1;
    projection = orth*ProjectToOrth;
    return projection;
}

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值