From 344ecc3450c9cba618962431b82a526d0367d620 Mon Sep 17 00:00:00 2001 From: Bradlee Speice Date: Sat, 27 Jun 2026 11:02:19 -0400 Subject: [PATCH] Add missing documentation --- enkou-shaders/src/camera.rs | 17 ++++++++++++----- enkou-shaders/src/chaos_game.rs | 19 +++++++++++++++++++ enkou-shaders/src/lib.rs | 8 ++++++-- enkou-shaders/src/transform.rs | 10 +++++++++- 4 files changed, 46 insertions(+), 8 deletions(-) diff --git a/enkou-shaders/src/camera.rs b/enkou-shaders/src/camera.rs index a05125b..7844233 100644 --- a/enkou-shaders/src/camera.rs +++ b/enkou-shaders/src/camera.rs @@ -1,7 +1,14 @@ +//! # Camera +//! +//! Map points from the IFS coordinate system to pixel coordinates. This is a lossy transformation. use bytemuck::{Pod, Zeroable}; use glam::{Affine2, IVec2, UVec2, Vec2, vec2}; use libm::powf; +/// Settings used to map IFS coordinates to pixel coordinates. +/// +/// The camera is itself an affine transformation, capable of zoom, rotation, and translation +/// of the IFS coordinates before rendering to the final image. #[derive(Copy, Clone, Pod, Zeroable)] #[repr(C)] pub struct Camera { @@ -10,10 +17,10 @@ pub struct Camera { } impl Camera { - /// Construct a new camera that maps IFS coordinates to pixel coordinates. + /// Construct a new camera for translating IFS coordinates to pixel coordinates. /// - /// The camera object is itself an affine transformation, but it's helpful to express - /// the parameters in individual steps, and compose them internally. + /// While the camera is implemented as a single affine transformation, it's helpful + /// to express the transform steps individually. /// /// # Arguments /// @@ -24,7 +31,7 @@ impl Camera { /// `center` translation, so it is about the new origin. /// * `zoom` - Zoom factor applied to IFS coordinates. IFS coordinates are scaled by /// `pow(2, zoom)`, so a zoom factor of 0 is the identity. - /// * `scale` - Pixels per unit of IFS coordinates. By default, this parameter is chosen such + /// * `scale` - Pixels per unit of IFS coordinates. This parameter is usually chosen such /// that the largest dimension will cover the range `[-2, 2]`, but values higher or lower /// can be used as a secondary zoom. pub fn new(dimensions: UVec2, center: Vec2, rotate: f32, zoom: Vec2, scale: Vec2) -> Camera { @@ -67,7 +74,7 @@ impl Camera { self.transform.transform_point2(point).as_ivec2() } - /// Map a point from IFS coordinates to pixel coordinates (like [`transform_point`]), + /// Map a point from IFS coordinates to pixel coordinates (like [`transform_point`](Camera::transform_point)), /// and check that the result is within the provided image dimensions. pub fn transform_point_to_image(&self, point: Vec2) -> Option { let pixel_coordinates = self.transform_point(point); diff --git a/enkou-shaders/src/chaos_game.rs b/enkou-shaders/src/chaos_game.rs index 56190f0..4d59e52 100644 --- a/enkou-shaders/src/chaos_game.rs +++ b/enkou-shaders/src/chaos_game.rs @@ -1,3 +1,17 @@ +//! # Chaos Game +//! +//! Fractal flames are a class of +//! [iterated function systems](https://en.wikipedia.org/wiki/Iterated_function_system) +//! that generate images following a simple algorithm: +//! +//! - Pick a starting point `(x, y)` +//! - Iterate: +//! - Pick a [`Transform`] from the set of available transforms +//! - Apply the current point to the chosen transform, generating a new point `(x, y)` +//! - Plot the new point `(x, y)` +//! +//! This algorithm is also known as the ["chaos game"](https://en.wikipedia.org/wiki/Chaos_game), +//! and it forms the basic system for producing images. use crate::transform::Transform; use glam::{Vec2, vec2}; use rand::distr::{Distribution, StandardUniform}; @@ -42,6 +56,10 @@ pub fn step_chaos_game( ) } +/// Iterator for chaos game state. Holds the current point and references to all other data +/// necessary to generate fractal flame images. +/// +/// New points in the chaos game are produced by iterating on the chaos game. pub struct ChaosGame<'a, R: Rng> { current_point: Vec2, rng: &'a mut R, @@ -50,6 +68,7 @@ pub struct ChaosGame<'a, R: Rng> { } impl<'a, R: Rng> ChaosGame<'a, R> { + /// Create a new chaos game iterator pub fn new(rng: &'a mut R, transforms: &'a [Transform], weights: &'a [f32]) -> Self { let current_point = vec2(rng.sample(BiUnit), rng.sample(BiUnit)); ChaosGame { diff --git a/enkou-shaders/src/lib.rs b/enkou-shaders/src/lib.rs index b46424a..d3d2a4a 100644 --- a/enkou-shaders/src/lib.rs +++ b/enkou-shaders/src/lib.rs @@ -13,9 +13,10 @@ use glam::{Affine2, Vec3, Vec4, vec2, vec3}; use spirv_std::num_traits::Float; use spirv_std::spirv; -/// Utility trait for [`Affine2`] to convert between `flam3` notation and [`glam`]. +/// Utility trait to convert between `flam3` notation and [`glam`]. +#[allow(missing_docs)] pub trait Coefficients2 { - /// Convert affine transformation coefficients to the [`Affine2`] representation. + /// Convert affine transformation coefficients to the [`glam`] representation. /// Parameters use the following form: /// /// ```text @@ -77,6 +78,7 @@ impl Coefficients2 for Affine2 { #[derive(Copy, Clone, Pod, Zeroable)] #[repr(C)] +#[allow(missing_docs)] pub struct ShaderConstants { pub width: u32, pub height: u32, @@ -84,11 +86,13 @@ pub struct ShaderConstants { } #[spirv(fragment)] +#[allow(missing_docs)] pub fn main_fs(vtx_color: Vec3, output: &mut Vec4) { *output = Vec4::from((vtx_color, 1.)); } #[spirv(vertex)] +#[allow(missing_docs)] pub fn main_vs( #[spirv(vertex_index)] vert_id: i32, #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] constants: &ShaderConstants, diff --git a/enkou-shaders/src/transform.rs b/enkou-shaders/src/transform.rs index e343827..fddcb56 100644 --- a/enkou-shaders/src/transform.rs +++ b/enkou-shaders/src/transform.rs @@ -1,17 +1,25 @@ +//! # Transform +//! +//! Transforms are the "functions" in an iterated function system. They take in a point, +//! and generate a new point. For fractal flames, transforms are always affine, +//! but produce more interesting images once we add variations. use bytemuck::{Pod, Zeroable}; use glam::{Affine2, Vec2}; +/// Affine transform for use in the [`chaos_game`](crate::chaos_game). #[derive(Copy, Clone, Pod, Zeroable)] #[repr(C)] pub struct Transform { - pub coefficients: Affine2, + coefficients: Affine2, } impl Transform { + /// Create a new transform from an affine transformation matrix pub fn new(coefficients: Affine2) -> Self { Transform { coefficients } } + /// Apply this transform to a point in IFS coordinates, producing a new point pub fn transform_point(&self, point: Vec2) -> Vec2 { self.coefficients.transform_point2(point) }