notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

material.rs (4350B)


      1 use crate::GpuData;
      2 use crate::texture::{make_1x1_rgba8, texture_layout_entry};
      3 use glam::Vec4;
      4 
      5 #[repr(C)]
      6 #[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
      7 pub struct MaterialUniform {
      8     pub base_color_factor: glam::Vec4, // rgba
      9     pub metallic_factor: f32,
     10     pub roughness_factor: f32,
     11     pub ao_strength: f32,
     12     pub _pad0: f32,
     13 }
     14 
     15 pub struct MaterialGpu {
     16     pub _uniform: MaterialUniform,
     17     pub _buffer: wgpu::Buffer,
     18     pub bindgroup: wgpu::BindGroup,
     19 }
     20 
     21 pub fn make_material_gpudata(
     22     device: &wgpu::Device,
     23     queue: &wgpu::Queue,
     24 ) -> (GpuData<MaterialUniform>, wgpu::BindGroupLayout) {
     25     let material_uniform = MaterialUniform {
     26         base_color_factor: Vec4::new(1.0, 0.1, 0.1, 1.0),
     27         metallic_factor: 1.0,
     28         roughness_factor: 0.1,
     29         ao_strength: 1.0,
     30         _pad0: 0.0,
     31     };
     32 
     33     let material_buf = device.create_buffer(&wgpu::BufferDescriptor {
     34         label: Some("material"),
     35         size: std::mem::size_of::<MaterialUniform>() as u64,
     36         usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
     37         mapped_at_creation: false,
     38     });
     39 
     40     let material_sampler = device.create_sampler(&wgpu::SamplerDescriptor {
     41         label: Some("material_sampler"),
     42         address_mode_u: wgpu::AddressMode::Repeat,
     43         address_mode_v: wgpu::AddressMode::Repeat,
     44         address_mode_w: wgpu::AddressMode::Repeat,
     45         mag_filter: wgpu::FilterMode::Linear,
     46         min_filter: wgpu::FilterMode::Linear,
     47         mipmap_filter: wgpu::FilterMode::Linear,
     48         ..Default::default()
     49     });
     50 
     51     // Default textures
     52     let basecolor_view = make_1x1_rgba8(
     53         device,
     54         queue,
     55         wgpu::TextureFormat::Rgba8UnormSrgb,
     56         [255, 255, 255, 255],
     57         "basecolor_1x1",
     58     );
     59 
     60     let mr_view = make_1x1_rgba8(
     61         device,
     62         queue,
     63         wgpu::TextureFormat::Rgba8Unorm,
     64         [0, 255, 0, 255], // G=roughness=1, B=metallic=0 (A unused)
     65         "mr_1x1",
     66     );
     67 
     68     let normal_view = make_1x1_rgba8(
     69         device,
     70         queue,
     71         wgpu::TextureFormat::Rgba8Unorm,
     72         [128, 128, 255, 255],
     73         "normal_1x1",
     74     );
     75 
     76     let material_bgl = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
     77         label: Some("material_bgl"),
     78         entries: &[
     79             // uniform
     80             wgpu::BindGroupLayoutEntry {
     81                 binding: 0,
     82                 visibility: wgpu::ShaderStages::FRAGMENT,
     83                 ty: wgpu::BindingType::Buffer {
     84                     ty: wgpu::BufferBindingType::Uniform,
     85                     has_dynamic_offset: false,
     86                     min_binding_size: None,
     87                 },
     88                 count: None,
     89             },
     90             // sampler
     91             wgpu::BindGroupLayoutEntry {
     92                 binding: 1,
     93                 visibility: wgpu::ShaderStages::FRAGMENT,
     94                 ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
     95                 count: None,
     96             },
     97             // baseColor (sRGB)
     98             texture_layout_entry(2),
     99             // metallicRougness (linear)
    100             texture_layout_entry(3),
    101             // normal (linear)
    102             texture_layout_entry(4),
    103         ],
    104     });
    105 
    106     let material_bg = device.create_bind_group(&wgpu::BindGroupDescriptor {
    107         label: Some("material_bg"),
    108         layout: &material_bgl,
    109         entries: &[
    110             wgpu::BindGroupEntry {
    111                 binding: 0,
    112                 resource: material_buf.as_entire_binding(),
    113             },
    114             wgpu::BindGroupEntry {
    115                 binding: 1,
    116                 resource: wgpu::BindingResource::Sampler(&material_sampler),
    117             },
    118             wgpu::BindGroupEntry {
    119                 binding: 2,
    120                 resource: wgpu::BindingResource::TextureView(&basecolor_view),
    121             },
    122             wgpu::BindGroupEntry {
    123                 binding: 3,
    124                 resource: wgpu::BindingResource::TextureView(&mr_view),
    125             },
    126             wgpu::BindGroupEntry {
    127                 binding: 4,
    128                 resource: wgpu::BindingResource::TextureView(&normal_view),
    129             },
    130         ],
    131     });
    132 
    133     (
    134         GpuData::<MaterialUniform> {
    135             data: material_uniform,
    136             buffer: material_buf,
    137             bindgroup: material_bg,
    138         },
    139         material_bgl,
    140     )
    141 }