diff --git a/blog/2025-03-30-draw-compute-shader/draw-compute/shader/src/lib.rs b/blog/2025-03-30-draw-compute-shader/draw-compute/shader/src/lib.rs index 10b25d4..77386e2 100644 --- a/blog/2025-03-30-draw-compute-shader/draw-compute/shader/src/lib.rs +++ b/blog/2025-03-30-draw-compute-shader/draw-compute/shader/src/lib.rs @@ -54,12 +54,16 @@ pub fn main_fs( #[spirv(storage_buffer, descriptor_set = 0, binding = 1)] image: &mut [glam::Vec4], output: &mut glam::Vec4, ) { - let pixel_coordinate = frag_coord.xy().as_usizevec2(); - let (pixel_x, pixel_y) = (pixel_coordinate.x, pixel_coordinate.y); + let vp_size = viewport.size.as_vec2(); + let img_size = viewport.image.as_vec2(); - *output = if pixel_x < viewport.image.x as usize && pixel_y < viewport.image.y as usize { - image[image_index(pixel_x, pixel_y, viewport.image.x as usize)] + let scale = (vp_size / img_size).min_element(); + let img_offset = (vp_size / scale - img_size) / 2.0; + let img_coord = (frag_coord.xy() - viewport.offset.as_vec2()) / scale - img_offset; + + *output = if img_coord.cmpge(glam::Vec2::ZERO).all() && img_coord.cmple(img_size).all() { + image[image_index(img_coord.x as usize, img_coord.y as usize, viewport.image.x as usize)] } else { BLACK - }; + } } diff --git a/blog/2025-03-30-draw-compute-shader/draw-compute/src/main.rs b/blog/2025-03-30-draw-compute-shader/draw-compute/src/main.rs index 9d32b2b..c67686f 100644 --- a/blog/2025-03-30-draw-compute-shader/draw-compute/src/main.rs +++ b/blog/2025-03-30-draw-compute-shader/draw-compute/src/main.rs @@ -172,6 +172,7 @@ impl DrawResources { fn resize(&mut self, width: u64, height: u64) { self.image_buffer = Self::image_buffer(&self.device, width, height); + self.image_size = glam::uvec2(width as u32, height as u32); self.bind_group = Self::bind_group( &self.device, &self.bind_group_layout, @@ -206,7 +207,7 @@ impl CallbackTrait for DrawCallback { ); } - let mut viewport = shader::Viewport { + let viewport = shader::Viewport { image: resources.image_size, offset: glam::uvec2(self.draw_rect.min.x as u32, self.draw_rect.min.y as u32), size: glam::uvec2( @@ -273,6 +274,13 @@ impl eframe::App for ComputeDraw { callback_resources.insert(DrawResources::new(&device, &format, 800, 600)); } + egui::TopBottomPanel::bottom("bottom").show(ctx, |ui| { + let wgpu_render_state = frame.wgpu_render_state().expect("missing WGPU state"); + let image_size = wgpu_render_state.renderer.as_ref().read().callback_resources.get::().unwrap().image_size; + + ui.label(format!("Viewport: image={image_size}")) + }); + egui::CentralPanel::default().show(ctx, |ui| { egui::Frame::canvas(ui.style()).show(ui, |ui| { let interact_rect = ui.available_rect_before_wrap(); @@ -301,7 +309,7 @@ fn main() { eframe::run_native( "Compute Draw", native_options, - Box::new(|cc| Ok(Box::new(ComputeDraw { initial_draw: true }))), + Box::new(|_cc| Ok(Box::new(ComputeDraw { initial_draw: true }))), ) .unwrap() }