我正在尝试将正交投影用于GUI渲染。当我仅使用常规变换矩阵绘制网格时,我会得到期望的结果,但是当我使用正交投影时,我什么也没得到。我的透视投影效果也很好。我的正交矩阵:
public Matrix4f initOrthographic(float left, float right, float bottom, float top, float near, float far)
{
m[0][0] = 2.0f / (right - left); m[0][1] = 0; m[0][2] = 0; m[0][3] = (left + right) / (left - right);
m[1][0] = 0; m[1][1] = 2.0f / (top - bottom); m[1][2] = 0; m[1][3] = (bottom + top) / (bottom - top);
m[2][0] = 0; m[2][1] = 0; m[2][2] = 2.0f / (near - far); m[2][3] = (far + near) / (far - near);
m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1;
return this;
}
我无法为我的生活找出错误所在。我将这个矩阵乘以常规变换,然后将该矩阵乘以着色器中的顶点位置。有任何想法吗?如果需要,我可以发布更多代码/信息。
我想我才发现问题。我的顶部为0,底部为720,当我将这些值翻转为720顶部和0底部时,效果很好。唯一的事情是我希望左上角为(0,0)。有什么办法可以做到这一点,还是我的左下角是(0,0)?
最佳答案
我的正交矩阵看起来与您的完全不同:
2.0f / (right - left) 0 0 0
0 2.0f / (top - bottom) 0 0
0 0 2.0f / (zFar - zNear) 0
-(right + left) / (right - left) -(top + bottom) / (top - bottom) -(zFar + zNear) / (zFar - zNear) 1
重要的是如何存储值。如果将单个float数组用于矩阵,则将其存储为:
float orthoMat[] =
{
2.0f / (right - left),
0,
0,
0,
0,
2.0f / (top - bottom),
0,
0,
0,
0,
2.0f / (zFar - zNear),
0,
-(right + left) / (right - left),
-(top + bottom) / (top - bottom),
-(zFar + zNear) / (zFar - zNear),
1
};
这是OpenGL期望您传递到着色器的布局。这是专栏文章的主要约定。 DirectX使用行优先约定。因此,基本上我的矩阵可以从左到右,下一行,从左到右读取,而您的矩阵应该从上到下,下一列,从上到下读取。如果转置矩阵,您得到的矩阵几乎与我相同。但是,即使在转置时,我们的矩阵也存在一些差异:
在你的代码中
- m[2][2] should be 2.0f / (zFar - zNear)
- m[0][3], m[1][3] and m[2][3] should be negative
只要解决了矩阵的这些问题并确保将矩阵传递到着色器时元素的正确顺序,您仍然可以使用矩阵实现。只要记住元素12、13和14会存储翻译。如果您对所有这些主要行/主要列的东西都感到困惑,请阅读this简短的文章,对它进行很好的解释。我强烈推荐它。