use wgpu::util::DeviceExt; #[repr(C)] #[derive(Default, Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] struct Material { pub albedo: [f32; 4], } impl Material { pub fn set_albedo(&mut self, r: f32, g: f32, b:f32) { self.albedo[0] = r; self.albedo[1] = g; self.albedo[2] = b; } } pub struct MaterialBuffer { materials: [Material; 256], pub buffer: wgpu::Buffer, pub bind_layout: wgpu::BindGroupLayout, pub bind_group: wgpu::BindGroup } impl MaterialBuffer { pub fn new(device: &wgpu::Device) -> Self { // Create values let mut materials: [Material; 256] = [Default::default(); 256]; materials[0].set_albedo(0.41,0.33,0.20); materials[1].set_albedo(0.15,0.5,0.05); materials[2].set_albedo(0.8,0.8,0.8); // Create buffer let buffer = device.create_buffer_init( &wgpu::util::BufferInitDescriptor { label: Some("Materials buffer"), contents: bytemuck::cast_slice(&materials), usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST, } ); // Create bind group let bind_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { entries: &[ wgpu::BindGroupLayoutEntry { binding: 0, visibility: wgpu::ShaderStage::FRAGMENT, ty: wgpu::BindingType::Buffer { ty: wgpu::BufferBindingType::Uniform, has_dynamic_offset: false, min_binding_size: None, }, count: None, } ], label: Some("Materials buffer layout"), }); let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { layout: &bind_layout, entries: &[ wgpu::BindGroupEntry { binding: 0, resource: buffer.as_entire_binding(), } ], label: Some("Materials buffer group"), }); // Done MaterialBuffer { buffer, materials, bind_layout, bind_group } } }