Hydra Livecoding Workshop Plan
Hydra Visual Livecoding Workshop⌗
Duration: 2 hours + 1 hour bonus
Format: :
- 5 lessons (30min each)
- 10min teaching
- 15-20min workshop
Cheat Sheet: Companion PDF (source)⌗
Workshop Philosophy:⌗
- Experimentation over perfection
- Happy accidents are learning opportunities
- Community and sharing enhances creativity
- Start simple, build complexity gradually
Lesson 1: Hydra 101 (10min + 20min)⌗
Teaching (10min)⌗
- Objective: Get familiar with Hydra interface and basic workflow
- Navigate to https://hydra.ojack.xyz
- Interface tour (2min):
- Play/Stop button
- Clear button
- Examples dropdown
- Settings gear
- Documentation overview: Quick look at built-in help
- Basic workflow demonstration:
osc(40, 0.1, 1.2).out()
- Show simple texture → output chain
Workshop 1 (20min)⌗
Goal: Get your first visual output working
- Navigate to https://hydra.ojack.xyz
- Try these basic generators:
osc().out()
noise().out()
solid(1,0,0).out()
- Experiment with changing numbers
- Bookmark useful resources page (see cheatsheet)
Lesson 2: Experimenting with Hydra (10min + 20min)⌗
Teaching (10min)⌗
- Core principle: “You always get a result, no matter what numbers you use”
- Dynamism: Array and arrow function add fun
- Math.PI exploration:
osc(40, 0.1, Math.PI).out()
- Show how Math.PI affects colors and scaling
- Number ranges: Demonstrate different parameter ranges
- Happy accidents: Show how random experimentation leads to discoveries
Workshop 2 (20min)⌗
Goal: Understand parameter experimentation
- Navigate to https://hydra.ojack.xyz/functions
- Use this as reference while experimenting
- Try:
- Different frequency values:
osc(10).out()
vsosc(100).out()
- Color experiments with Math.PI
- Scaling with various numbers
- Different frequency values:
Lesson 3: Mastering the Chain “.” (10min + 20min)⌗
Teaching (10min)⌗
- The power of chaining: Everything connects with “.”
- Write slowly and deliberately
- Basic chain structure: source().transform().output()
- Example progression:
osc() // just a source osc().rotate() // add transformation osc().rotate(0.1).out() // complete chain
- Keep function reference page open
Workshop 3 (20min)⌗
Goal: Practice chaining functions confidently
- Navigate to blank canvas https://hydra.ojack.xyz
- Build chains step by step:
- Start simple:
noise().out()
- Add transforms:
noise().color(1,0,0).out()
- Try combinations:
osc().rotate().scale().out()
- Start simple:
- Keep it simple, focus on the flow
Lesson 4: Hyper-Hydra Modules (10min + 20min)⌗
Teaching (10min)⌗
- Introduction to external modules
- Modules icon: Show how to add modules easily
- Hyper-Hydra: A collection of advanced modules
- ShaderPark (glsl) integration demo:
- Navigate to: ShaderPark Example
- Show 3D sculptural possibilities
- Extensibility of Hydra
- JavaScript tricks:
c=0;f = new Array(3).fill().reduce(
(acc, e) =>
acc.add(
shape(3,0.1)
.scroll((c += 0.1), 0.1)
),
solid()
)
f.out()
Workshop 4 (20min)⌗
Goal: Explore advanced modules and understand performance
- Reference: Hyper-Hydra GitHub
- Try the ShaderPark example
- Experiment with:
- Image loading functions
- Canvas size modifications
- CPU-intensive operations
- Notice performance differences and how it affects visuals
Lesson 5: Hydra-MIDI Integration (10min + 20min)⌗
Teaching (10min)⌗
- Real-time control with MIDI
- Music visualization possibilities
- Demo setup:
await loadScript("https://h.6120.eu/midi.js") await midi.start({ channel: '*', input: '*' }) midi.show()
- Show how MIDI values can control visual parameters
Workshop 5 (20min)⌗
Goal: Connect MIDI to visuals
- Navigate to: MIDI Example
- Set up MIDI connection (virtual MIDI if no hardware)
- Try:
solid(note('*'), 0, 1).out()
- Link different MIDI controls to visual parameters
- Create responsive audio-visual performances
BONUS CONTENT (1 hour)⌗
Lesson 6: Collaborative Coding with Flok (10min + 20min)⌗
Teaching (10min)⌗
- Collaborative live coding concept
- Flok platform introduction
- Sharing sessions and real-time collaboration
- Community aspect of live coding
Workshop 6 (20min)⌗
Goal: Experience collaborative visual coding
- Set up shared Flok session
- Practice collaborative etiquette
- Create group visual performances
- Share and iterate on each other’s code
Key Resources to Keep Handy:⌗
Hydra Cheat Sheet⌗
Sources⌗
osc(frequency, sync, offset)⌗
Description: Generates an oscillating wave pattern.
osc(60, 0.1, 0).out()
noise(scale, offset)⌗
Description: Creates a noise texture.
noise(10, 0.1).out()
voronoi(scale, speed, blending)⌗
Description: Generates a Voronoi pattern.
voronoi(5, 0.3, 0.3).out()
shape(sides, radius, smoothing)⌗
Description: Renders a geometric shape.
shape(3, 0.3, 0.01).out()
gradient(speed)⌗
Description: Creates a gradient pattern.
gradient(0).out()
solid(r, g, b, a)⌗
Description: Generates a solid color.
solid(0, 0, 0, 1).out()
Modulation⌗
modulate(amount)⌗
Description: Modulates the source using another texture.
osc(60, 0.1, 0).modulate(noise(10, 0.1), 0.1).out()
modulateScale(multiple, offset)⌗
Description: Modulates the scale of the source.
osc(60, 0.1, 0).modulateScale(noise(10, 0.1), 1, 1).out()
modulateRotate(multiple, offset)⌗
Description: Modulates the rotation of the source.
osc(60, 0.1, 0).modulateRotate(noise(10, 0.1), 1, 0).out()
modulatePixelate(multiple, offset)⌗
Description: Modulates the pixelation of the source.
osc(60, 0.1, 0).modulatePixelate(noise(10, 0.1), 10, 3).out()
modulateRepeat(repeatX, repeatY, offsetX, offsetY)⌗
Description: Modulates the repetition of the source.
osc(60, 0.1, 0).modulateRepeat(noise(10, 0.1), 3, 3, 0.5, 0.5).out()
modulateScrollX(scrollX, speed)⌗
Description: Modulates horizontal scrolling.
osc(60, 0.1, 0).modulateScrollX(noise(10, 0.1), 0.5, 0).out()
modulateScrollY(scrollY, speed)⌗
Description: Modulates vertical scrolling.
osc(60, 0.1, 0).modulateScrollY(noise(10, 0.1), 0.5, 0).out()
modulateHue(amount)⌗
Description: Modulates the hue of the source.
osc(60, 0.1, 0).modulateHue(noise(10, 0.1), 1).out()
Color⌗
color(r, g, b, a)⌗
Description: Applies color to the source.
osc(60, 0.1, 0).color(1, 1, 1, 1).out()
colorama(amount)⌗
Description: Applies a colorama effect.
osc(60, 0.1, 0).colorama(0.005).out()
saturate(amount)⌗
Description: Adjusts the saturation.
osc(60, 0.1, 0).saturate(2).out()
contrast(amount)⌗
Description: Adjusts the contrast.
osc(60, 0.1, 0).contrast(1.6).out()
brightness(amount)⌗
Description: Adjusts the brightness.
osc(60, 0.1, 0).brightness(0.4).out()
invert(amount)⌗
Description: Inverts the colors.
osc(60, 0.1, 0).invert(1).out()
luma(threshold, tolerance)⌗
Description: Applies a luma key.
osc(60, 0.1, 0).luma(0.5, 0.1).out()
posterize(bins, gamma)⌗
Description: Applies a posterization effect.
osc(60, 0.1, 0).posterize(3, 0.6).out()
Geometry⌗
rotate(angle, speed)⌗
Description: Rotates the source.
osc(60, 0.1, 0).rotate(10, 0).out()
scale(amount, xMult, yMult, offsetX, offsetY)⌗
Description: Scales the source.
osc(60, 0.1, 0).scale(1.5, 1, 1, 0.5, 0.5).out()
pixelate(pixelX, pixelY)⌗
Description: Applies a pixelation effect.
osc(60, 0.1, 0).pixelate(20, 20).out()
repeat(repeatX, repeatY, offsetX, offsetY)⌗
Description: Repeats the source.
osc(60, 0.1, 0).repeat(3, 3, 0, 0).out()
repeatX(reps, offset)⌗
Description: Repeats the source horizontally.
osc(60, 0.1, 0).repeatX(3, 0).out()
repeatY(reps, offset)⌗
Description: Repeats the source vertically.
osc(60, 0.1, 0).repeatY(3, 0).out()
scroll(scrollX, scrollY, speedX, speedY)⌗
Description: Scrolls the source.
osc(60, 0.1, 0).scroll(0.5, 0.5, 0, 0).out()
scrollX(scrollX, speed)⌗
Description: Scrolls the source horizontally.
osc(60, 0.1, 0).scrollX(0.5, 0).out()
scrollY(scrollY, speed)⌗
Description: Scrolls the source vertically.
osc(60, 0.1, 0).scrollY(0.5, 0).out()
kaleid(nSides)⌗
Description: Applies a kaleidoscope effect.
osc(60, 0.1, 0).kaleid(4).out()
Blending⌗
add(amount)⌗
Description: Adds two sources.
osc(60, 0.1, 0).add(noise(10, 0.1), 1).out()
sub(amount)⌗
Description: Subtracts one source from another.
osc(60, 0.1, 0).sub(noise(10, 0.1), 1).out()
layer()⌗
Description: Overlays one source on another.
osc(60, 0.1, 0).layer(noise(10, 0.1)).out()
blend(amount)⌗
Description: Blends two sources.
osc(60, 0.1, 0).blend(noise(10, 0.1), 0.5).out()
mult(amount)⌗
Description: Multiplies two sources.
osc(60, 0.1, 0).mult(noise(10, 0.1), 1).out()
diff()⌗
Description: Calculates the difference between two sources.
osc(60, 0.1, 0).diff(noise(10, 0.1)).out()
mask()⌗
Description: Applies a mask to the source.
osc(60, 0.1, 0).mask(shape(3, 0.3, 0.01)).out()
Utilities⌗
out()⌗
Description: Outputs the current buffer.
osc(60, 0.1, 0).out()
render()⌗
Description: Renders the specified buffer.
render(o0)
initCam(cameraNumber)⌗
Description: Initializes the webcam.
s0.initCam(0)
src(s0).out()
initVideo()⌗
Description: Initializes a video source.
s0.initVideo("https://6120.eu/public/storm.mp4")
src(s0).out()
initImage()⌗
Description: Initializes an image source.
s0.initImage("file:///path/to/image.jpg")
src(s0).out()
src(texture)⌗
Description: Sets the source for the pipeline.
src(o0).out()
time⌗
Description: Global variable representing elapsed time.
osc(60, 0.1, 0).rotate(() => time).out()
speed⌗
Description: Global variable controlling playback speed.
speed = 0.5
mouse⌗
Description: Global variable representing mouse position.
osc(60, 0.1, 0).rotate(() => mouse.x * 0.01).out()
a.show⌗
Description: Show FFT volume meter.
a.show()
a.fft⌗
Description: Array representing audio frequency data.
osc(60, 0.1, 0).modulate(noise(() => a.fft[0] * 10, 0.1), 0.1).out()
a.setSmooth()⌗
Description: Sets the smoothing for audio analysis.
a.setSmooth(0.8)
a.setBins()⌗
Description: Sets the number of frequency bins for audio analysis.
a.setBins(4)
a.setCutoff()⌗
Description: Sets the cutoff frequency for audio analysis.
a.setCutoff(2)
a.setScale()⌗
Description: Sets the scale for audio analysis.
a.setScale(2)
MIDI⌗
await midi.start().show()⌗
Description: Start MIDI connection and display interface.
await midi.start().show()
note('*')⌗
Description: Get MIDI note value from any channel.
solid(note('*'), 0, 1).out()
cc(channel, controller)⌗
Description: Get MIDI CC (Continuous Controller) value.
osc(cc(0, 1) * 100).out()
aft('*')⌗
Description: Get MIDI aftertouch value from any channel.
solid(aft('*'), 0, 1).out()