视口变换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

原文地址:https://www.cnblogs.com/wbaoqing/p/5433193.html