Skip to main content

concinnity_render/uniforms/
view.rs

1//! The camera blocks: what the forward pass and the G-buffer pre-pass need to
2//! place a fragment, and the per-draw model pair the pre-pass differentiates for
3//! motion vectors.
4
5/// Per-frame view-projection uniforms, uploaded once per frame and shared across
6/// every draw in it. `view` is the standalone view matrix the vertex shader uses
7/// to compute view-space depth for cascade selection in the fragment shader.
8///
9/// **The field names are a published contract.** A world-authored Metal shader
10/// declares its own `ViewUniforms` and binds it at Metal buffer(0); the runtime
11/// validator (`metal::shader_layout`) compares that declaration against this
12/// struct field by field, by name. Renaming one here rejects every world shader
13/// that spells it the old way. The `.slang` source declares the same bytes with
14/// its own spelling (`view_mat`, and `cam_x`/`cam_y`/`cam_z` in place of
15/// `cam_pos`), which is why the two are checked as byte ranges rather than by
16/// name.
17#[derive(Copy, Clone, bytemuck::NoUninit)]
18#[repr(C)]
19pub struct ViewUniforms {
20    /// Combined view-projection matrix (column-major).
21    pub vp: [[f32; 4]; 4],
22    /// Camera view matrix (column-major). Used to compute view-space depth
23    /// in the vertex shader for shadow cascade selection.
24    pub view: [[f32; 4]; 4],
25    /// Elapsed seconds, available to shaders for animation.
26    pub elapsed: f32,
27    /// 1.0 when a screen-space / ray-traced reflection resolve composites this
28    /// frame, else 0.0. The forward fragment shader uses it to yield the sharp
29    /// specular for glossy surfaces to that resolve (whose miss-fallback samples
30    /// the same probe set), so a glossy surface does not show both the
31    /// parallax-approximate forward probe reflection and the exact resolved one.
32    pub reflections_enabled: f32,
33    /// World-space camera position (packed_float3 in the MSL contract, alignment 4).
34    pub cam_pos: [f32; 3],
35    /// Number of mip levels in the bound IBL prefilter cubemap. 0 means
36    /// "no EnvironmentMap bound": the fragment shader uses this as the IBL
37    /// enable flag and falls back to a flat ambient placeholder.
38    pub prefilter_mip_count: f32,
39    /// 1.0 while the unlit view mode is active: shade_surface returns the base
40    /// color before lighting. Occupies what was pad space, so the offsets in
41    /// the user-shader binding contract are unchanged.
42    pub shade_mode: f32,
43    /// End-padding: the shader rounds the block up to a multiple of float4x4's
44    /// 16-byte alignment, so the upload rounds explicitly to match.
45    pub _end_pad: f32,
46}
47
48/// Per-frame view inputs to the unified G-buffer pre-pass. The jittered current
49/// VP drives the rasterised position (matching the main pass); `view` takes the
50/// normal + position into view space (where SSR / SSAO / SSGI / RT work); the
51/// un-jittered cur/prev VPs derive a jitter-free motion vector. Matches `GbView`
52/// in `shaders/gbuffer_prepass.slang`. 256 bytes (four float4x4, all naturally
53/// 16-aligned, no padding).
54#[derive(Copy, Clone, bytemuck::NoUninit)]
55#[repr(C)]
56pub struct GBufferView {
57    /// View-projection with this frame's TAA jitter applied.
58    pub jittered_vp: [[f32; 4]; 4],
59    /// This frame's unjittered view-projection.
60    pub cur_vp: [[f32; 4]; 4],
61    /// The previous frame's unjittered view-projection.
62    pub prev_vp: [[f32; 4]; 4],
63    /// View matrix, column-major.
64    pub view: [[f32; 4]; 4],
65}
66
67/// Per-draw model matrices for the G-buffer pre-pass. Matches `GbModel` in
68/// `shaders/gbuffer_prepass.slang`, which Metal and DirectX bind as a constant
69/// buffer; Vulkan carries the same pair plus the roughness in one push-constant
70/// block (`vulkan::uniforms::GbModelPush`), because a pipeline layout may declare
71/// only one. For a static or skinned object with no motion the caller sets
72/// `prev == cur`.
73#[derive(Copy, Clone, bytemuck::NoUninit)]
74#[repr(C)]
75pub struct GBufferModel {
76    /// This frame's model matrix, column-major.
77    pub cur_model: [[f32; 4]; 4],
78    /// The previous frame's model matrix, for velocity.
79    pub prev_model: [[f32; 4]; 4],
80}