GAMES101 作业1

这篇具有很好参考价值的文章主要介绍了GAMES101 作业1。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

作业pa1对应的是GAMES101课程Lecture02到Lecture04这三节课的内容,主要是用于巩固空间中的物体投影到相机平面的整个过程。
说在前面,本文是在左手系下进行讨论的。

1、从main函数看投影

粗略地看一遍我们可以知晓main函数的流程:
①设定一些基本的初始参数并初始化源代码给出的光栅化类rasterizer
while循环:
 ②通过set_model设定被投影物体的位姿变换
 ☂通过ser_view设定相机系的位姿变换
 ④通过set_projection设定投影关系
 ⑤绘制显示投影结果
其中②☂④构成整个投影的过程。初学的小伙伴可能不理解这几个位姿变换的意义是什么,博主学过SLAM有一些三维旋转变换的基础,在我看来——

被投影物体的位姿变换

②中的model_matrix表示被投影的物体在世界坐标系下(即常说的xyz轴)的旋转和平移变换,他表示物体相对于我们最初给的位置(在本例中为三角形的三个顶点),经过了怎么样的运动:
m o d e l m a t r i x ∗ 物体原始坐标—— > 运动后的新坐标 modelmatrix*物体原始坐标——>运动后的新坐标 modelmatrix物体原始坐标——>运动后的新坐标

相机系的位姿变换

☂中的view_matrix表示相机所观察的角度,其往往包含:相机所在位置t+相机朝向的方向R,R和t是相对于世界坐标系而言的,即将世界坐标系做旋转和平移变化R、t后可变换成以相机建立的坐标系。这样可以将被投影物体的坐标转换到相机所建立的坐标系下:
M a t r i x ( R , t ) ∗ 世界坐标系—— > 相机坐标系 M a t r i x ( R − 1 , − t ) ∗ 运动后的新坐标 ( 世界系 ) —— > 运动后的新坐标 ( 相机系 ) \begin{aligned} & Matrix(R,t)*世界坐标系——>相机坐标系 \\ & Matrix(R^{-1}, -t)*运动后的新坐标(世界系)——>运动后的新坐标(相机系) \end{aligned} Matrix(R,t)世界坐标系——>相机坐标系Matrix(R1,t)运动后的新坐标(世界系)——>运动后的新坐标(相机系)
注:这里为什么是 R − 1 R^{-1} R1 − t -t t是因为坐标变换坐标系变换其实是相反的,本质上是相对运动的关系。就像你静止不动,一个人离你而去,如果假设离去的人是静止的,那么就变成了你在以相反的方向离开那个人,在坐标变换中同理。

投影关系

这里就是Games101课程中讲的核心内容啦。主要就是正交投影(Othographic Projection)和透视投影(Perspective Projection)两部分。
需要先介绍几个重要的形状,从左到右分别表示1、透视投影前的视角形状;2、透视投影后,正交投影前的视角形状;3、正交投影后的视角形状。
从这三张图可以很好地理解初学时课上可能存在的许多疑惑点,比如:
远近平面是什么?
图1中的粉色方形面为远平面,蓝色方形面为近平面,远近平面通过绿色的投影线包裹起来的部分会被投影到我们最后的屏幕上。图2中的红色方形面为透视投影后的远平面。
透视投影矩阵推导时两个用于计算第三行的等式关系是怎么来的?
观察图1图2就可以知道了。透视投影前后蓝色的近平面是不变的,此为等式1;粉色远平面投影后变成红色远平面,是一个挤压的过程,但是前后的中心点即粉色点和红色点是一样的,此为等式2。
GAMES101 作业1

透视投影

