[ad_1]
I am writing a simple graphics engine using Rusts WGPU. I have a Sphere rendering at the origin of my scene like so:
let globe_radius = 100.0;
let globe_matrix = cgmath::Matrix4::identity();
// ...generate bind groups, layout, buffers, etc.
let globe_matrix_bind_group_layout = mesh_system.create_model_matrix_bind_group_layout();
let globe_mesh_component = MeshComponent {
vertex_buffer: mesh_system.create_vertex_buffer(&globe_vertices_vec.as_slice()),
index_buffer: mesh_system.create_index_buffer(&globe_indices_vec.as_slice()),
num_indices: globe_indices_vec.len() as u32,
model_matrix_bind_group_layout: globe_matrix_bind_group_layout,
model_matrix_bind_group: globe_matrix_bind_group,
model_matrix: globe_matrix,
};
and I am creating a camera that is 200 units away from the origin / center of the sphere like so:
let camera = Camera {
eye: (0.0, 0.0, 200.0).into(),
target: (0.0, 0.0, 0.0).into(),
up: cgmath::Vector3::unit_y(),
aspect: screen_width as f32 / screen_height as f32,
fovy: 45.0,
znear: 0.1,
zfar: 100.0,
};
const OPENGL_TO_WGPU_MATRIX= cgmath::Matrix4::new(
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 0.5, 0.5,
0.0, 0.0, 0.0, 1.0,
);
let view_matrix = cgmath::Matrix4::look_at_rh(eye, target, up);
let proj_matrix = cgmath::perspective(cgmath::Deg(fovy), aspect, znear, zfar);
let view_proj_matrix = OPENGL_TO_WGPU_MATRIX * proj * view.into();
this results in the following scene:
the scene you see when starting the program
Finally, I have the ray-sphere intersection happening on-click. I have hardcoded the click to click directly in the middle of the screen. This should result in my point_closest_to_origin
being 0
. However, I instead get 200
, meaning that the closest point of my ray is the ray_origin
(camera_origin
) on click:
let screen_width = self.config.width as f32;
let screen_height = self.config.height as f32;
let position_x = screen_width / 2.0;
let position_y = screen_height / 2.0;
let cam_proj_matrix = self.camera_component.camera_uniform.proj_matrix;
let cam_view_matrix = self.camera_component.camera_uniform.view_matrix;
let globe_origin = cgmath::Matrix4::identity();
let ray_origin = cgmath::Vector4::new(
cam_view_matrix[3][0],
cam_view_matrix[3][1],
cam_view_matrix[3][2],
cam_view_matrix[3][3],
);
let mouse_pos_clip_space = cgmath::Vector4::new(
(position_x * 2.0) / screen_width - 1.0,
1.0 - (2.0 * position_y) / screen_height,
0.0,
1.0,
);
let mut mouse_pos_view_space =
cgmath::Matrix4::from(cam_proj_matrix).invert().unwrap()
* mouse_pos_clip_space;
mouse_pos_view_space = mouse_pos_view_space / mouse_pos_view_space.w;
let model_matrix_inverse = globe_origin.invert().unwrap();
let mouse_pos_world_space = model_matrix_inverse * mouse_pos_view_space;
let ray_direction = (mouse_pos_world_space - ray_origin).normalize();
// This should be 0.0, but instead I am getting 200.0
let point_closest_to_origin = (globe_origin[3] - ray_origin).dot(ray_direction);
This is where I have been stuck at for the past couple of days and cannot tell where the issue is stemming from. I am beginning to think it has something to do with the OPENGL_TO_WGPU_MATRIX
affecting the z-axis
, but I cannot figure out how to confirm or deny that.
To make things as easy to possible to debug, here is also the output of all variables when running the program:
You can also view this code on github here:
https://github.com/shanebenlolo/hypersphere/tree/ray-sphere-intersection
Thank you very much for any and all help you can offer.
[ad_2]