# Custom Shaders

### Writing a Custom Shader

With valora, you can shade each path with its own shader, and define custom uniforms. We'll start with this simple GLSL fragment shader:

```c
#version 400

uniform vec3 color;
uniform float scale;
uniform float height;
uniform float width;

out vec4 frag;

void main() {
  vec2 pos = gl_FragCoord.xy / scale;

  vec3 white = vec3(1., 1., 1.);

  frag = vec4(mix(white, color, pos.x / width), 1.);
}
```

Save this to a file named `pattern.frag`.

Now, we'll use valora's shader API to define some uniforms and load the shader. A shader in valora is made of two parts:

1. The shader program. This is the GLSL above, which exposes an interface to provide uniforms.
2. The uniforms bound to the shader.

First let's define the uniforms type in Rust:

```rust
#[derive(UniformSet, Copy, Clone, Debug)]
struct Uniforms {
    /// A solid color overlay on the shader pattern.
    color: (f32, f32, f32),
    /// The vector scale of the output.
    scale: f32,
    /// Width of the output.
    width: f32,
    /// Height of the output.
    height: f32,
}
```

The derive macro `UniformSet` will generate mappings from the field types to something we can send to the GPU, should such a mapping exist for the type.

Now let's load the shader and draw with it:

```rust
fn main() -> Result<()> {
    run_fn(Options::from_args(), |gpu, world, _rng| {
        let mut program = ShaderProgram::new(&gpu, "pattern.frag")?;
        let uniforms = Uniforms {
            color: Hsv::new(0., 0.7, 0.7).into_rgb::<Srgb>().into_components(),
            scale: world.scale,
            width: world.width,
            height: world.height,
        };
        let shader = program.bind(uniforms);

        Ok(move |ctx: Context, canvas: &mut Canvas| {
            canvas.set_color(LinSrgb::new(1., 1., 1.));
            canvas.paint(Filled(ctx.world));

            canvas.set_shader(shader.clone());
            let square = Ngon::square(world.center(), 200.);

            canvas.paint(Filled(square));
        })
    })
}
```

If you run the painting with `cargo run --release`, and change the GLSL, you'll notice that the view pane will update live!

![A path rendered with a custom shader.](/files/-LwHCDwn1lBLQw75vLg9)

### Updating Uniforms

We can update our uniform values each frame. Once the uniforms are updated, we can rebind with the shader program to make a new shader.

```rust
let hue = ctx.time.as_secs_f32().sin().abs() * 40.;
uniforms.color = Hsv::new(hue, 0.7, 0.7).into_rgb::<Srgb>().into_components();
canvas.set_shader(program.bind(uniforms));
```

![](/files/-LwHD3FHP3zdCNyBd5IP)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://paytonturnage.gitbook.io/valora/custom-shaders.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
