Getting started with generative art and Hydra
Published: 2022-09-01 03:23:18

---
title: Getting started with generative art and Hydra
published: true
date: 2022-04-15 04:56:50 UTC
tags: 
canonical_url: https://zachkrall.hashnode.dev/getting-started-with-generative-art-and-hydra
---

# What is Hydra?

Hydra is a JavaScript library for creating interactive visual art by [Olivia Jack](https://ojack.xyz/). The API was designed to function like an analog video synthesizer, where the output of one process is fed into the next one.

> ![Sandin Image Processor](https://cdn.hashnode.com/res/hashnode/image/upload/v1649994039812/eOdNvgGAF.jpg)Image: Sandin Image Processor, exhibited at School of the Art Institute of Chicago (SAIC), photographed by Rosa Menkman, https://commons.wikimedia.org/wiki/File:Sandin\_Image\_Processor.jpg

Hydra takes the resulting output and constructs a [fragment shader](https://www.khronos.org/opengl/wiki/Fragment_Shader) that is rendered into a [<canvas/>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas) element.

This article will go over the three primary elements needed to make a hydra sketch: sources, modifiers, and outputs.

## Getting Started

To follow along with the code examples, you can use the hydra editor at [https://hydra.ojack.xyz/](https://hydra.ojack.xyz/?code=JTBBJTIwJTBBJTIwJTJGJTJGJTIwVHlwZSUyMHNvbWUlMjBjb2RlJTIwb24lMjBhJTIwbmV3JTIwbGluZSUyMChzdWNoJTIwYXMlMjAlMjJvc2MoKS5vdXQoKSUyMiklMkMlMjBhbmQlMjBwcmVzcyUyMENUUkwlMkJzaGlmdCUyQmVudGVyJTBBJTBB).

## Sources

A source is a starting input for any hydra sketch. There are some predefined fragment shaders that are provided by hydra. We'll start by looking at `osc`.

An oscillator takes the `x` coordinate of the screen and passes it through a sine wave, essentially moving continuously between black (`vec3(0.0,0.0,0.0)`) and white (`vec3(1.0,1.0,1.0)`).

![hydra-2022-4-15-0.5.42.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1649995698279/ouRtl2zAZ.png)

To render the oscillator, we attach the `out` function to our source function.

```
osc().out()

```

The `osc` function takes three parameters: frequency, speed, and offset.

- frequency affects how long a full cycle takes for the sine wave or essentially, how many bands appear on the screen (default: 60)
- speed affects how quickly the oscillator moves to the left (default: 1.0)
- offset affects the distance between and red, green, and blue channels (default: 0)

![hydra-2022-4-15-0.21.20.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1649996490150/yHW7b6NAL.png)

```
osc(10, 0.1, 0.3).out()

```

Try seeing what happens if you use: `gradient`, `noise`, `shape`, `solid`, or `voronoi`

## Modifiers

Modifiers take the pixel data from a previous process, manipulates it, and returns a new function that you can either pass to another modifier, or an output channel.

For example, we could take our oscillator and rotate it 90 degrees. Since we're working with WebGL, we'll need to convert degrees into radians.

![hydra-2022-4-15-0.26.31.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1649996832065/TRdUi9RNR.png)

An easy way to set this up is to use `<DEGREES> * Math.PI / 180`

```
osc(10, 0.1, 0.3).rotate(90 * Math.PI / 180).out()
// or
osc(10, 0.1, 0.3).rotate(Math.PI * 0.5).out()

```

Any parameter can be defined as a function or array, so we could change our rotation over time.

```
osc(10, 0.1, 0.3)
.rotate((args) => {
   const d = args.time * 0.1
   return Math.PI * d
})
.out()


const r1 = Math.PI * 0.5
const r2 = Math.PI * 0.25

osc(10, 0.1, 0.3)
.rotate([r1, r2])
.out()

```

We can also increase the color saturation of our shader with `saturate`

![hydra-2022-4-15-0.37.37.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1649997464480/oslVKv-e_.png)

```
osc(10, 0.1, 0.3).rotate(Math.PI * 0.5).saturate(5).out()

```

We can also use operators like `add`, `blend`, `mult` to mix layers together.

![hydra-2022-4-15-0.43.30.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1649997820727/_nDYHW03I.png)

```
const triangle = shape(3, 0.4).scrollY(0.07).rotate(Math.PI)

osc(10, 0.1, 0.3)
.rotate(Math.PI * 0.5)
.saturate(5)
.mult(triangle)
.out()

```

## Output

Hydra has four possible output buffers. By default `out` send the shader to the first buffer or `o0`. We can observe all four buffers by using the `render` function without any parameters

![hydra-2022-4-15-0.40.23.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1649997628681/7quoufFGb.png)

```
osc().out(o0)
noise().out(o1)
shape().out(o2)
voronoi().out(o3)

render()

```

You can switch to displaying a single buffer by passing in the buffer name as a parameter.

```
render(o2)

```

## Experiment!

Now that you're familiar with hydra's syntax including sources, modifiers, and output buffers, you can start exploring with chaining functions together in different ways to make some fun visuals!

**Additional Resources:**

- Hydra Github repository: https://github.com/hydra-synth/hydra
- All hydra functions: https://github.com/hydra-synth/hydra/blob/main/docs/funcs.md
- Introduction to Hydra workshop at NYU, February 2019: https://www.slideshare.net/ZachKrall/hydra-workshop-nyu-live-code-lab-feb-2019