在 3D 世界中查找视口矩形 Space (Opengl)
Find ViewPort Rectangle in 3D world Space (Opengl)
我需要有关矩阵变换的帮助,以在 3d 坐标(世界 Space)中找到我的视口的角点。
我做了一些测试,但找不到解决方案。
第一步:
我有可用的投影和模型矩阵(也有 ViewPort 大小)。为了找到我的 "Screen" 的中心,我使用了这个:
OpenGL.UnProject(0.0, 0.0, 0.0)
<- 这个函数告诉我 3D 屏幕的中心在哪里 space(正确!)
另一种方法是乘以 Coordinate (0, 0, 0) * ProjectionMtx.Inverse
.
第 2 步:
现在我需要例如视口的左上角,如何找到世界中的 3D 点 space?
也许我应该使用视口大小,但是如何?
这是我的取消项目方法:
double[] mview = new double[16];
GetDouble(GL_MODELVIEW_MATRIX, mview);
double[] prj = new double[16];
GetDouble(GL_PROJECTION_MATRIX, prj);
int[] vp = new int[4];
GetInteger(GL_VIEWPORT, vp);
double[] r = new double[3];
gluUnProject(winx, winy, winz, mview, prj, vp, ref r[0], ref r[1], ref r[2]);
例如:
如果我的相机在 (-40,0,0) 和我的视口 [0,0,1258,513] 并且我取消投影我的近平面点我有这个结果:
left_bottom_near =>X=-39.7499881839701,Y=-0.0219584744091603,Z=0.946276352352364
right_bottom_near =>X=-39.7499881839701,Y=-0.0219584744091603,Z=0.946446903614738
left_top_near =>X=-39.7499881839701,Y=-0.0217879231516134,Z=0.946276352352364
right_top_near =>X=-39.7499881839701,Y=-0.0217879231516134,Z=0.946446903614738
我可以理解我的点的 X 值,即我的相机位置的 x 世界值,但是,Y 和 Z 呢?看不懂。
gluUnProject
从 window 坐标转换到世界 space(或模型 space)。
视图矩阵从世界 space 转换为视图 space.
投影矩阵从视图 space 转换为归一化设备 space。归一化设备space是一个立方体,左、下、近为(-1, -1, -1),右、上、远为(1, 1, 1)。
最后,标准化设备 space 中的 xy 坐标映射到视口(window 坐标)。视口由 glViewport
. The z component is maped to the glDepthRange
定义(默认 [0.0, 1.0]。gluUnProject
与所有这些步骤相反。
在 orthographic projection the viewing volume is a cuboid. At Perspective projection the viewing volume is a frustum。投影矩阵从视图 space 转换为归一化设备 space.
您在视口上看到的是标准化设备 space 到其 xy 平面的投影。
一般情况下,可以将window坐标的8个角点反投影得到视体的角点。为此,您必须知道视口矩形和深度范围。
我假设 viwport 的大小为 window (0, 0, widht
, height
) 并且深度范围为 [0.0, 1.0]:
left = 0.0;
right = width;
bottom = 0.0;
top = height;
left_bottom_near = gluUnProject(left, bottom, 0.0)
right_bottom_near = gluUnProject(right, bottom, 0.0)
left_top_near = gluUnProject(left, top, 0.0)
right_top_near = gluUnProject(right, top, 0.0)
left_bottom_far = gluUnProject(left, bottom, 1.0)
right_bottom_far = gluUnProject(right, bottom, 1.0)
left_top_far = gluUnProject(left, top, 1.0)
right_top_far = gluUnProject(right, top, 1.0)
我需要有关矩阵变换的帮助,以在 3d 坐标(世界 Space)中找到我的视口的角点。
我做了一些测试,但找不到解决方案。
第一步:
我有可用的投影和模型矩阵(也有 ViewPort 大小)。为了找到我的 "Screen" 的中心,我使用了这个:
OpenGL.UnProject(0.0, 0.0, 0.0)
<- 这个函数告诉我 3D 屏幕的中心在哪里 space(正确!)
另一种方法是乘以 Coordinate (0, 0, 0) * ProjectionMtx.Inverse
.
第 2 步: 现在我需要例如视口的左上角,如何找到世界中的 3D 点 space? 也许我应该使用视口大小,但是如何?
这是我的取消项目方法:
double[] mview = new double[16];
GetDouble(GL_MODELVIEW_MATRIX, mview);
double[] prj = new double[16];
GetDouble(GL_PROJECTION_MATRIX, prj);
int[] vp = new int[4];
GetInteger(GL_VIEWPORT, vp);
double[] r = new double[3];
gluUnProject(winx, winy, winz, mview, prj, vp, ref r[0], ref r[1], ref r[2]);
例如: 如果我的相机在 (-40,0,0) 和我的视口 [0,0,1258,513] 并且我取消投影我的近平面点我有这个结果:
left_bottom_near =>X=-39.7499881839701,Y=-0.0219584744091603,Z=0.946276352352364
right_bottom_near =>X=-39.7499881839701,Y=-0.0219584744091603,Z=0.946446903614738
left_top_near =>X=-39.7499881839701,Y=-0.0217879231516134,Z=0.946276352352364
right_top_near =>X=-39.7499881839701,Y=-0.0217879231516134,Z=0.946446903614738
我可以理解我的点的 X 值,即我的相机位置的 x 世界值,但是,Y 和 Z 呢?看不懂。
gluUnProject
从 window 坐标转换到世界 space(或模型 space)。
视图矩阵从世界 space 转换为视图 space.
投影矩阵从视图 space 转换为归一化设备 space。归一化设备space是一个立方体,左、下、近为(-1, -1, -1),右、上、远为(1, 1, 1)。
最后,标准化设备 space 中的 xy 坐标映射到视口(window 坐标)。视口由 glViewport
. The z component is maped to the glDepthRange
定义(默认 [0.0, 1.0]。gluUnProject
与所有这些步骤相反。
在 orthographic projection the viewing volume is a cuboid. At Perspective projection the viewing volume is a frustum。投影矩阵从视图 space 转换为归一化设备 space.
您在视口上看到的是标准化设备 space 到其 xy 平面的投影。
一般情况下,可以将window坐标的8个角点反投影得到视体的角点。为此,您必须知道视口矩形和深度范围。
我假设 viwport 的大小为 window (0, 0, widht
, height
) 并且深度范围为 [0.0, 1.0]:
left = 0.0;
right = width;
bottom = 0.0;
top = height;
left_bottom_near = gluUnProject(left, bottom, 0.0)
right_bottom_near = gluUnProject(right, bottom, 0.0)
left_top_near = gluUnProject(left, top, 0.0)
right_top_near = gluUnProject(right, top, 0.0)
left_bottom_far = gluUnProject(left, bottom, 1.0)
right_bottom_far = gluUnProject(right, bottom, 1.0)
left_top_far = gluUnProject(left, top, 1.0)
right_top_far = gluUnProject(right, top, 1.0)