即图1到图2的变换过程/变换矩阵,可以用下图表示。表示从粉红色所包裹的空间压缩为红色大红色包裹的空间这一过程。GAMES101 作业1用矩阵可表示为下式,最左边的4*4矩阵 M p e r s p M_{persp} Mpersp为透视投影阵: M p e r s p ∗ [ x y z 1 ] = [ n 0 0 0 0 n 0 0 0 0 n + f − n ∗ f 0 0 1 0 ] ∗ [ x y z 1 ] = [ n x n y u n k o n w z ] M_{persp}* \begin{bmatrix} x \\ y \\ z \\ 1 \\ \end{bmatrix}= \begin{bmatrix} n & 0 & 0 & 0 \\ 0 & n & 0 & 0 \\ 0 & 0 & n+f & -n*f \\ 0 & 0 & 1 & 0 \\ \end{bmatrix}* \begin{bmatrix} x \\ y \\ z \\ 1 \\ \end{bmatrix}= \begin{bmatrix} nx \\ ny \\ unkonw \\ z \\ \end{bmatrix} Mpersp xyz1 = n0000n0000n+f100nf0 xyz1 = nxnyunkonwz
推导这个矩阵的条件有3个
条件①观察透视投影图可以知道任一点(x,y,z)在投影后的坐标 x ′ x^{'} x y ′ y^{'} y(z无法确定)都可以通过投影关系在近平面上确定为 x ′ = n z ∗ x x^{'}=\frac{n}{z}*x x=znx y ′ = n z ∗ y y^{'}=\frac{n}{z}*y y=zny,因为一条绿色投影线上的点在投影后的xy坐标就是投影线和近平面的交点的xy坐标
则可写出等式:
1 z ∗ M p e r s p ∗ [ x y z 1 ] = [ n x z n y z u n k n o w 1 ] M p e r s p ∗ [ x y z 1 ] = [ n x n y s t i l l u n k n o w z ] \frac{1}{z}*M_{persp}* \begin{bmatrix} x \\ y \\ z \\ 1 \\ \end{bmatrix}=\begin{bmatrix} \frac{nx}{z} \\ \frac{ny}{z} \\ unknow \\ 1 \\ \end{bmatrix} \qquad M_{persp}* \begin{bmatrix} x \\ y \\ z \\ 1 \\ \end{bmatrix}=\begin{bmatrix} nx \\ ny \\ stillunknow \\ z \\ \end{bmatrix} z1Mpersp xyz1 = znxznyunknow1 Mpersp xyz1 = nxnystillunknowz
GAMES101 作业1
上式可推导出矩阵的1、2、4行。

此时假设仍然未知的第三行为 [ X Y A B ] \begin{bmatrix} X & Y & A & B\end{bmatrix} [XYAB]
条件②所有近平面上的点是不变的,原因上面已经解释。
M p e r s p ∗ [ x y n 1 ] n e a r = [ n x n y n 2 n ] M_{persp}* \begin{bmatrix} x \\ y \\ n \\ 1 \\ \end{bmatrix}_{near}=\begin{bmatrix} nx \\ ny \\ n^{2} \\ n \\ \end{bmatrix} Mpersp xyn1 near= nxnyn2n
上式可以推出 X = Y = 0 X=Y=0 X=Y=0,因为式子对任意 [ x y n ] \begin{bmatrix} x \\ y \\ n\end{bmatrix} xyn 都成立,还可以推出 A n + B = n 2 An+B=n^2 An+B=n2
条件☂远平面中点是不变的,原因上面已经解释。
M p e r s p ∗ [ 0 0 f 1 ] = [ 0 0 f 2 f ] M_{persp}* \begin{bmatrix} 0 \\ 0 \\ f \\ 1 \\ \end{bmatrix}=\begin{bmatrix} 0 \\ 0 \\ f^{2} \\ f \\ \end{bmatrix} Mpersp 00f1 = 00f2f
上式可以推出 A f + B = f 2 Af+B=f^2 Af+B=f2
综上,可以解的 A = n + f A=n+f A=n+f B = − n ∗ f B=-n*f B=nf

正交投影

