可以将投影转换视为控制相机的内部;这类似于为相机选择镜头。 这是三种转换类型中最复杂的。 投影转换的这一讨论组织为以下主题。
投影矩阵通常是缩放和透视投影。 投影转换将查看 frustum 转换为立方体形状。 由于视锥的近端小于远端,因此它具有扩展靠近相机的对象的效果:这是如何将透视应用于场景。
在 观看 frustum中,相机与观看转换空间的原点之间的距离任意定义为 D,因此投影矩阵如下图所示。
投影矩阵插图
查看矩阵通过向 z 方向翻译 -D 将相机转换为原点。翻译矩阵如下图所示。
翻译矩阵插图
将转换矩阵乘以投影矩阵(T*P),可提供复合投影矩阵,如下图所示。
复合投影矩阵插图
透视转换将查看 frustum 转换为新的坐标空间。 请注意,frustum 变为小熊体,并且原点从场景右上角移动到中心,如下图所示。
在透视转换中,x 方向和 y 方向的限制 -1 和 1。 z 方向的限制是前平面的 0,后平面为 1。
此矩阵基于从相机到接近剪裁平面的指定距离转换和缩放对象,但它不考虑视场(fov),并且它为距离中的对象生成的 z 值可能几乎相同,使得深度比较变得困难。 以下矩阵解决了这些问题,并调整顶点以考虑视区纵横比,使其成为透视投影的一个不错的选择。
透视投影插图
在此矩阵中,Zn 是接近剪裁平面的 z 值。 变量 w、h 和 Q 具有以下含义。 请注意,fovw 和 fovk 以弧度表示视区的水平和垂直视图字段。
变量的
对于应用程序,使用视场角度定义 x 和 y 缩放系数可能不如使用视口的水平和垂直尺寸(在相机空间中)那么方便。 随着数学的计算结果,w 和 h 的以下两个公式使用视区的尺寸,并且等效于前面的公式。
w 和 h 变量的
在这些公式中,Zn 表示接近剪裁平面的位置,Vw 和 Vh 变量表示视区的宽度和高度(以相机空间为单位)。
对于C++应用程序,这两个维度直接对应于 D3DVIEWPORT9 结构的 Width 和 Height 成员。
无论你决定使用哪种公式,请务必将 Zn 设置为尽可能大的一个值,因为与相机非常接近的 z 值不会变化很大。 这使得使用 16 位 z 缓冲区进行深度比较有点复杂。
与世界和视图转换一样,调用 IDirect3DDevice9::SetTransform 方法来设置投影转换。
设置投影矩阵
以下 ProjectionMatrix 示例函数设置前后剪裁平面以及视图角度的水平和垂直字段。 视图字段应小于 pi 弧度。
D3DXMATRIX
ProjectionMatrix(const float near_plane, // Distance to near clipping
// plane
const float far_plane, // Distance to far clipping
// plane
const float fov_horiz, // Horizontal field of view
// angle, in radians
const float fov_vert) // Vertical field of view
// angle, in radians
{
float h, w, Q;
w = (float)1/tan(fov_horiz*0.5); // 1/tan(x) == cot(x)
h = (float)1/tan(fov_vert*0.5); // 1/tan(x) == cot(x)
Q = far_plane/(far_plane - near_plane);
D3DXMATRIX ret;
ZeroMemory(&ret, sizeof(ret));
ret(0, 0) = w;
ret(1, 1) = h;
ret(2, 2) = Q;
ret(3, 2) = -Q*near_plane;
ret(2, 3) = 1;
return ret;
} // End of ProjectionMatrix
创建矩阵后,使用 IDirect3DDevice9::SetTransform 指定D3DTS_PROJECTION对其进行设置。
D3DX 实用工具库提供以下函数来帮助设置投影矩阵。
- D3DXMatrixPerspectiveLH
- D3DXMatrixPerspectiveRH
- D3DXMatrixPerspectiveFovLH
- D3DXMatrixPerspectiveFovRH
- D3DXMatrixPerspectiveOffCenterLH
- D3DXMatrixPerspectiveOffCenterRH
W 友好投影矩阵
Direct3D 可以使用由世界、视图和投影矩阵转换的顶点的 w 分量来执行深度缓冲区或雾效果的基于深度的计算。 此类计算要求投影矩阵规范化 w 等效于 world-space z。 简言之,如果投影矩阵包含非 1 的 (3,4) 系数,则必须按 (3,4) 系数的反转来缩放所有系数,才能生成正确的矩阵。 如果未提供兼容的矩阵,则无法正确应用雾效果和深度缓冲。
下图显示了一个不相容的投影矩阵,并缩放了相同的矩阵,以便启用眼睛相对雾。
在前面的矩阵中,所有变量都假定为非零。 有关眼睛相对雾的详细信息,请参阅 Eye-Relative 与基于 Z 的深度。 有关基于 w 的深度缓冲的信息,请参阅 深度缓冲区(Direct3D 9)。
Direct3D 在其基于 w 的深度计算中使用当前设置的投影矩阵。 因此,应用程序必须设置合规的投影矩阵才能接收所需的基于 w 的功能,即使它们不使用 Direct3D 进行转换也是如此。
相关主题