euv_engine/raytracing/pipeline/data/struct.rs
1use super::*;
2
3/// Ray-tracing quality settings shared by the CPU reference renderer and
4/// both GPU shader backends.
5///
6/// The values are packed into the GPU frame header so the CPU path and the
7/// shaders sample and bounce identically.
8#[derive(Clone, Copy, Data, Debug, New, PartialEq)]
9pub struct RayTraceSettings {
10 /// Supersampling grid resolution per axis. `1` traces one ray per
11 /// pixel; `4` traces sixteen and averages them. Valid range 1..=4.
12 #[get(type(copy))]
13 pub samples_per_axis: u32,
14 /// Maximum number of secondary bounces after the primary hit. `0`
15 /// still shades the primary hit. Valid range 0..=16.
16 #[get(type(copy))]
17 pub max_bounces: u32,
18}
19
20/// Read-only frame inputs shared by the CPU renderer and GPU header packer.
21///
22/// Named width and height fields make their roles explicit at call sites.
23/// The camera, lighting, and settings are borrowed; dimensions are copied.
24/// Constructing a frame neither clones those resources nor allocates memory.
25#[derive(Clone, Copy, Debug, Getter)]
26pub struct RayTraceFrame<'a> {
27 /// The camera supplying the eye, target, up, fov, and depth range.
28 #[get(type(copy))]
29 pub camera: &'a Camera3D,
30 /// The lights, ambient, and shading eye.
31 #[get(type(copy))]
32 pub lights: &'a LightingUniforms,
33 /// The sampling grid and bounce limit.
34 #[get(type(copy))]
35 pub settings: &'a RayTraceSettings,
36 /// The frame width in pixels.
37 #[get(type(copy))]
38 pub width: u32,
39 /// The frame height in pixels.
40 #[get(type(copy))]
41 pub height: u32,
42}
43
44/// A validated, immutable description of one frame's camera.
45///
46/// Building a [`FrameBasis`] performs every check the packed frame header
47/// and the CPU pixel loop both need: the settings are in range, the
48/// dimensions are usable, the field of view lies in `(0, PI)`, the depth
49/// range satisfies `0 <= near < far` and survives the `f32` narrowing, and
50/// the camera basis is non-degenerate. Holding the result means neither
51/// path has to re-derive the basis or re-run the validation, and neither
52/// can accept a frame the other rejects.
53#[derive(Clone, Copy, Data, Debug, PartialEq)]
54pub(crate) struct FrameBasis {
55 /// The world-space eye position.
56 #[get(pub(crate), type(copy))]
57 pub(crate) eye: Vector3D,
58 /// The unit forward direction, from the eye toward the target.
59 #[get(pub(crate), type(copy))]
60 pub(crate) forward: Vector3D,
61 /// The unit right direction, `forward` crossed with the camera up.
62 #[get(pub(crate), type(copy))]
63 pub(crate) right: Vector3D,
64 /// The unit up direction, `right` crossed with `forward`.
65 #[get(pub(crate), type(copy))]
66 pub(crate) up: Vector3D,
67 /// `tan(fov / 2)`, the factor that makes the rendered vertical field
68 /// of view exactly `fov`.
69 #[get(pub(crate), type(copy))]
70 pub(crate) tan_half_fov: f64,
71 /// `width / height`.
72 #[get(pub(crate), type(copy))]
73 pub(crate) aspect: f64,
74 /// The frame width in pixels.
75 #[get(pub(crate), type(copy))]
76 pub(crate) width: u32,
77 /// The frame height in pixels.
78 #[get(pub(crate), type(copy))]
79 pub(crate) height: u32,
80 /// The near clipping distance used as the primary ray's `t_min`.
81 #[get(pub(crate), type(copy))]
82 pub(crate) near_t: f64,
83 /// The far clipping distance used as the primary ray's `t_max`.
84 #[get(pub(crate), type(copy))]
85 pub(crate) far_t: f64,
86}