Home Forums GAMES在线课程(现代计算机图形学入门)讨论区 关于透视和视图投影的疑问,以及自己的整体理解是否正确

Viewing 2 reply threads
  • Author
    Posts
    • #2989 Score: 0
      Luckin呀
      Participant
      2 pts

      我的问题比较多,希望老师和助教有时间解决下我的疑惑,辛苦了你们!!peace!!!
      第1个问题:课上老师推导透视投影矩阵的过程中,说了近平面和远平面的z值不变,请问这个是规定的吗?如果是规定的或者约定成俗的,所以说,才能根据这两个特殊值求出透视投影矩阵(否则求不出第三行),然后根据求出来的这个矩阵,导致介于近平面和远平面之间的物体的z值发生变化,对吗?

      第2个问题:课上求出来的视图(view)投影矩阵,是将任意位置的camera移到位置在原点,看向-z轴,向上方向为y轴。老师课上也说了,之所以这样,有很多好处。我想问的是,这个好处是什么?另外就是,我记得用一些图形API(比如OpenGL)写图形学作业的时候,有函数可以将camera的位置不在原点,lookat也不指向-z轴,向上方向不是y,field-of-view的值等这些参数作为输入参数,其内部实现是不是并没有真正的移动camera,而是利用这些参数计算出视图矩阵,然后将其应用到model上(与移动camera,不移动model效果等同)?

      第3个问题:整体的理解,以透视投影为例:先给出model的数据(世界坐标系的坐标?),然后定义camera的一些参数(lookat,up,fov等等),然后将透视投影矩阵应用到model上,变为[-1,1]之间的标准坐标,最终将其进行视口变换(应用视口矩阵)为屏幕坐标系下的坐标,model上加上一些颜色值,最终显示出来,我这样理解的对吗?当然如果camera移动的话,视图矩阵还需要应用到model上?

    • #3000 Score: 0
      左趋趋
      Participant
      4 pts

      兄弟我来回答你一下吧,虽然我不是助教。

      1. 你说的是frustum的远近平面还是说的标准化设备坐标(NDC)的?OpenGL的NDC是从[-1,-1,-1]~[1,1,1], DirectX的NDC是xy从[-1,-1]~[1,1],z是0到1. 而frustum的远近值是你自己设定的,比如说渲染多远,一般是看机器性能来设置的,一般游戏里也有一个条让你拉,选择渲染距离,往往就是调整这个frustum的far plane的值的。

      2. 是的,lookat一共有7个自由度,首先是摄像机的坐标,然后是观察点的坐标,然后是摄像机旋转的方向。输入这7个值(一般是给出摄像机坐标,观察点,以及一个上参考矢量)。 比如OpenGL是这样创建的。

      glm::mat4 view;
      view = glm::lookAt(glm::vec3(0.0f, 0.0f, 3.0f), 
        		   glm::vec3(0.0f, 0.0f, 0.0f), 
        		   glm::vec3(0.0f, 1.0f, 0.0f));

      3. 你对model的理解不是很正确,model矩阵是什么呢,比如有一个箱子,它的坐标有一个local坐标,8个点,大概长这个样子:(点集A)

      [0,0,0]
      [0,1,0]
      [1,0,0]
      [1,1,0]
      [0,0,1]
      [0,1,1]
      [1,0,1]
      [1,1,1]

      但是你这样的坐标是针对这个model内部来说,local的,你把它放在一个大的world里,比如不旋转,只是把箱子平移了[2,2,0], 那么你的箱子的这8个点在world里就变成了:(点集B)

      [2,2,0]
      [2,3,0]
      [3,2,0]
      [3,3,0]
      [2,2,1]
      [2,3,1]
      [3,2,1]
      [3,3,1]

      这个从点集A到点集B的变换就是model矩阵。

      至于你说的model上加上一些颜色值,最终显示出来,这本质上也没错,就像以下图片的第五步一样,非常的简单。
      draw  hourse

      • #3011 Score: 0
        Lingqi Yan
        Keymaster
        26 pts

        我补充一下两位同学的回答。
        关于问题1,我确实是规定了近远平面在 frustum->cuboid 这个挤压操作前后 z 值不变,这样限制了只有一种挤压的方法。
        关于问题2,由于相对运动的存在,相机和所有物体都同时移动就等于都没有移动。把相机放在规定位置是为了后面做投影变换方便。而在 OpenGL 等等 API 里面也确实是这样做的,只是隐藏在 OpenGL 自己的实现内部你没有发现而已。如果你自己写 vertex shader 就会发现需要对顶点应用 MVP 矩阵。这个 V 就是视图变换。
        关于问题3,“model上加上一些颜色值” 我们会花好几节课来讲解怎么加。这个确实和上面这位同学回答的第五步一样简单 🙂

        • #3014 Score: 0
          Luckin呀
          Participant
          2 pts

          感谢老师,我懂了!

        • #3078 Score: 0
          sublimation
          Participant
          3 pts

          闫老师好,我想再请教一下您,关于问题1.
          为什么一定要去确定一个frustum,然后再挤压内部所有的点到cuboid。再做正交变换。
          如果我想直接对内部每一个点分别做透视投影,直接到成像平面,这样可以吗?这样不是也保证了z的相对大小不变?

      • #3013 Score: 0
        Luckin呀
        Participant
        2 pts

        谢谢这位同学,你说的物体先有local坐标是对的,是我忘记了,然后在应用model矩阵。感谢!!!!!!!

    • #3005 Score: 0
      Angus
      Participant
      23 pts

      不是助教,人在宿舍,刚下床铺

      问题1:推荐同学再听一遍老师的推导。你迷惑的这里是求透视投影的第一步,即把frustum挤压成为cuboid。挤压的具体操作是将远平面四个点在x-y平面内移动来形成一个cuboid,在这个过程中显然近平面和远平面的z值是不变的,我觉得应该不需要去约定。

      问题2.1:这个好处具体是什么我还真说不上来,等助教大佬来解答吧。只是如果相机不这样假设,后续的视口变换等我推导起来会感觉有点费劲。

      问题2.2:Camera 一开始确实可以不在原点,可以随意设置,闫老师的讲解角度与OpenGL等并不冲突,你可以再看一下相应的那几页PPT。【第一步】就像 lookat() 函数一样,根据你的喜好设置 Camera 位置,角度等。【第二步】把 Camera 和 Objects 看作一个整体(整个世界),计算如何把 Camera 移动到origin,up at y,look at -z(即求 View Transformation 矩阵),再把这个矩阵应用到这个整体上。我相信OpenGL 背后应该也是在做这样的工作,如果我理解错了,还请助教同学指正一下。

      问题3:我觉得你整体理解的是不错的,就是 View Transformation 那里感觉有些不太熟悉,看看我问题2.1的解答,且最好还是多看两遍老师的讲解。

      • #3015 Score: 0
        Luckin呀
        Participant
        2 pts

        谢谢兄弟,你回答的问题1,其实把frustum挤压成cuboid,其实在没有计算出透视投影矩阵的时候,我一直认为frustum之间的z值都是不变的,但是根据远和近平面z值不变而求出的矩阵,再去应用到frustum内的物体,这个z值明显就变了,所以我觉得应该是规定的。

        • #3016 Score: 0
          Angus
          Participant
          23 pts

          是的。听闫老师那么一解释,我觉得这就其实是一个「先有鸡还是先有蛋」的问题:当约定好一种挤压方式后,远近平面的值是不变的。同时也可以说当约定好远近平面的z值不变后,挤压方式也就剩了一种。

Viewing 2 reply threads
  • You must be logged in to reply to this topic.