OpenGL透视投影矩阵问题
OpenGL perspective projection matrix trouble
我真的不明白我在透视矩阵创建代码中做错了什么:
public static Matrix4f perspective(float fov, float width, float height,
float Near, float Far) {
Matrix4f projection = new Matrix4f(0);
float a = width / height;
float h = 1.0f/(float) Math.tan(Math.toRadians(fov / 2));
float depth = Near - Far;
// x&y
projection.values[0][0] = h/a;
projection.values[1][1] = h;
projection.values[2][2] = ((Far + Near)/depth);
projection.values[2][3] = 2.0f *(Far * Near) / depth;
projection.values[3][2] = -1.0f;
return projection;
}
然后当我将它发送到着色器时,我之前将它与模型视图矩阵相乘,如下所示:
math.mul(camera.getMatrix(), mesh.transform.getMatrix());
这意味着
P*M
使用其他语言可以覆盖运算符,因为我没有来自相机的视图矩阵。
发生的事情是 3d 模型是平面的,当我旋转它时,它真的变形了。我整天都在尝试找出问题所在,但我没有运气。
我做错了什么?
有什么我忘了的吗?
编辑:
可能我的乘法代码有问题:
乘法码:
public static Matrix4f mul(Matrix4f m1, Matrix4f m2) {
Matrix4f result = new Matrix4f();
for (int j = 0; j < 4; j++) {
for (int i = 0; i < 4; i++) {
float sum = 0;
for (int n = 0; n < 4; n++) {
sum += m1.values[n][i] * m2.values[j][n];
}
result.values[j][i] = sum;
}
}
return result;
}
我什至尝试将乘法顺序从P * M
换成M * P
,但仍然没有解决问题。
我尝试在乘法后转置矩阵:
转置码:
public static Matrix4f transpose(Matrix4f data)
{
Matrix4f result = new Matrix4f();
for(int y = 0; y < 4; y++)
{
for(int x = 0; x < 4; x++)
{
result.values[x][y] = data.values[y][x];
}
}
return result;
}
但这会导致更严重的失真。
编辑:
这里是投影矩阵的原始打印内存内容:
matrix[0][0] = 1.071111
matrix[0][1] = 0.0
matrix[0][2] = 0.0
matrix[0][3] = 0.0
matrix[1][0] = 0.0
matrix[1][1] = 1.428148
matrix[1][2] = 0.0
matrix[1][3] = 0.0
matrix[2][0] = 0.0
matrix[2][1] = 0.0
matrix[2][2] = -1.00002
matrix[2][3] = -0.0200002
matrix[3][0] = 0.0
matrix[3][1] = 0.0
matrix[3][2] = -1.0
matrix[3][3] = 0.0
这里是ModelView矩阵(转换)(模型位置=0,0,5):
model[0][0] = 1.0
model[0][1] = 0.0
model[0][2] = 0.0
model[0][3] = 0.0
model[1][0] = 0.0
model[1][1] = 1.0
model[1][2] = 0.0
model[1][3] = 0.0
model[2][0] = 0.0
model[2][1] = 0.0
model[2][2] = 1.0
model[2][3] = 5.0
model[3][0] = 0.0
model[3][1] = 0.0
model[3][2] = 0.0
model[3][3] = 1.0
这里是M*P
:
matrix[0][0] = 1.071111
matrix[0][1] = 0.0
matrix[0][2] = 0.0
matrix[0][3] = 0.0
matrix[1][0] = 0.0
matrix[1][1] = 1.428148
matrix[1][2] = 0.0
matrix[1][3] = 0.0
matrix[2][0] = 0.0
matrix[2][1] = 0.0
matrix[2][2] = -1.00002
matrix[2][3] = -5.0201
matrix[3][0] = 0.0
matrix[3][1] = 0.0
matrix[3][2] = -1.0
matrix[3][3] = -5.0
这里是P*M
:
matrix[0][0] = 1.071111
matrix[0][1] = 0.0
matrix[0][2] = 0.0
matrix[0][3] = 0.0
matrix[1][0] = 0.0
matrix[1][1] = 1.428148
matrix[1][2] = 0.0
matrix[1][3] = 0.0
matrix[2][0] = 0.0
matrix[2][1] = 0.0
matrix[2][2] = -6.00002
matrix[2][3] = -0.0200002
matrix[3][0] = 0.0
matrix[3][1] = 0.0
matrix[3][2] = -1.0
matrix[3][3] = 0.0
答案属于@derhass:
"From the numbers given, it looks like M*P is the correct result. However, you store the matrices transposed to what GL (somewhat) defaults to. So either you use vec4 * mat4 in the shader, and it should work, or you have to transpose the result for the GL and can use the default mat4 * vec4 convetion"
我真的不明白我在透视矩阵创建代码中做错了什么:
public static Matrix4f perspective(float fov, float width, float height,
float Near, float Far) {
Matrix4f projection = new Matrix4f(0);
float a = width / height;
float h = 1.0f/(float) Math.tan(Math.toRadians(fov / 2));
float depth = Near - Far;
// x&y
projection.values[0][0] = h/a;
projection.values[1][1] = h;
projection.values[2][2] = ((Far + Near)/depth);
projection.values[2][3] = 2.0f *(Far * Near) / depth;
projection.values[3][2] = -1.0f;
return projection;
}
然后当我将它发送到着色器时,我之前将它与模型视图矩阵相乘,如下所示:
math.mul(camera.getMatrix(), mesh.transform.getMatrix());
这意味着
P*M
使用其他语言可以覆盖运算符,因为我没有来自相机的视图矩阵。
发生的事情是 3d 模型是平面的,当我旋转它时,它真的变形了。我整天都在尝试找出问题所在,但我没有运气。
我做错了什么? 有什么我忘了的吗?
编辑:
可能我的乘法代码有问题:
乘法码:
public static Matrix4f mul(Matrix4f m1, Matrix4f m2) {
Matrix4f result = new Matrix4f();
for (int j = 0; j < 4; j++) {
for (int i = 0; i < 4; i++) {
float sum = 0;
for (int n = 0; n < 4; n++) {
sum += m1.values[n][i] * m2.values[j][n];
}
result.values[j][i] = sum;
}
}
return result;
}
我什至尝试将乘法顺序从P * M
换成M * P
,但仍然没有解决问题。
我尝试在乘法后转置矩阵:
转置码:
public static Matrix4f transpose(Matrix4f data)
{
Matrix4f result = new Matrix4f();
for(int y = 0; y < 4; y++)
{
for(int x = 0; x < 4; x++)
{
result.values[x][y] = data.values[y][x];
}
}
return result;
}
但这会导致更严重的失真。
编辑:
这里是投影矩阵的原始打印内存内容:
matrix[0][0] = 1.071111
matrix[0][1] = 0.0
matrix[0][2] = 0.0
matrix[0][3] = 0.0
matrix[1][0] = 0.0
matrix[1][1] = 1.428148
matrix[1][2] = 0.0
matrix[1][3] = 0.0
matrix[2][0] = 0.0
matrix[2][1] = 0.0
matrix[2][2] = -1.00002
matrix[2][3] = -0.0200002
matrix[3][0] = 0.0
matrix[3][1] = 0.0
matrix[3][2] = -1.0
matrix[3][3] = 0.0
这里是ModelView矩阵(转换)(模型位置=0,0,5):
model[0][0] = 1.0
model[0][1] = 0.0
model[0][2] = 0.0
model[0][3] = 0.0
model[1][0] = 0.0
model[1][1] = 1.0
model[1][2] = 0.0
model[1][3] = 0.0
model[2][0] = 0.0
model[2][1] = 0.0
model[2][2] = 1.0
model[2][3] = 5.0
model[3][0] = 0.0
model[3][1] = 0.0
model[3][2] = 0.0
model[3][3] = 1.0
这里是M*P
:
matrix[0][0] = 1.071111
matrix[0][1] = 0.0
matrix[0][2] = 0.0
matrix[0][3] = 0.0
matrix[1][0] = 0.0
matrix[1][1] = 1.428148
matrix[1][2] = 0.0
matrix[1][3] = 0.0
matrix[2][0] = 0.0
matrix[2][1] = 0.0
matrix[2][2] = -1.00002
matrix[2][3] = -5.0201
matrix[3][0] = 0.0
matrix[3][1] = 0.0
matrix[3][2] = -1.0
matrix[3][3] = -5.0
这里是P*M
:
matrix[0][0] = 1.071111
matrix[0][1] = 0.0
matrix[0][2] = 0.0
matrix[0][3] = 0.0
matrix[1][0] = 0.0
matrix[1][1] = 1.428148
matrix[1][2] = 0.0
matrix[1][3] = 0.0
matrix[2][0] = 0.0
matrix[2][1] = 0.0
matrix[2][2] = -6.00002
matrix[2][3] = -0.0200002
matrix[3][0] = 0.0
matrix[3][1] = 0.0
matrix[3][2] = -1.0
matrix[3][3] = 0.0
答案属于@derhass:
"From the numbers given, it looks like M*P is the correct result. However, you store the matrices transposed to what GL (somewhat) defaults to. So either you use vec4 * mat4 in the shader, and it should work, or you have to transpose the result for the GL and can use the default mat4 * vec4 convetion"