【发布时间】:2013-12-05 18:34:00
【问题描述】:
这是我生成透视矩阵的代码:
public static Matrix4f orthographicMatrix(float left, float right, float bot,
float top, float far, float near) {
// construct and return matrix
Matrix4f mat = new Matrix4f();
mat.m00 = 2 / (right - left);
mat.m11 = 2 / (top - bot);
mat.m22 = -2 / (far - near);
mat.m30 = -((right + left) / (right - left));
mat.m31 = -((top + bot) / (top - bot));
mat.m32 = -((far + near) / (far - near));
mat.m33 = 1;
return mat;
}
public static Matrix4f projectionMatrix(float fovY, float aspect,
float near, float far) {
// compute values
float yScale = (float) ((float) 1 / Math.tan(Math.toRadians(fovY / 2)));
float xScale = yScale / aspect;
float zDistn = near - far;
// construct and return matrix
Matrix4f mat = new Matrix4f();
mat.m00 = xScale;
mat.m11 = yScale;
mat.m22 = far / zDistn;
mat.m23 = (near * far) / zDistn;
mat.m32 = -1;
mat.m33 = 0;
return mat;
}
在我的程序中,首先以正交透视渲染一个正方形,然后以投影透视渲染一个正方形。
但这是我的问题 - 当我的着色器按此顺序执行乘法时:
gl_Position = mvp * vec4(vPos.xyz, 1);
仅显示使用投影透视渲染的正方形。但是当按这个顺序进行乘法运算时:
gl_Position = vec4(vPos.xyz, 1) * mvp;
仅显示使用正交透视渲染的正方形!所以很明显我的问题是在给定乘法顺序的情况下一次只显示一个正方形。
【问题讨论】:
-
乘法顺序问题表明您在矩阵中存储组件的顺序存在问题。
mat * vec等效于vec * transpose (mat),换句话说,如果您使用的是行优先矩阵(就 GL 而言实际上是transpose (mat))而不是列优先矩阵,您需要反转矩阵的顺序乘法。这也适用于复合乘法,您必须反转整个乘法序列,这就是为什么 D3D 和 OpenGL 之间的缩放、旋转和平移顺序是向后的。 -
@AndonM.Coleman 解决了它 - 我在投影矩阵构造中交换了“xy”值并使用了
gl_Position = vec4(vPos.xyz, 1) * mvp;。非常感谢 - 把它变成一个答案,我会接受! -
@AndonM.Coleman 你提出 OpenGL 和 D3D 之间的差异可以解释为什么会发生这种情况 - 我从 D3D 教程中得到投影矩阵代码,从 OpenGL 中得到正交代码。
-
@AndonM.Coleman 哎呀,这是我将代码复制到问题中的错误。我确实在我的实际代码中将 m33 设置为 1。
-
@AndonM.Coleman 我还没有实现模型视图部分,所以我所做的就是将透视矩阵传递给 MVP。