From 295037edc6a22774ae76cb3a9b26d97766e0db5d Mon Sep 17 00:00:00 2001 From: numzero Date: Mon, 24 Nov 2025 18:15:48 +0300 Subject: [PATCH] add depth buffer --- src/lib.rs | 56 +++++++++++++++++++++++++++++++++++++-------- src/render/faces.rs | 10 ++++++-- src/render/lines.rs | 14 ++++++++++-- src/render/mod.rs | 1 + 4 files changed, 67 insertions(+), 14 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 87c1922..0beb0aa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,7 +9,7 @@ use crate::{ camera::OrbitalCamera, ray::Ray, render::{ - OUTPUT_FORMAT, + DEPTH_FORMAT, OUTPUT_FORMAT, lines::{LookParams, Mesh, Pipeline, Vertex}, }, trace::{Hit, Lambertian, Reflector, Scene, Source, Sphere}, @@ -67,6 +67,8 @@ pub struct Core { queue: wgpu::Queue, surface: wgpu::Surface<'static>, + depth: wgpu::Texture, + pipeline: Pipeline, mesh_pipe: render::faces::Pipeline, tripod: Mesh, @@ -134,18 +136,20 @@ impl Core { let pipeline = Pipeline::new(&device); let mesh_pipe = render::faces::Pipeline::new(&device); let tripod = new_tripod(&device); + let depth = Self::create_depth_buffer(&device, pixel_size); queue.submit([]); // flush buffer updates - let mut this = Self { + Self::configure_surface(&surface, &device, pixel_size); + + Self { device, queue, surface, + depth, pipeline, tripod, mesh_pipe, - }; - this.configure(pixel_size); - this + } } fn render(&self, output: &wgpu::Texture, args: &RedrawArgs) { @@ -176,6 +180,9 @@ impl Core { self.queue.submit([]); // flush buffer updates let view = output.create_view(&wgpu::TextureViewDescriptor::default()); + let depth_view = self + .depth + .create_view(&wgpu::TextureViewDescriptor::default()); let mut encoder = self .device .create_command_encoder(&wgpu::CommandEncoderDescriptor::default()); @@ -189,7 +196,14 @@ impl Core { store: wgpu::StoreOp::Store, }, })], - depth_stencil_attachment: None, + depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment { + view: &depth_view, + depth_ops: Some(wgpu::Operations { + load: wgpu::LoadOp::Clear(1.), + store: wgpu::StoreOp::Discard, + }), + stencil_ops: None, + }), ..Default::default() }); if args.show_axes { @@ -389,10 +403,26 @@ impl Core { self.queue.submit(std::iter::once(encoder.finish())); } - /// Configures the renderer for a given target size. - pub fn configure(&mut self, pixel_size: UVec2) { - self.surface.configure( - &self.device, + fn create_depth_buffer(device: &wgpu::Device, pixel_size: UVec2) -> wgpu::Texture { + device.create_texture(&wgpu::TextureDescriptor { + label: Some("depth buffer"), + size: wgpu::Extent3d { + width: pixel_size.x, + height: pixel_size.y, + depth_or_array_layers: 1, + }, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: DEPTH_FORMAT, + usage: wgpu::TextureUsages::RENDER_ATTACHMENT, + view_formats: &[], + }) + } + + fn configure_surface(surface: &wgpu::Surface, device: &wgpu::Device, pixel_size: UVec2) { + surface.configure( + device, &wgpu::SurfaceConfiguration { usage: wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::COPY_DST, format: OUTPUT_FORMAT, @@ -406,6 +436,12 @@ impl Core { ); } + /// Configures the renderer for a given target size. + pub fn configure(&mut self, pixel_size: UVec2) { + Self::configure_surface(&self.surface, &self.device, pixel_size); + self.depth = Self::create_depth_buffer(&self.device, pixel_size); + } + /// Redraws the entire surface. /// /// [`Self::configure`] must be called at least once before this. diff --git a/src/render/faces.rs b/src/render/faces.rs index e52e3e7..b6a2a20 100644 --- a/src/render/faces.rs +++ b/src/render/faces.rs @@ -4,7 +4,7 @@ use bytemuck::{Pod, Zeroable, bytes_of, cast_slice}; use glam::{Mat4, Vec3}; use wgpu::util::DeviceExt as _; -use crate::render::OUTPUT_FORMAT; +use crate::render::{DEPTH_FORMAT, OUTPUT_FORMAT}; #[derive(Debug, Clone, Copy, Pod, Zeroable)] #[repr(C)] @@ -109,7 +109,13 @@ impl Pipeline { topology: wgpu::PrimitiveTopology::TriangleList, ..Default::default() }, - depth_stencil: None, + depth_stencil: Some(wgpu::DepthStencilState { + format: DEPTH_FORMAT, + depth_write_enabled: true, + depth_compare: wgpu::CompareFunction::LessEqual, + stencil: wgpu::StencilState::default(), + bias: wgpu::DepthBiasState::default(), + }), multisample: wgpu::MultisampleState { count: 1, mask: !0, diff --git a/src/render/lines.rs b/src/render/lines.rs index 8a7ef94..b68fb86 100644 --- a/src/render/lines.rs +++ b/src/render/lines.rs @@ -4,7 +4,7 @@ use bytemuck::{Pod, Zeroable, bytes_of, cast_slice}; use glam::{Mat4, Vec3}; use wgpu::util::DeviceExt as _; -use crate::render::OUTPUT_FORMAT; +use crate::render::{DEPTH_FORMAT, OUTPUT_FORMAT}; #[derive(Debug, Clone, Copy, Pod, Zeroable)] #[repr(C)] @@ -91,7 +91,17 @@ impl Pipeline { topology: wgpu::PrimitiveTopology::LineList, ..Default::default() }, - depth_stencil: None, + depth_stencil: Some(wgpu::DepthStencilState { + format: DEPTH_FORMAT, + depth_write_enabled: true, + depth_compare: wgpu::CompareFunction::LessEqual, + stencil: wgpu::StencilState::default(), + bias: wgpu::DepthBiasState { + constant: -2, + slope_scale: 0., + clamp: 0., + }, + }), multisample: wgpu::MultisampleState { count: 1, mask: !0, diff --git a/src/render/mod.rs b/src/render/mod.rs index 435dc0d..2f629ee 100644 --- a/src/render/mod.rs +++ b/src/render/mod.rs @@ -4,3 +4,4 @@ pub mod lines; static SIMPLE_SHADER: &str = include_str!("simple.wgsl"); pub const OUTPUT_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Bgra8UnormSrgb; +pub const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth24Plus;