即图2到图3的变换过程/变换矩阵,可以用下图表示。表示从大红色表示的空间压缩成白色表示的空间的过程。
GAMES101 作业1
用矩阵可表示为下式,最左边的4*4矩阵 M o r t h o M_{ortho} Mortho为正交投影阵,可以拆分为尺度变换 M s c a l e M_{scale} Mscale和平移变换 M t r a n s M_{trans} Mtrans部分:
M o r t h o [ x y z 1 ] = M s c a l e ∗ M t r a n s [ x y z 1 ] = [ 2 r − l 0 0 0 0 2 t − b 0 0 0 0 2 n − f 0 0 0 0 1 ] ∗ [ 1 0 0 − r + l 2 0 1 0 − t + b 2 0 0 1 − n + f 2 0 0 0 1 ] [ x y z 1 ] M_{ortho} \begin{bmatrix} x \\ y \\ z \\ 1 \\ \end{bmatrix}= M_{scale}*M_{trans} \begin{bmatrix} x \\ y \\ z \\ 1 \\ \end{bmatrix}= \begin{bmatrix} \frac{2}{r-l} & 0 & 0 & 0 \\ 0 & \frac{2}{t-b} & 0 & 0 \\ 0 & 0 & \frac{2}{n-f} & 0 \\ 0 & 0 & 0 & 1 \\ \end{bmatrix}* \begin{bmatrix} 1 & 0 & 0 & -\frac{r+l}{2} \\ 0 & 1 & 0 & -\frac{t+b}{2} \\ 0 & 0 & 1 & -\frac{n+f}{2} \\ 0 & 0 & 0 & 1 \\ \end{bmatrix} \begin{bmatrix} x \\ y \\ z \\ 1 \\ \end{bmatrix} Mortho xyz1 =MscaleMtrans xyz1 = rl20000tb20000nf200001 1000010000102r+l2t+b2n+f1 xyz1
这个就不解释了,知道前后(n,f)左右(l,r)上下(tb)可以很快写出上面的式子,注意注意注意 M s c a l e M_{scale} Mscale中第三行第三个为 n − f n-f nf,因为是右手系,n的值是比f大的n的值是比f大的n的值是比f大的
至此,设计到的知识基本讲完了,接下来看代码部分。

2、从代码看投影

get_model_matrix

在这里实现物体的位姿变换,作业中要求的代码如下,即按照角度构建一个简单的旋转矩阵

Eigen::Matrix4f get_model_matrix(float rotation_angle)
{
    Eigen::Matrix4f m;
    float angle = rotation_angle/180.0f * PI;
    float c = cosf(angle),s = sinf(angle);
    m << c, -s, 0, 0,
        s, c, 0, 0,
        0, 0, 1, 0,
        0, 0, 0, 1;
    return m;
}

如果按照提高部分实现任意轴旋转变化如下,get_rotation中利用罗德里格斯公式实现轴角到旋转矩阵的变化,距离表现形式有两种,两个return的结果是一样的

Eigen::Matrix4f get_rotation(Vector3f axis, float angle)
{
    float a = angle*PI/180.0;
    float cosa = cosf(a), sina = sinf(a);
    Eigen::Matrix3f  I = Eigen::Matrix3f::Identity();
    axis = axis.normalized();
    Eigen::Matrix3f nhat;
    nhat << 0, -axis.z(), axis.y(),
                axis.z(), 0, -axis.x(),
                -axis.y(), axis.x(), 0;
    // 两种罗德里格斯公式
    return toMatrix4f(I + (nhat*nhat)*(1-cosa) + sina*nhat);
    // return toMatrix4f(cosa*I + (1-cosa)*(axis*axis.transpose()) + sina*nhat);
}

Eigen::Matrix4f get_model_matrix(float rotation_angle)
{
    Eigen::Matrix4f m;
    Vector3f axis{1, 1, 1};		// 旋转轴
    Eigen::Matrix4f t;				// 位移矩阵,左右1列的三个0改成其他值表示三个方向的位移
    t << 1, 0, 0, 0,
            0, 1, 0, 0,
            0, 0, 1, 0,
            0, 0, 0, 1;
    m = get_rotation(axis, rotation_angle);
    return m*t;
}

