投影矩阵产生不正确的结果
Projection Matrix yielding incorrect results
我目前正在尝试创建一个透视函数,它为 OpenGL 生成一个投影。我已经用很多很多方法创建了它,最新的复制处理它的 GLM 函数(我必须使用我自己的 Matrix4 class 来完成我的任务)。无论我尝试什么代码,与 GLM 相比,我总是产生不正确的数字,这导致我的立方体仅使用 GLM 渲染。
它们都使用相同的变量初始化
glm::mat4 ProjectionGLM = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
Matrix4 Projection = Matrix4::Perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
透视函数
Matrix4 Matrix4::Perspective(double fov, double aspect, double zNear, double zFar) {
double fovy = fov * 0.0174532925;
double const tanHalfFovy = tan(fovy / 2.0f);
Matrix4 temp;
temp.data[0][0] = 1.0f / (aspect * tanHalfFovy);
temp.data[1][1] = 1.0f / (tanHalfFovy);
temp.data[2][2] = -(zFar + zNear) / (zFar - zNear);
temp.data[2][3] = -1.0f;
temp.data[3][2] = -(2.0f * zFar * zNear) / (zFar - zNear);
return temp;
代码直接仿照 GLM,减去 static_cast 和模板。它与我尝试过的许多其他函数的数学相同。然而生成的矩阵是不同的。
GLM 结果
1.34444320 0 0 0
0 1.79259098 0 0
0 0 -1.00200200 -1.00000000
0 0 -0.200200200 0
我的成绩
1.81066012 0 0 0
0 2.41421366 0 0
0 0 -1.00200200 -1.00000000
0 0 -0.200200200 0
关于我的透视函数可能有什么问题或 GLM 可以做些什么不同的想法?
链接到我的数学库(只有 .h 和 .cpp 文件)
https://mega.co.nz/#!lokhCBaB!5r7GwpWhEZ-tUcXV_ccxmQvZgRwIVU8K7dlIffVqZic
GLM 采用以弧度为单位的 FOV 角度,而您传递的值 (45.0
) 以度为单位。
参数的 GLM documentation 尽可能不清楚:
Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
是的,两者都表示它是度数和弧度。但是看源码确实是弧度。
这与您的结果一致。对于矩阵元素[2][2]
,即:
1.0 / tan(0.5 * fov)
使用以弧度为单位的 tan()
函数求值,直接使用 45.0
时会产生以下结果:
1.0 / tan(0.5 * 45.0) = 1.0 / tan(22.5) = 1.79251
先将角度转换为弧度时:
1.0f / tan(0.5 * 45.0 * pi / 180.0) = 1.0 / tan(0.3927) = 2.41421
因此,如果您将 GLM 版本的输入角度转换为弧度,我的预测是您将获得与您自己计算的值相同的值:
glm::mat4 ProjectionGLM = glm::perspective(45.0f * M_PI / 180.0f, 4.0f / 3.0f, 0.1f, 100.0f);
我目前正在尝试创建一个透视函数,它为 OpenGL 生成一个投影。我已经用很多很多方法创建了它,最新的复制处理它的 GLM 函数(我必须使用我自己的 Matrix4 class 来完成我的任务)。无论我尝试什么代码,与 GLM 相比,我总是产生不正确的数字,这导致我的立方体仅使用 GLM 渲染。
它们都使用相同的变量初始化
glm::mat4 ProjectionGLM = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
Matrix4 Projection = Matrix4::Perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
透视函数
Matrix4 Matrix4::Perspective(double fov, double aspect, double zNear, double zFar) {
double fovy = fov * 0.0174532925;
double const tanHalfFovy = tan(fovy / 2.0f);
Matrix4 temp;
temp.data[0][0] = 1.0f / (aspect * tanHalfFovy);
temp.data[1][1] = 1.0f / (tanHalfFovy);
temp.data[2][2] = -(zFar + zNear) / (zFar - zNear);
temp.data[2][3] = -1.0f;
temp.data[3][2] = -(2.0f * zFar * zNear) / (zFar - zNear);
return temp;
代码直接仿照 GLM,减去 static_cast 和模板。它与我尝试过的许多其他函数的数学相同。然而生成的矩阵是不同的。
GLM 结果
1.34444320 0 0 0
0 1.79259098 0 0
0 0 -1.00200200 -1.00000000
0 0 -0.200200200 0
我的成绩
1.81066012 0 0 0
0 2.41421366 0 0
0 0 -1.00200200 -1.00000000
0 0 -0.200200200 0
关于我的透视函数可能有什么问题或 GLM 可以做些什么不同的想法?
链接到我的数学库(只有 .h 和 .cpp 文件) https://mega.co.nz/#!lokhCBaB!5r7GwpWhEZ-tUcXV_ccxmQvZgRwIVU8K7dlIffVqZic
GLM 采用以弧度为单位的 FOV 角度,而您传递的值 (45.0
) 以度为单位。
参数的 GLM documentation 尽可能不清楚:
Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
是的,两者都表示它是度数和弧度。但是看源码确实是弧度。
这与您的结果一致。对于矩阵元素[2][2]
,即:
1.0 / tan(0.5 * fov)
使用以弧度为单位的 tan()
函数求值,直接使用 45.0
时会产生以下结果:
1.0 / tan(0.5 * 45.0) = 1.0 / tan(22.5) = 1.79251
先将角度转换为弧度时:
1.0f / tan(0.5 * 45.0 * pi / 180.0) = 1.0 / tan(0.3927) = 2.41421
因此,如果您将 GLM 版本的输入角度转换为弧度,我的预测是您将获得与您自己计算的值相同的值:
glm::mat4 ProjectionGLM = glm::perspective(45.0f * M_PI / 180.0f, 4.0f / 3.0f, 0.1f, 100.0f);