使用OpenGL 2从鼠标进行光线投射
ray casting from mouse with opengl 2
我正在尝试在鼠标单击时进行光线投射,最终目标是找到与飞机的碰撞点。但是我无法创建射线。世界是使用视锥体和我用作摄像机的另一个矩阵渲染的,顺序是视锥体 * 相机 * vertex_position。屏幕左上角为 0,0,我能够以像素为单位获得点击的 X,Y。然后,我使用以下代码将其转换为射线:
float x = (2.0f * x_screen_position) / width - 1.0f;
float y = 1.0f - (2.0f * y_screen_position) / height;
Vector4 screen_click = Vector4 (x, y, 1.0f, 1.0f);
Vector4 ray_origin_world = get_camera_matrix() * screen_click;
Vector4 tmp = (inverse(get_view_frustum()) * screen_click;
tmp = get_camera_matrix() * tmp;
Vector4 ray_direction = normalize(tmp);
view_frustum矩阵:
Matrix4 view_frustum(float angle_of_view, float aspect_ratio, float z_near, float z_far) {
return Matrix4(
Vector4(1.0/tan(angle_of_view), 0.0, 0.0, 0.0),
Vector4(0.0, aspect_ratio/tan(angle_of_view), 0.0, 0.0),
Vector4(0.0, 0.0, (z_far+z_near)/(z_far-z_near), 1.0),
Vector4(0.0, 0.0, -2.0*z_far*z_near/(z_far-z_near), 0.0)
);
}
当"相机"矩阵为 0,0,0 时,这给出了预期的结果,但是一旦我更改为另一个位置的固定相机位置,返回的结果根本不正确。固定的"相机"矩阵:
Matrix4(
Vector4(1.0, 0.0, 0.0, 0.0),
Vector4(0.0, 0.70710678118, -0.70710678118, 0.000),
Vector4(0.0, 0.70710678118, 0.70710678118, 0.0),
Vector4(0.0, 8.0, 20.0, 1.000)
);
因为我在网上找到的许多例子都没有以这种方式实现相机,所以我无法在这种情况下找到很多信息来提供帮助。谁能对此提供任何见解或为我指出更好的方向?
Vector4 tmp = (inverse(get_view_frustum() * get_camera_matrix()) * screen_click; //take the inverse of the camera matrix as well
tmp /= tmp.w; //homogeneous coordinate "normalize" (different to typical normalization), needed with perspective projection or non-linear depth
Vector3 ray_direction = normalize(Vector3(tmp.x, tmp.y, tmp.z)); //make sure to normalize just the direction without w
[编辑]
一个更长和类似的帖子在这里:https://stackoverflow.com/a/20143963/1888983
如果只有矩阵,则应使用射线方向的起点和点。为此,通常在近平面和远平面上使用点(一个优点是,如果您只希望光线与可见的物体相交)。那是
(x, y, -1, 1)至 (x, y, 1, 1)
这些点位于标准化设备坐标(NDC,一个 -1 到 1 的立方体,即您的查看音量)中。您需要做的就是将两个点一直移动到世界空间并规范化......
ndcPoint4 = /* from above */;
eyespacePoint4 = inverseProjectionMatrix * ndcPoint4;
worldSpacePoint4 = inverseCameraMatrix * eyespacePoint4;
worldSpacePoint3 = worldSpacePoint4.xyz / worldSpacePoint4.w;
//alternatively, with combined matrices
worldToClipMatrix = projectionMatrix * cameraMatrix; //called "clip" space before normalization
clipToWorldMatrix = inverse(worldToClipMatrix);
worldSpacePoint4 = clipToWorldMatrix * ndcPoint4;
worldSpacePoint3 = worldSpacePoint4.xyz / worldSpacePoint4.w;
//then for the ray, after transforming both start/end points
rayStart = worldPointOnNearPlane;
rayEnd = worldPointOnFarPlane;
rayDir = rayEnd - rayStart;
如果您拥有摄像机的世界空间位置,则可以删除起点或终点,因为所有光线都会穿过摄像机的原点。
相关文章:
- 函数样式投射指针
- WinAPI挂钩鼠标
- 光线跟踪器灯光反射错误
- 将鼠标悬停在问题上时与预期">"相关的代码错误
- 跟踪滚动条上的鼠标事件
- SendInput()鼠标移动计算
- 为什么我的点没有在 OpenGL 中绘制鼠标所在的位置?
- 在 OpenGL 中使用透视与正交投影时的光线投射(鼠标拾取)
- 在UE4中,玩家进行光线投射、击中物体并触发自定义事件C++
- 连续光线投射之间的时间延迟
- 将投影转换为正交光线投射
- 一种在没有光线投射的情况下在 3D 中使用寻路和多目标的方法
- box2d光线投射向后兼容性问题
- 3D 屏幕空间光线投射/拾取 DirectX9
- 使用OpenGL 2从鼠标进行光线投射
- 没有侧坐标的光线投射算法
- 光线投射算法中的精度问题
- OpenGL光线投射与任何对象
- 在DirectX11中的c++ -光线投射
- CPU光线投射