我了解如何取消项目的基本概念:
let mut z = 0.0;
gl::ReadPixels(x as i32, y as i32, 1, 1, gl::DEPTH_COMPONENT, gl::FLOAT, &z);
// window position to screen position
let screen_position = self.to_screen_position(x, y);
// screen position to world position
let world_position = self.projection_matrix().invert() *
Vector4::new(screen_position.x, screen_position.y, z, 1.0);
但这并没有采取W坐标正确-当我渲染的东西从世界空间到屏幕空间,他们最终与W != 1
,因为透视转换(https://www.opengl.org/sdk/docs/man2/xhtml/gluPerspective.xml)。当我从屏幕空间转换回世界空间时(假设W=1
),物体处于错误的位置。
据我所知,W
是所有其他坐标的缩放因子。如果是这样的话,这是否意味着屏幕向量(0, 0, -1, 1)
和(0, 0, -2, 2)
将映射到相同的窗口坐标,并且不投影不一定产生独特的结果,而无需进一步的工作?
谢谢!
由于透视转换,您不能真正忽略w
我建议在这里查看gluUnproject
函数的源代码:http://www.opengl.org/wiki/GluProject_and_gluUnProject_code。你会看到它的作用是:
- 计算投影*modelView矩阵并求反
- 从屏幕位置乘一个矢量(在代码中,winZ=0对应于透视投影的近平面,winZ=1对应于远平面);W总是1).
- 将计算出的向量的X、Y、Z除以w。
请注意,如果你这样做,结果的W应该被忽略(即假设为1)。
你也可以看这里看看如何转换在OpenGL工作-如果你不熟悉这个,我建议阅读剪辑坐标和标准化设备坐标。