get_view_matrix

源代码中已经给出,看一遍就可以知道在构建位姿变换矩阵view,正确理解上面将的“相机系的位姿变换”部分应该对其中的一些负号变换就不奇怪了。

get_projection_matrix

在上面我们说到正交矩阵 M o r t h o M_{ortho} Mortho的计算需要知道前后(n,f)左右(l,r)上下(tb),但是我们目前还不知道上下左右是多少。我们可以通过垂直的可视角度fovY和长宽比aspect以及近平面距离n算出前后(n,f)左右(l,r)上下(tb),计算方式如图。这下我们就可以完全表示出所有矩阵啦。
GAMES101 作业1
get_projection_matrix函数的传入:垂直的可视角度fovY、长宽比aspect、远近平面距离zNear、zFar

Eigen::Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio,
                                      float zNear, float zFar)
{
    Eigen::Matrix4f Mpersp, Mscale, Mtrans, MP2O;
    float fovY = eye_fov*PI/180.0;
    float t = abs(zNear)*tanf(fovY/2);
    float r = t*aspect_ratio;

    Mscale << 1/r, 0, 0, 0,
                            0, 1/t, 0, 0,
                            0, 0, 2/(zNear-zFar), 0,
                            0, 0, 0, 1;
    Mtrans << 1, 0, 0, 0,
                        0, 1, 0, 0,
                        0, 0, 1, -(zNear+zFar)/2,
                        0, 0, 0, 1;
    MP2O << zNear, 0, 0, 0,
                    0, zNear, 0, 0,
                    0, 0, zNear+zFar, -zNear*zFar,
                    0, 0, 1, 0;
    Mpersp = Mscale*Mtrans*MP2O;

    return Mpersp; 
}

由于本例中情况比较特殊,上下左右都为对称情况,所以 M s c a l e M_{scale} Mscale中的 2 2 − l \frac{2}{2-l} 2l2 2 t − b \frac{2}{t-b} tb2简化成了 1 r \frac{1}{r} r1 1 t \frac{1}{t} t1 M t r a n s M_{trans} Mtrans中的 − r + l 2 -\frac{r+l}{2} 2r+l − t + b 2 -\frac{t+b}{2} 2t+b简化成了0。
当然,不用分成三个矩阵,直接将结果计算好再码成代码也是可以的

Eigen::Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio,
                                      float zNear, float zFar)
{
    Eigen::Matrix4f Mpersp;
    float fovY = eye_fov*PI/180.0;
    float cota = 1.f/tanf(fovY/2);
    float zD = zNear-zFar;
    Mpersp << -cota/aspect_ratio, 0, 0, 0,
                        0, -cota, 0, 0,
                        0, 0, (zNear+zFar)/zD, -2*zNear*zFar/zD,
                        0, 0, 1, 0;
 }

按AD旋转

在网上找了一份C++中检测键盘输入的代码,在main函数最后加上实现,其中kbhit()为检测键盘输入的函数,有键入是返回1,对具体感兴趣的可以看一下我的源代码

        if(kbhit()){
            char action = getchar();
            if(action=='A') angle += 3;
            else if(action=='D')    angle -=3;
        }

3、总结

本文讲了GAMES101作业1中涉及的知识和代码实现。源码可以去我的Github查看,为pa1对应的部分,感谢阅读!文章来源地址https://www.toymoban.com/news/detail-487335.html

