#[derive(Copy, Clone, bytemuck::NoUninit)]
#[repr(C)]
pub struct ModelUniforms {
pub model: [[f32; 4]; 4],
}
#[derive(Copy, Clone, bytemuck::NoUninit)]
#[repr(C)]
pub struct SsrPrepassMat {
pub roughness: f32,
pub _pad: [f32; 3],
}
#[derive(Copy, Clone, bytemuck::NoUninit)]
#[repr(C)]
pub struct CullUniforms {
pub planes: [[f32; 4]; 6],
pub cam_pos: [f32; 3],
pub object_count: u32,
pub prev_view_proj: [[f32; 4]; 4],
pub hiz_size: [f32; 2],
pub hiz_mip_count: u32,
pub hiz_enabled: u32,
pub skinned_base: u32,
pub cascade_base: u32,
pub bucket_count: u32,
pub _pad_skin: u32,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct VelocityUniforms {
pub jittered_vp: [[f32; 4]; 4],
pub cur_vp: [[f32; 4]; 4],
pub prev_vp: [[f32; 4]; 4],
}
#[derive(Copy, Clone, bytemuck::NoUninit)]
#[repr(C)]
pub struct RaymarchView {
pub vp: [[f32; 4]; 4],
pub inv_vp: [[f32; 4]; 4],
pub cam_pos: [f32; 4],
pub viewport: [f32; 2],
pub time: f32,
pub prefilter_mip_count: f32,
}
#[derive(Copy, Clone, bytemuck::NoUninit)]
#[repr(C)]
pub struct RaymarchVolumeUniforms {
pub centre: [f32; 3],
pub _pad0: f32,
pub extent: [f32; 3],
pub _pad1: f32,
pub cone_ratio: f32,
pub max_distance: f32,
pub max_steps: i32,
pub receive_shadows: i32,
pub params: [f32; crate::components::sdf_volume::SDF_PARAMS_LEN],
}
#[derive(Copy, Clone, bytemuck::NoUninit)]
#[repr(C)]
pub struct RaymarchShadowCascade {
pub cascade_idx: u32,
pub _pad: [u32; 3],
}
pub const MAX_MORPH_TARGETS: usize = 64;
#[repr(C)]
#[derive(Clone, Copy, bytemuck::NoUninit)]
pub struct VsMorphParams {
pub vertex_base: u32,
pub vertex_count: u32,
pub target_count: u32,
pub _pad: u32,
pub weights: [f32; MAX_MORPH_TARGETS],
}
#[cfg(test)]
mod tests {
use super::*;
use core::mem::{offset_of, size_of};
#[test]
fn cull_uniforms_layout_matches_msl() {
assert_eq!(size_of::<CullUniforms>(), 208);
assert_eq!(offset_of!(CullUniforms, planes), 0);
assert_eq!(offset_of!(CullUniforms, cam_pos), 96);
assert_eq!(offset_of!(CullUniforms, object_count), 108);
assert_eq!(offset_of!(CullUniforms, prev_view_proj), 112);
assert_eq!(offset_of!(CullUniforms, hiz_size), 176);
assert_eq!(offset_of!(CullUniforms, hiz_mip_count), 184);
assert_eq!(offset_of!(CullUniforms, hiz_enabled), 188);
assert_eq!(offset_of!(CullUniforms, skinned_base), 192);
assert_eq!(offset_of!(CullUniforms, cascade_base), 196);
assert_eq!(offset_of!(CullUniforms, bucket_count), 200);
assert_eq!(size_of::<CullUniforms>() % 16, 0);
}
#[test]
fn velocity_uniforms_layout_matches_msl() {
assert_eq!(size_of::<VelocityUniforms>(), 192);
assert_eq!(offset_of!(VelocityUniforms, jittered_vp), 0);
assert_eq!(offset_of!(VelocityUniforms, cur_vp), 64);
assert_eq!(offset_of!(VelocityUniforms, prev_vp), 128);
}
#[test]
fn raymarch_view_layout_matches_msl() {
assert_eq!(size_of::<RaymarchView>(), 160);
assert_eq!(offset_of!(RaymarchView, vp), 0);
assert_eq!(offset_of!(RaymarchView, inv_vp), 64);
assert_eq!(offset_of!(RaymarchView, cam_pos), 128);
assert_eq!(offset_of!(RaymarchView, viewport), 144);
assert_eq!(offset_of!(RaymarchView, time), 152);
assert_eq!(offset_of!(RaymarchView, prefilter_mip_count), 156);
assert_eq!(size_of::<RaymarchView>() % 16, 0);
}
#[test]
fn raymarch_volume_uniforms_layout_matches_msl() {
assert_eq!(size_of::<RaymarchVolumeUniforms>(), 176);
assert_eq!(offset_of!(RaymarchVolumeUniforms, centre), 0);
assert_eq!(offset_of!(RaymarchVolumeUniforms, _pad0), 12);
assert_eq!(offset_of!(RaymarchVolumeUniforms, extent), 16);
assert_eq!(offset_of!(RaymarchVolumeUniforms, _pad1), 28);
assert_eq!(offset_of!(RaymarchVolumeUniforms, cone_ratio), 32);
assert_eq!(offset_of!(RaymarchVolumeUniforms, max_distance), 36);
assert_eq!(offset_of!(RaymarchVolumeUniforms, max_steps), 40);
assert_eq!(offset_of!(RaymarchVolumeUniforms, receive_shadows), 44);
assert_eq!(offset_of!(RaymarchVolumeUniforms, params), 48);
}
#[test]
fn raymarch_shadow_cascade_layout_matches_msl() {
assert_eq!(size_of::<RaymarchShadowCascade>(), 16);
assert_eq!(offset_of!(RaymarchShadowCascade, cascade_idx), 0);
assert_eq!(offset_of!(RaymarchShadowCascade, _pad), 4);
}
#[test]
fn vs_morph_params_layout_matches_msl() {
assert_eq!(size_of::<VsMorphParams>(), 272);
assert_eq!(offset_of!(VsMorphParams, vertex_base), 0);
assert_eq!(offset_of!(VsMorphParams, vertex_count), 4);
assert_eq!(offset_of!(VsMorphParams, target_count), 8);
assert_eq!(offset_of!(VsMorphParams, _pad), 12);
assert_eq!(offset_of!(VsMorphParams, weights), 16);
}
}