goldy 0.1.0

Goldy - Modern Graphics Library
Documentation
# Plasma Effect

Classic demoscene plasma effect using fragment shaders.

## Run It

```bash
cargo run --example plasma --release
```

## What It Demonstrates

- Custom fragment shader
- Time-based animation
- Passing time to shader via vertex attributes
- Mathematical functions in WGSL

## The Shader

The plasma effect is entirely computed in the fragment shader:

```wgsl
@fragment
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
    let uv = in.uv * 4.0;
    let t = in.time;
    
    // Classic plasma formula
    var v = sin(uv.x + t);
    v += sin(uv.y + t);
    v += sin(uv.x + uv.y + t);
    
    // Circular wave
    let cx = uv.x + 0.5 * sin(t / 3.0);
    let cy = uv.y + 0.5 * cos(t / 2.0);
    v += sin(sqrt(cx * cx + cy * cy + 1.0) + t);
    
    v = v / 2.0;
    
    // Color palette using phase-shifted sines
    let r = sin(v * 3.14159);
    let g = sin(v * 3.14159 + 2.094);  // +120°
    let b = sin(v * 3.14159 + 4.188);  // +240°
    
    return vec4<f32>(r * 0.5 + 0.5, g * 0.5 + 0.5, b * 0.5 + 0.5, 1.0);
}
```

## Key Techniques

### Passing Time to Shader

Without uniform buffers, we pass time through vertex attributes:

```rust
#[repr(C)]
struct PlasmaVertex {
    position: [f32; 2],
    uv: [f32; 2],
    time: f32,  // Same value for all vertices
}

fn create_quad(time: f32) -> [PlasmaVertex; 6] {
    [
        PlasmaVertex { position: [-1.0, -1.0], uv: [0.0, 1.0], time },
        PlasmaVertex { position: [1.0, -1.0], uv: [1.0, 1.0], time },
        // ...
    ]
}
```

### Full-Screen Quad

The plasma covers the entire screen using a quad from (-1,-1) to (1,1):

```rust
fn create_quad(time: f32) -> [PlasmaVertex; 6] {
    [
        PlasmaVertex { position: [-1.0, -1.0], uv: [0.0, 1.0], time },
        PlasmaVertex { position: [1.0, -1.0], uv: [1.0, 1.0], time },
        PlasmaVertex { position: [1.0, 1.0], uv: [1.0, 0.0], time },
        PlasmaVertex { position: [-1.0, -1.0], uv: [0.0, 1.0], time },
        PlasmaVertex { position: [1.0, 1.0], uv: [1.0, 0.0], time },
        PlasmaVertex { position: [-1.0, 1.0], uv: [0.0, 0.0], time },
    ]
}
```

### Color Cycling

The rainbow effect comes from phase-shifted sine waves:
- Red: `sin(v * π)`
- Green: `sin(v * π + 120°)`
- Blue: `sin(v * π + 240°)`

This creates smooth color transitions through the spectrum.

## Variations

### Different Plasma Formulas

```wgsl
// Interference pattern
v = sin(uv.x * 10.0) + sin(uv.y * 10.0);

// Spiral
let angle = atan2(uv.y - 0.5, uv.x - 0.5);
let dist = length(uv - 0.5);
v = sin(angle * 5.0 + dist * 10.0 + t);

// Ripples
v = sin(length(uv - 0.5) * 20.0 - t * 5.0);
```

### Different Color Palettes

```wgsl
// Fire palette
let r = v;
let g = v * v;
let b = v * v * v;

// Ocean palette
let r = 0.0;
let g = v * 0.5;
let b = 0.5 + v * 0.5;
```

## Full Source

See `goldy/examples/plasma.rs` for the complete code.