OpenGL射线拾取

3
一般而言,Ray拾取的流程应该按照以下步骤进行(实验结果证明是正确的):
  1. transform screen point to normalized device space direction vector:

    float x = (2.0f * mouse_x) / width - 1.0f;
    float y = 1.0f - (2.0f * mouse_y) / height;
    float z = 1.0f;
    vec3 ray_nds = vec3 (x, y, z);
    
  2. transform direction vector to Homogeneous Clip Coordinates

    vec4 ray_clip = vec4 (ray_nds.xy, -1.0, 1.0);
    
  3. transform direction vector to eye space direction vector

    vec4 ray_eye = inverse (projection_matrix) * ray_clip;
    
  4. transform direction vector to world space, get a pick ray with world space camera position and the direction vector

我的问题是,在标准化设备空间中,为什么方向向量的z分量为1.0?
我的意思是,在OpenGL标准化设备空间中,xyz分量应全部在-1~1范围内,因此相机应该位于平面z=-1的中心位置。所以方向向量应为:视角目标位置 - 相机位置,而z分量应为1-(-1)=2.0f。(在DirectX标准化设备空间中,xy分量在-1~1范围内,z分量在0~1范围内,相机位置应该位于z=0的平面中心位置,例如(0,0,0),并且方向向量的z分量应为1-0=1)
2个回答

1

ray_nds.z是完全无关紧要的,因为您根本不使用它。这是因为您不知道像素的深度。

ray_clip不是方向,而是在投影后近裁剪平面(z=-1)上的位置。如果您使用逆投影矩阵撤消此投影,则会在相机空间中得到相同的点。在相机空间中,相机位于(0, 0, 0)处。可以使用ray_eye - (0, 0, 0)计算射线的方向向量,这本质上是ray_eye。因此,如果我们忽略w分量,我们可以将位置用作方向。这仅适用于相机空间!剪辑空间和世界空间很可能在其他地方具有投影中心。

不要混淆不同空间中的相机位置。在相机空间中,它位于原点。在剪辑空间中,可以假定其位于(0, 0, -无穷大)处。点(x, y, ...)只是由相应像素覆盖的任意点。您需要其中任何一个来定义光线。


0

相机并不位于z=-1(或0),它甚至在其后面。

近裁剪平面位于z=-1。这使得所有这种数学的复杂性,因为所有的方程都涉及到如果追踪会产生不通过0的曲线。因此我们总是携带大量的znzm

看看这个,方程4.2:http://www.arcsynthesis.org/gltut/Positioning/Tut04%20Perspective%20Projection.html

更可怕但更完整的:http://www.songho.ca/opengl/gl_projectionmatrix.html

更多链接: http://unspecified.wordpress.com/2012/06/21/calculating-the-gluperspective-matrix-and-other-opengl-matrix-maths/

http://schabby.de/projection-matrix/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接