concinnity-core 0.19.24

Runtime vocabulary for the Concinnity engine: GPU layouts, ECS components, registry, CPU kernels
Documentation
//! The passes that draw their own geometry into the main target: projected
//! decals, world-space lines, and the GPU particle system.

/// Per-frame view inputs to the projected-decal pass. Matches `DecalView` in
/// `shaders/decal.slang`. 144 bytes.
#[derive(Copy, Clone, bytemuck::NoUninit)]
#[repr(C)]
pub struct DecalView {
    /// View-projection matrix used by the main pass (jittered when TAA is on).
    pub vp: [[f32; 4]; 4],
    /// Inverse of `vp`. The fragment shader uses it to reconstruct world space
    /// from the depth attachment at each pixel.
    pub inv_vp: [[f32; 4]; 4],
    /// HDR target dimensions in pixels: drives the screen->NDC conversion.
    pub viewport: [f32; 2],
    /// Padding so the field layout matches the shader-side struct.
    pub _pad: [f32; 2],
}

/// Per-decal uniforms uploaded before each draw. Matches `DecalParams` in
/// `shaders/decal.slang`. 160 bytes (two float4x4s, a float4 tint, four scalars).
#[derive(Copy, Clone, bytemuck::NoUninit)]
#[repr(C)]
pub struct DecalParams {
    /// Model matrix, column-major.
    pub model: [[f32; 4]; 4],
    /// Inverse model matrix, column-major.
    pub inv_model: [[f32; 4]; 4],
    /// Linear RGBA tint multiplied into the sampled image.
    pub tint: [f32; 4],
    /// Exponent of the edge fade curve.
    pub fade_pow: f32,
    /// Padding so the field layout matches the shader-side struct.
    pub _pad0: f32,
    /// Padding so the field layout matches the shader-side struct.
    pub _pad1: f32,
    /// Padding so the field layout matches the shader-side struct.
    pub _pad2: f32,
}

/// Per-frame view inputs to the line pass. Matches `LineView` in
/// `shaders/line.slang`. 80 bytes.
#[derive(Copy, Clone, bytemuck::NoUninit)]
#[repr(C)]
pub struct LineView {
    /// View-projection matrix used by the main pass (jittered when TAA is on),
    /// so a line lands on the same pixel the geometry it sits on did.
    pub vp: [[f32; 4]; 4],
    /// Alpha multiplier applied where a line falls behind scene geometry.
    pub occluded_alpha: f32,
    /// Padding so the field layout matches the shader-side struct.
    pub _pad: [f32; 3],
}

/// Per-frame view inputs to the particle render pass. Matches `ParticleView` in
/// `shaders/particle.slang`. 96 bytes.
#[derive(Copy, Clone, bytemuck::NoUninit)]
#[repr(C)]
pub struct ParticleView {
    /// View-projection matrix used by the main pass.
    pub vp: [[f32; 4]; 4],
    /// World-space camera right vector: drives the first billboard axis. The
    /// shader reads a float4 whose trailing component is unused padding.
    pub cam_right: [f32; 3],
    /// Padding so the field layout matches the shader-side struct.
    pub _pad0: f32,
    /// World-space camera up vector: drives the second billboard axis.
    pub cam_up: [f32; 3],
    /// Padding so the field layout matches the shader-side struct.
    pub _pad1: f32,
}

/// One particle slot in the pool the simulation kernel writes and the render
/// pair reads. Matches `Particle` in `shaders/particle_types.slang`, which
/// spells the same 32 bytes as two float4 lanes.
#[derive(Copy, Clone, Default)]
#[repr(C)]
pub struct GpuParticle {
    /// World-space position.
    pub position: [f32; 3],
    /// Seconds since the particle spawned.
    pub age: f32,
    /// World-space velocity in units per second.
    pub velocity: [f32; 3],
    /// Total lifetime in seconds.
    pub lifetime: f32,
}

/// Per-dispatch parameters for the `rt_skin` compute kernel, which deforms one
/// skinned object's bind-pose vertices into the shared deformed buffer the RT
/// acceleration structure traces. Matches `SkinParams` in `rt_skin.slang`.
///
/// Metal writes it to buffer(3), Vulkan pushes it, DirectX takes it as root
/// constants at b0.
#[repr(C)]
#[derive(Clone, Copy, bytemuck::NoUninit)]
pub struct SkinParams {
    /// First vertex of this object's region in the shared vertex buffer.
    pub vertex_base: u32,
    /// Vertices this dispatch deforms.
    pub vertex_count: u32,
    /// Palette size; joint indices are clamped below it.
    pub joint_count: u32,
    /// Morph targets in the delta buffer; zero when the object has none.
    pub target_count: u32,
}

/// Per-dispatch parameters for the `model_history` compute kernel, which
/// snapshots this frame's model matrices out of the bindless object buffer into
/// the frame's model-history ring slot. Matches `ModelHistoryParams` in
/// `model_history.slang`.
///
/// Every backend binds it at the kernel's first slot: Metal at buffer(0),
/// Vulkan as set 0 binding 0, DirectX as root constants at b0.
#[repr(C)]
#[derive(Clone, Copy, bytemuck::NoUninit)]
pub struct ModelHistoryParams {
    /// Cull records to snapshot: the object buffer's whole length.
    pub record_count: u32,
    /// Pads the block to the 16-byte floor a constant buffer binds at.
    pub _pad: [u32; 3],
}

#[cfg(test)]
mod model_history_tests {
    use super::*;
    use core::mem::{offset_of, size_of};

    // One uint padded to the 16-byte constant-buffer floor.
    #[test]
    fn model_history_params_layout_matches_the_shader() {
        assert_eq!(size_of::<ModelHistoryParams>(), 16);
        assert_eq!(offset_of!(ModelHistoryParams, record_count), 0);
        assert_eq!(offset_of!(ModelHistoryParams, _pad), 4);
    }
}