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}