Particle

Derive Macro Particle 

Source
#[derive(Particle)]
{
    // Attributes available to this derive:
    #[color]
}
Expand description

Derive macro for particle structs.

Transforms a Rust struct into a GPU-compatible particle type. Generates:

  • A companion {Name}Gpu struct with #[repr(C)] and proper WGSL alignment
  • Implementation of ParticleTrait
  • WGSL struct definition as a const string

§Required Fields

Every particle must have these fields:

FieldTypePurpose
positionVec3Particle location in 3D space
velocityVec3Particle movement direction and speed

§Optional Fields

FieldTypePurpose
particle_typeu32Category for typed interactions (auto-added if missing)
#[color] nameVec3Custom particle color (RGB, 0.0-1.0)
(any name)f32, u32, i32, Vec2, Vec3, Vec4Custom data

§Supported Types

Rust TypeWGSL TypeSizeAlignment
Vec3vec3<f32>12 bytes16 bytes
Vec2vec2<f32>8 bytes8 bytes
Vec4vec4<f32>16 bytes16 bytes
f32f324 bytes4 bytes
u32u324 bytes4 bytes
i32i324 bytes4 bytes

§GPU Memory Layout

WGSL has strict alignment requirements that differ from Rust. This macro automatically inserts padding fields to ensure correct GPU memory layout:

  • Vec3 requires 16-byte alignment (despite being 12 bytes)
  • Arrays of structs require 16-byte stride
  • Padding fields are named _pad0, _pad1, etc.

§The #[color] Attribute

Mark a Vec3 field with #[color] to use it for particle rendering:

#[derive(Particle, Clone)]
struct Firework {
    position: Vec3,
    velocity: Vec3,
    #[color]
    color: Vec3,  // RGB values 0.0-1.0
}

Without #[color], particles are colored based on their position.

§Example

use rdpe::prelude::*;

// Minimal particle
#[derive(Particle, Clone)]
struct Basic {
    position: Vec3,
    velocity: Vec3,
}

// Full-featured particle
#[derive(Particle, Clone)]
struct Advanced {
    position: Vec3,
    velocity: Vec3,
    #[color]
    color: Vec3,
    particle_type: u32,
    energy: f32,
    age: f32,
}

§Generated Code

For a particle Ball, the macro generates:

// GPU-compatible struct
#[repr(C)]
#[derive(Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
pub struct BallGpu {
    pub position: [f32; 3],
    pub _pad0: f32,  // Alignment padding
    pub velocity: [f32; 3],
    pub _pad1: f32,
    pub particle_type: u32,
    pub _pad2: [f32; 3],  // Struct size padding
}

impl ParticleTrait for Ball {
    type Gpu = BallGpu;
    const WGSL_STRUCT: &'static str = "...";
    // ...
}

§Panics

The macro panics at compile time if:

  • Applied to an enum instead of a struct
  • Struct uses tuple fields instead of named fields
  • Any field has an unsupported type