到了这里,关于GAMES101 作业1的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • GAMES101 作业0

    课上提供的环境是Linux, 还需要安装Vitrual Box和创建虚拟机,省事就直接在Windows系统下Visual Studio下操作了。 简单的环境配置: 下载Eigen 的库 在工程属性中添加目录: 2处地方 注意: 刚添加完后,我新建main.cpp后, 引入头文件 路径也没有设置错啊,但是就是找不到。 直到看

    2024年02月16日
    浏览(41)
  • GAMES101作业2

    在屏幕上画出一个实心三角形, 换言之,栅格化一个三角形。上一次作业中,在视口变化之后,我们调用了函数 rasterize_wireframe(const Triangle t)。但这一次,你需要自己填写并调用 函数 rasterize_triangle(const Triangle t)。 该函数的内部工作流程如下: 创建三角形的 2 维 bounding box。

    2024年02月16日
    浏览(42)
  • GAMES101:作业7记录

    在之前的练习中,我们实现了 Whitted-Style Ray Tracing 算法,并且用 BVH等加速结构对于求交过程进行了加速。在本次实验中,我们将在上一次实验的基础上实现完整的 Path Tracing 算法。至此,我们已经来到了光线追踪版块的最后一节内容。 请认真阅读本文档,按照本文档指示的流程完成

    2024年02月01日
    浏览(46)
  • Games101作业5解读

    在scene中加入两个球一个地板和两个点光源 在Render中我们从eye_pos向屏幕打出一根一根的ray与场景相交 第一步先与场景的求交,如果光线打到了物体,就继续判断打到的物体的材质,根据不同的材质进行不同的处理,这里重点说下REFLECTION和default 在REFLECTION中,这一段代码有点问

    2024年02月09日
    浏览(32)
  • 【GAMES101】作业1(提高)与框架理解

    本次作业的任务是填写一个旋转矩阵和一个透视投影矩阵。给定三维下三个点 v0(2.0, 0.0, −2.0), v1(0.0, 2.0, −2.0), v2(−2.0, 0.0, −2.0), 你需要将这三个点的坐标变换为屏幕坐标并在屏幕上绘制出对应的线框三角形 (在代码框架中,我们已经提供了 draw_triangle 函数,所以你只需要去

    2023年04月12日
    浏览(42)
  • 【GAMES101】作业5 简单光线追踪与代码流程理解

    在这部分的课程中,我们将专注于使用光线追踪来渲染图像。在光线追踪中最重要的操作之一就是找到光线与物体的交点。一旦找到光线与物体的交点,就可以执行着色并返回像素颜色。在这次作业中,我们需要实现两个部分:光线的生成和光线与三角的相交。本次代码框架

    2024年02月06日
    浏览(38)
  • 【GAMES101】作业7(提高)路径追踪 多线程、Microfacet(全镜面反射)、抗锯齿

    在之前的练习中,我们实现了 Whitted-Style Ray Tracing 算法,并且用 BVH等加速结构对于求交过程进行了加速。在本次实验中,我们将在上一次实验的基础上实现完整的 Path Tracing 算法。至此,我们已经来到了光线追踪版块的最后一节内容。 相比上一次实验,本次实验对框架的修改

    2023年04月08日
    浏览(43)
  • NLP作业02:课程设计报告

    作业头 这个作业属于哪个课程 自然语言处理 这个作业要求在哪里 NLP作业02:课程设计报告 我在这个课程的目标 实现基于Seq2Seq注意力机制的聊天机器人 这个作业在哪个具体方面帮助我实现目标 问题的提出,资料的查找 参考文献 1.简说Seq2Seq原理以及实现 2.序列到序列学习

    2024年02月09日
    浏览(43)
  • games101-3 BRDF101

    本文基于知乎Maple对brdf的文章,在此基础又收集了一些其它来源的关于brdf的文章,希望能够完全理解记忆相关知识 关于Jakub Boksansky的文章,看的过程中又去搜集了很多其它文章来理解,发现已经超出了我目前的知识厚度,因此只会简单的翻译一下我能理解的部分,感兴趣的

    2024年04月25日
    浏览(32)
  • 【GAMES101】03 Transformation

    1、Scale(缩放)  2、Reflection Matrix(反射矩阵)  3、Shear Matrix(剪切矩阵)  4、Rotation Matrix(旋转矩阵) 推导过程:     5、Translation Matrix(平移矩阵) 平移操作不属于线性变换的范畴。 引入 齐次坐标 ,通过增加维度,来将平移坐标写成同样的矩阵形式。 很显然,平移无

    2024年02月02日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包