zoukankan      html  css  js  c++  java
  • 视口变换ViewPort transformation 和空间拾取

    经过投影矩阵变换的顶点,再经过透视除法变换规范的NDC空间,这里的XY顶点都变换都近裁剪面了。

    3D中东西要经过最后一步才能变成真正的屏幕坐标系中。这步叫ViewPort Transformation

    ViewPort Transformation

    我们先看下屏幕的坐标系什么样子

    这个是windows下情况,屏幕X轴 正方向朝右 Y轴正方向朝下。原点在屏幕的左上角

    Viewport 矩阵我们分两步求得

    The viewport transformation will be represented by a 4x4 matrix. It encapsulates 2 stages

    1. a scaling to the shape of the viewport
    2. a transformation to the position of the viewport

    第一步,放大的屏幕ViewPort大小,就是屏幕大小。

    第二部,移动点到ViewPort,这步是因为 3D空间原点在中心。 以windows为例屏幕原点在左上角。

    第一步

    x在[-1,1]之间, 变换到屏幕[0~width] width屏幕宽分辨率

    X轴在CVV中方向一样,只是放大了 width/2

    y在[-1,1]之间, 变换到屏幕[0~height] height屏幕高分辨率

    同样放大了 height/2 ,但是屏幕的Y轴方向和NDC中间相反,那么取反 -height/2

    Z轴,我们在屏幕中先不关心,因为实际的值我们是写入Zbuff中,跟屏幕显示无关。

    那么我们就构造缩放矩阵

    第二步

    消除屏幕坐标和NDC坐标系原点误差。

    构造矩阵

    x,y表示屏幕左下角的起点。一般我们是设置为0,0

    那么想过矩阵相乘得到我们最终的ViewPort矩阵

    Z轴部分我们不是很关心。也可以自己推到,屏幕空间Z的范围[Zmin Zmax]

    ViewPort Transformation 是在管线中完成的,我们只要设置ViewPort大小,其他不用心。

    但是有个地方要设计到。那么就是空间的拾取

    我们把屏幕上一个点,变换3D空间中一个点。再和Camera的点,构成一条射线查询碰撞。

    变换过程:

    通过上面的矩阵 我们得到公式:

    一般来说我们的X,y都是 0 0的,变换公式

    这样我们有了屏幕的坐标就可以求出的NDC中xy坐标,但是一般我们能用都是世界坐标系或者摄像机坐标系的坐标。

    这样我们变换回摄像机坐标系。我们可以承受 投影矩阵的逆矩阵,但是有简单的方法

    投影矩阵

    这里投影的X轴的基向量是2N/(right-left),那么投影矩阵对于X只是做了2N/(right-left)的缩放,那么逆操作成上他缩放值倒数(right-left)/2N

    那么最终的矩阵公式

    那么在摄像机坐标系在,可以得到一个点

    因为摄像机坐标系中,摄像机点是原点。那么上面就是我们要的查询射线向量了。

    如果要在世界坐标系中,只有把向量乘上相机矩阵的逆矩阵,摄像机的逆矩阵也特殊,看View矩阵那章。

     参考:http://glasnost.itcarlow.ie/~powerk/GeneralGraphicsNotes/projection/viewport_transformation.html

  • 相关阅读:
    Linux Shell编程入门
    vim 文件在linux不换行,只显示^M解决办法
    服务器高性能程序 磁盘I/O篇
    车牌识别_转自别人的博客
    ubuntu网络简单设置
    C++设计模式(转载)
    结构算法之道
    C++设计模式工厂方法
    二叉树的深度优先遍历、广度优先遍历和非递归遍历
    iptables
  • 原文地址:https://www.cnblogs.com/wbaoqing/p/5433193.html
Copyright © 2011-2022 走看看