rend3_pbr/
uniforms.rs

1use glam::{Mat4, Vec4};
2use rend3::{
3    resources::CameraManager,
4    util::{bind_merge::BindGroupBuilder, frustum::ShaderFrustum},
5};
6use wgpu::{
7    util::{BufferInitDescriptor, DeviceExt},
8    BindGroup, BufferUsages, Device,
9};
10
11use crate::common::interfaces::ShaderInterfaces;
12
13#[derive(Debug, Copy, Clone)]
14#[repr(C, align(16))]
15pub struct ShaderCommonUniform {
16    view: Mat4,
17    view_proj: Mat4,
18    inv_view: Mat4,
19    inv_origin_view_proj: Mat4,
20    frustum: ShaderFrustum,
21    ambient: Vec4,
22}
23
24unsafe impl bytemuck::Zeroable for ShaderCommonUniform {}
25unsafe impl bytemuck::Pod for ShaderCommonUniform {}
26
27pub struct CreateShaderUniformArgs<'a> {
28    pub device: &'a Device,
29    pub camera: &'a CameraManager,
30
31    pub interfaces: &'a ShaderInterfaces,
32
33    pub ambient: Vec4,
34}
35
36pub fn create_shader_uniform(args: CreateShaderUniformArgs<'_>) -> BindGroup {
37    profiling::scope!("create uniforms");
38
39    let view = args.camera.view();
40
41    let uniforms = ShaderCommonUniform {
42        view,
43        view_proj: args.camera.view_proj(),
44        inv_view: view.inverse(),
45        inv_origin_view_proj: args.camera.origin_view_proj().inverse(),
46        frustum: ShaderFrustum::from_matrix(args.camera.proj()),
47        ambient: args.ambient,
48    };
49
50    let buffer = args.device.create_buffer_init(&BufferInitDescriptor {
51        label: Some("shader uniform"),
52        contents: bytemuck::bytes_of(&uniforms),
53        usage: BufferUsages::UNIFORM,
54    });
55
56    BindGroupBuilder::new(Some("shader uniform"))
57        .with_buffer(&buffer)
58        .build(args.device, &args.interfaces.uniform_bgl)
59}