fix uniform buffer mismatch between cord-render and cord-shader WGSL

This commit is contained in:
jess 2026-03-31 13:00:07 -07:00
parent 97653580e5
commit 3804075537
4 changed files with 30 additions and 18 deletions

View File

@ -9,10 +9,8 @@ keywords = ["wgpu", "raymarching", "sdf", "renderer", "3d"]
categories = ["graphics", "rendering"]
[dependencies]
cord-shader = { path = "../cord-shader" }
wgpu = "24"
winit = "0.30"
pollster = "0.4"
bytemuck = { version = "1", features = ["derive"] }
glam = "0.29"
anyhow = "1"

View File

@ -217,8 +217,9 @@ async fn init_render_state(
};
surface.configure(&device, &config);
let pipeline = RenderPipeline::new(&device, format, wgsl_source)?;
let camera = Camera::new(bounding_radius as f32);
let scene_scale = (bounding_radius as f32).max(0.1);
let pipeline = RenderPipeline::new(&device, format, wgsl_source, scene_scale)?;
let camera = Camera::new(scene_scale);
Ok(RenderState {
window,

View File

@ -2,26 +2,33 @@ use crate::camera::Camera;
use anyhow::Result;
use bytemuck::{Pod, Zeroable};
/// Matches the WGSL `Uniforms` struct byte-for-byte.
///
/// WGSL alignment: vec3<f32> aligns to 16 bytes, vec2 to 8, vec4 to 16.
/// Total: 80 bytes (multiple of 16).
#[repr(C)]
#[derive(Debug, Copy, Clone, Pod, Zeroable)]
struct Uniforms {
resolution: [f32; 2],
time: f32,
_pad0: f32,
camera_pos: [f32; 3],
_pad1: f32,
camera_target: [f32; 3],
fov: f32,
resolution: [f32; 2], // offset 0
viewport_offset: [f32; 2], // offset 8
camera_pos: [f32; 3], // offset 16 (vec3 align 16)
time: f32, // offset 28
camera_target: [f32; 3], // offset 32 (vec3 align 16)
fov: f32, // offset 44
render_flags: [f32; 4], // offset 48 (vec4 align 16)
scene_scale: f32, // offset 64
_pad: [f32; 3], // offset 68
}
pub struct RenderPipeline {
pipeline: wgpu::RenderPipeline,
uniform_buffer: wgpu::Buffer,
bind_group: wgpu::BindGroup,
scene_scale: f32,
}
impl RenderPipeline {
pub fn new(device: &wgpu::Device, format: wgpu::TextureFormat, wgsl_source: &str) -> Result<Self> {
pub fn new(device: &wgpu::Device, format: wgpu::TextureFormat, wgsl_source: &str, scene_scale: f32) -> Result<Self> {
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: Some("scene"),
source: wgpu::ShaderSource::Wgsl(wgsl_source.into()),
@ -42,7 +49,9 @@ impl RenderPipeline {
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
min_binding_size: None,
min_binding_size: wgpu::BufferSize::new(
std::mem::size_of::<Uniforms>() as u64
),
},
count: None,
}],
@ -92,7 +101,7 @@ impl RenderPipeline {
cache: None,
});
Ok(Self { pipeline, uniform_buffer, bind_group })
Ok(Self { pipeline, uniform_buffer, bind_group, scene_scale })
}
pub fn update_uniforms(
@ -105,12 +114,14 @@ impl RenderPipeline {
) {
let uniforms = Uniforms {
resolution: [width as f32, height as f32],
time,
_pad0: 0.0,
viewport_offset: [0.0, 0.0],
camera_pos: camera.position(),
_pad1: 0.0,
time,
camera_target: camera.target,
fov: camera.fov,
render_flags: [1.0, 1.0, 1.0, 0.0],
scene_scale: self.scene_scale,
_pad: [0.0; 3],
};
queue.write_buffer(&self.uniform_buffer, 0, bytemuck::bytes_of(&uniforms));
}

View File

@ -87,7 +87,9 @@ r#"struct Uniforms {
fov: f32,
render_flags: vec4<f32>,
scene_scale: f32,
_pad: vec3<f32>,
_pad1: f32,
_pad2: f32,
_pad3: f32,
};
@group(0) @binding(0) var<uniform> u: Uniforms;