[GAMES101] homework1:Transformation

理论回顾

Model transformation

解决两个问题:1、将相对坐标转换为绝对坐标;2、对模型进行位移、旋转和缩放;

目的可以概括为在”虚拟世界中“放置一个模型。

Unity中的Transform就是干这件事情,如图:

View(Camera) transformation

将世界坐标变换到摄像机坐标。先将相机平移到坐标原点,然后将相机的视角方向变换到(0,0,-1),视角变换的原理是向量空间的基底变换。

Projection transformation

首先澄清一个误区:这里的投影变换不是指的把3D空间的向量投影到平面上,而是一种对三维空间顶点的线性变换,类似于向量a在向量b上的投影,结果为一个与向量b同方向向量。投影变换指的是将视景体(view volume)里的顶点变换到一个规则观察体(canonical view volume)

  • 正交投影(cuboid to “canonical” cube [-1, 1]^3 )

    将视觉立方体里面的物体投影到单位立方里里去(下面左图到右图)

  • 立方体通常这样表示:[l,r]X[b,t]X[f,n],即xyz表示的是:左右、上下、远近。

  • 通常这几个值是用户设定的,xy取决于视角和渲染比例;z中的远平面f大小取决于渲染距离,很多游戏提供了这个选项给用户调整,来改变画面的精细程度。

然后是translate和scale操作:

 这样操作完,渲染区域内的物体就被放在了CVV里面。

  • 透视投影(frustum to “canonical” cube)

    透视投影与正交投影最大的区别是有“近大远小”的视觉效果,物理会随着离摄像机的距离产生大小变化。

    首先将视椎体(frustum)挤压成视觉立方体,这一步的操作可以用如下P矩阵表示:

    推导过程略,用的是待定系数法,需要找两个在挤压过程中不变的点。这里的“挤压”操作实际上是对距离(f)不同的物体,施加不同的伸缩变换,根据距离调整大小。最终的效果是将视椎变成了orthography view volume。

    然后按照正交投影变换为规则观察体:

    这样就把视椎里的物体变换到了单位立方体内。

    viewport transformation

    视口变换,又称为窗口变换。将规则观察体内的单位图像矩阵映射到屏幕空间的像素矩阵。 它仅取决于输出图像的大小和位置。

实验代码

模型变换

按照要求实现绕z轴旋转,需要现将角度转换为弧度,然后在矩阵中填入正确的数值。

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

    rotation_angle = Degree(rotation_angle);
    model<<cos(rotation_angle), -sin(rotation_angle), 0, 0,
        sin(rotation_angle), cos(rotation_angle), 0, 0,
        0,0,1,0,
        0,0,0,1;

    return model;
}

投影变换

要实现透视投影

Eigen::Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio,
                                      float zNear, float zFar){
    Eigen::Matrix4f projection = Eigen::Matrix4f::Identity();

    float n=-zNear;
    float f=-zFar;
    float t=zNear*tan(Degree(eye_fov/2.0f));
    float r=aspect_ratio*t;

    projection<< n/r, 0, 0, 0,
                 0, n/t, 0, 0,
                 0, 0, (n+f)/(n-f), -2*f*n/(n-f),
                 0, 0, 1, 0;

    return projection;
}

这里要先用视角角度计算view volume的宽高,然后代入正交投影矩阵,程序中先根据几何关系计算出t和r。需要注意的是view volume的中心点在z轴上,所以l+r=0,且t+b=0,只需要考虑边长即可。

需要注意的是输入进来的zNear和zFar都是正的,上面理论部分的推导是基于zFar<zNear<0的,所以要先取反,但这样计算出的三角形和标准答案也不太一样(具体表现在旋转了90度)。

但这样也不影响,因为图形学的实验注重所实现的效果,在这里已经实现了模型变换和投影变换,而结果与标准答案有区别并不重要。

参考资料:

[1] Fundamentals of Computer Graphics 5th Edition.

[2] games101 Lecture

[3] 《GAMES101》作业框架问题详解 - 知乎

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值