diff --git a/assets/shaders/voxel_volume.wgsl b/assets/shaders/voxel_volume.wgsl index d07b19f..4586434 100644 --- a/assets/shaders/voxel_volume.wgsl +++ b/assets/shaders/voxel_volume.wgsl @@ -1,13 +1,14 @@ @group(0) @binding(0) var output: texture_storage_2d; @group(1) @binding(0) var voxels_t: texture_3d; @group(1) @binding(1) var voxels_s: sampler; -// @group(2) @binding(0) var camera: Camera; +@group(2) @binding(0) var camera: Camera; -// struct Camera { -// projection: mat4x4, -// view: mat4x4, -// pos: vec3, -// }; +struct Camera { + projection: mat4x4, + view: mat4x4, + pos: vec3, + _pad: f32, +}; struct HitInfo { hit: bool, @@ -115,15 +116,10 @@ fn compute(@builtin(global_invocation_id) global_id: vec3) { // Construct ray let img_coord_frac = vec2(img_coord) / vec2(img_dims); let screen_pos = img_coord_frac * 2.0 - vec2(1.0); - // var ray_eye = camera.projection * vec4(screen_pos, -1.0, 0.0); - // ray_eye = vec4(ray_eye.xy, -1.0, 0.0); - // let ray_dir = normalize((camera.view * ray_eye).xyz); - // let ray_pos = camera.pos; - let camera_dir = vec3(0.01, 0.0, 0.8); - let camera_plane_u = vec3(1.0, 0.0, 0.0); - let camera_plane_v = vec3(0.0, 1.0, 0.0) * f32(img_dims.y) / f32(img_dims.x); - let ray_dir = camera_dir + screen_pos.x * camera_plane_u + screen_pos.y * camera_plane_v; - let ray_pos = vec3(-4.01, 5.0, -10.0); + var ray_eye = camera.projection * vec4(screen_pos, -1.0, 0.0); + ray_eye = vec4(ray_eye.xy, -1.0, 0.0); + let ray_dir = normalize((camera.view * ray_eye).xyz); + let ray_pos = camera.pos; // Cast the ray var hit_info = cast_ray(ray_pos, ray_dir); diff --git a/src/app.rs b/src/app.rs index 2d83766..9398cef 100644 --- a/src/app.rs +++ b/src/app.rs @@ -45,7 +45,9 @@ impl App { window_id, } if window_id == self.window.id() => match event { WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit, - _ => {} + _ => { + self.renderer.input(&event); + } }, Event::MainEventsCleared => { self.window.request_redraw(); @@ -54,6 +56,7 @@ impl App { let now = Instant::now(); let dt = now - last_render_time; last_render_time = now; + self.renderer.update(dt, &self.render_ctx); self.renderer.render(&self.render_ctx); } _ => {} diff --git a/src/renderer.rs b/src/renderer.rs index 03127b3..9a476db 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -1,5 +1,10 @@ +use std::time::Duration; + +use wgpu::util::DeviceExt; +use winit::event::WindowEvent; use winit::{dpi::PhysicalSize, window::Window}; +use crate::camera; use crate::texture::{Texture, TextureBuilder}; pub(crate) struct RenderContext { @@ -77,6 +82,8 @@ pub(crate) struct Renderer { render_pipeline: wgpu::RenderPipeline, render_texture: Texture, voxel_texture: Texture, + camera_controller: camera::CameraController, + camera_bind_group: wgpu::BindGroup, } impl Renderer { @@ -132,6 +139,56 @@ impl Renderer { } voxel_texture.update(&context, &data); + log::info!("Creating camera..."); + let camera_controller = camera::CameraController::new( + context, + camera::Camera::new( + glam::Vec3 { + x: 4.01, + y: 4.01, + z: 20.0, + }, + -90.0_f32.to_radians(), + 0.0_f32.to_radians(), + ), + camera::Projection::new( + context.size.width, + context.size.height, + 90.0_f32.to_radians(), + 0.01, + 100.0, + ), + 10.0, + 0.25, + ); + + let camera_bind_group_layout = + context + .device + .create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + entries: &[wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStages::COMPUTE, + ty: wgpu::BindingType::Buffer { + ty: wgpu::BufferBindingType::Uniform, + has_dynamic_offset: false, + min_binding_size: None, + }, + count: None, + }], + label: Some("camera_bind_group_layout"), + }); + let camera_bind_group = context + .device + .create_bind_group(&wgpu::BindGroupDescriptor { + layout: &camera_bind_group_layout, + entries: &[wgpu::BindGroupEntry { + binding: 0, + resource: camera_controller.get_buffer().as_entire_binding(), + }], + label: Some("camera_bind_group"), + }); + log::info!("Creating render pipeline..."); let render_pipeline = context @@ -201,6 +258,7 @@ impl Renderer { bind_group_layouts: &[ &compute_layout, &voxel_texture.bind_group_layout, + &camera_bind_group_layout, ], push_constant_ranges: &[], }, @@ -223,6 +281,8 @@ impl Renderer { render_pipeline, render_texture, voxel_texture, + camera_controller, + camera_bind_group, } } @@ -241,6 +301,7 @@ impl Renderer { compute_pass.set_pipeline(&self.compute_pipeline); compute_pass.set_bind_group(0, &self.compute_bind_group, &[]); compute_pass.set_bind_group(1, &self.voxel_texture.bind_group, &[]); + compute_pass.set_bind_group(2, &self.camera_bind_group, &[]); compute_pass.dispatch_workgroups(size.width / 8, size.height / 8, 1); drop(compute_pass); @@ -265,4 +326,13 @@ impl Renderer { context.queue.submit(Some(encoder.finish())); frame.present(); } + + pub fn input(&mut self, event: &WindowEvent) -> bool { + self.camera_controller.process_events(event) + } + + pub fn update(&mut self, dt: Duration, render_ctx: &RenderContext) { + self.camera_controller.update(dt); + self.camera_controller.update_buffer(render_ctx) + } }