Skip to main content
The IPlugP5js example demonstrates how to integrate P5.js, a JavaScript library for creative coding, to build generative and visually dynamic plugin interfaces. This is perfect for visualizers, shader-based UIs, and experimental interfaces.

What This Example Demonstrates

  • P5.js library integration
  • GLSL shader support
  • WebGL rendering in plugins
  • Creative coding patterns
  • Parameter-driven visuals
  • Generative graphics

What is P5.js?

P5.js is a JavaScript library that makes coding accessible for artists, designers, and beginners. It provides:

Simple API

Easy-to-learn drawing and animation functions

WebGL Support

3D graphics and shader programming

Creative Tools

Built-in noise functions, easings, math utilities

Rich Ecosystem

Extensive library of examples and add-ons

C++ Plugin Setup

IPlugP5js::IPlugP5js(const InstanceInfo& info)
: iplug::Plugin(info, MakeConfig(kNumParams, kNumPresets))
{
  GetParam(kGain)->InitGain("Gain", -70., -70, 0.);

  SetCustomUrlScheme("iplug2");
  SetEnableDevTools(true);
  
  mEditorInitFunc = [&]() {
    LoadIndexHtml(__FILE__, GetBundleID());
    EnableScroll(false);
  };
  
  MakeDefaultPreset();
}

void IPlugP5js::ProcessBlock(sample** inputs, sample** outputs, int nFrames)
{
  // Audio processing here
}
The plugin setup is minimal because P5.js handles all the rendering. You can focus on the creative visuals.

HTML Structure

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <style type="text/css">
      body {
        padding: 0;
        margin: 0;
        overflow: hidden;
      }
    </style>
    <script src="p5.min.js" type="text/javascript"></script>
    <script src="sketch.js"></script>
    <script src="script.js"></script>
    <title>P5.js Plugin UI</title>
    <script>
      function OnParamChange(param, value) {
        // Handle parameter changes
      }
    
      function OnControlChange(ctrlTag, value) {
        console.log("Control changed");
      }
      
      function OnMidiMsg(statusByte, dataByte1, dataByte2) {
        // Handle MIDI input
      }
      
      function onLoad() {
        // Initialization
      }
    </script>
  </head>
  <body onload="onLoad()">
  </body>
</html>

P5.js Sketch with Shaders

The example includes a shader-based sketch that responds to mouse interaction:
// This variable will hold our shader object
let theShader;

function preload() {
  // Load the shader files
  theShader = loadShader('uniforms.vert', 'uniforms.frag');
}

function setup() {
  // Shaders require WEBGL mode to work
  createCanvas(windowWidth, windowHeight, WEBGL);
  noStroke();
}

function draw() {
  // Set the active shader
  shader(theShader);

  // Send uniforms to the shader
  theShader.setUniform('resolution', [width, height]);
  theShader.setUniform('mouse', map(mouseX, 0, width, 0, 7));
  theShader.setUniform('time', frameCount * 0.01);

  // Draw geometry
  rect(0, 0, width, height);
}

function windowResized() {
  resizeCanvas(windowWidth, windowHeight);
}
The sketch uses GLSL shaders for GPU-accelerated rendering. Uniforms like mouse and time make the visuals interactive and animated.

Vertex Shader Example

// uniforms.vert
attribute vec3 aPosition;

void main() {
  vec4 positionVec4 = vec4(aPosition, 1.0);
  positionVec4.xy = positionVec4.xy * 2.0 - 1.0;
  gl_Position = positionVec4;
}

Fragment Shader Example

// uniforms.frag
#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 resolution;
uniform float mouse;
uniform float time;

void main() {
  vec2 st = gl_FragCoord.xy / resolution.xy;
  
  // Create animated pattern
  float r = abs(sin(st.x * mouse + time));
  float g = abs(sin(st.y * mouse + time * 0.5));
  float b = abs(sin((st.x + st.y) * mouse + time * 0.3));
  
  gl_FragColor = vec4(r, g, b, 1.0);
}

Integrating Parameters

Connect plugin parameters to P5.js visuals:
let gainParam = 0.0;

function OnParamChange(param, value) {
  if (param === 0) {
    gainParam = value;
  }
}

function draw() {
  shader(theShader);
  
  // Use parameter to control shader uniforms
  theShader.setUniform('resolution', [width, height]);
  theShader.setUniform('gain', gainParam);
  theShader.setUniform('time', frameCount * 0.01);
  
  rect(0, 0, width, height);
}

Audio-Reactive Visuals

Create visuals that respond to audio:
let audioBuffer = [];
let fftData = [];

// Receive audio data from C++
function OnControlChange(ctrlTag, value) {
  if (ctrlTag === 0) {
    // Update audio buffer
    audioBuffer.push(value);
    if (audioBuffer.length > 512) {
      audioBuffer.shift();
    }
  }
}

function draw() {
  background(0);
  
  // Draw waveform
  stroke(255);
  noFill();
  beginShape();
  for (let i = 0; i < audioBuffer.length; i++) {
    let x = map(i, 0, audioBuffer.length, 0, width);
    let y = map(audioBuffer[i], -1, 1, 0, height);
    vertex(x, y);
  }
  endShape();
}

Common P5.js Patterns

function setup() {
  createCanvas(windowWidth, windowHeight);
}

function draw() {
  background(0);
  
  // Draw circles based on mouse position
  for (let i = 0; i < 10; i++) {
    let x = mouseX + sin(frameCount * 0.05 + i) * 100;
    let y = mouseY + cos(frameCount * 0.05 + i) * 100;
    fill(i * 25, 100, 200);
    circle(x, y, 50);
  }
}

Performance Considerations

1

Use WEBGL mode for shaders

GPU acceleration provides smooth 60fps rendering
2

Limit particle counts

Keep particle systems under 1000 particles for consistent performance
3

Optimize draw calls

Batch similar drawing operations together
4

Use push/pop matrices

Properly manage transformation state

Use Cases

Audio Visualizers

Real-time visualization of audio signals and spectrum data

Generative Art

Algorithmic visuals driven by parameters and randomness

Shader Effects

GPU-accelerated visual effects and post-processing

Interactive Graphics

Mouse/touch-driven interactive visualizations

Resources

P5.js Reference

Official P5.js API documentation

P5.js Examples

Gallery of example sketches

OpenProcessing

Community-created P5.js sketches

The Coding Train

Video tutorials by Daniel Shiffman
P5.js adds ~1MB to your plugin bundle. Consider this for plugins where size is critical.

Advantages of P5.js UI

Creative Focus

Designed for artists and creative coders

Simple API

Beginner-friendly with immediate visual feedback

WebGL Ready

Built-in shader support for advanced graphics

Large Community

Extensive examples and tutorials available