这是我生成透视矩阵的代码:
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;
仅显示使用正交透视渲染的正方形!所以显然我的问题是在给定某个乘法顺序的情况下,一次只显示一个方格。
答案 0 :(得分:2)
乘法顺序问题表示存储矩阵中组件的顺序存在问题。
mat * vec
相当于vec * transpose (mat)
换句话说,如果你使用行主矩阵(就GL来说实际上是transpose (mat)
)而不是列主要,你需要颠倒矩阵乘法的顺序。这也适用于复合乘法,你必须反转整个乘法序列。这就是为什么D3D(行主要)和OpenGL(列主要)之间的缩放,旋转和平移顺序是倒退的。
projection * view * model
(OpenGL的)
model * view * projection
(的Direct3D)
OpenGL使用的列主矩阵乘法应从右向左阅读。也就是说,您从对象空间位置(最右侧)开始并转换为剪辑空间(最左侧)。
换句话说,这是转换顶点的正确方法......
gl_Position = ModelViewProjectionMatrix * position;
~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~
clip space object space to clip space obj space