Skip to content

Instantly share code, notes, and snippets.

@bzztbomb
Created January 12, 2019 05:18
Show Gist options
  • Save bzztbomb/df5d6fcf2f32bff0673350599de0f155 to your computer and use it in GitHub Desktop.
Save bzztbomb/df5d6fcf2f32bff0673350599de0f155 to your computer and use it in GitHub Desktop.
import * as Regl from "regl"
import * as dat from "dat.gui";
const regl = Regl();
const image = new Image()
image.crossOrigin = 'anonymous';
image.src = 'cor-logo.png';
let imageTexture = regl.texture();
image.onload = () => {
imageTexture({data: image, flipY: true, min: 'linear', mag: 'linear' });
}
interface FeedbackParams {
polarThetaOffset: number,
polarRadiusOffset: number,
drawRadius: number,
borderAmp: number,
sinAmp: number,
cosAmp: number,
timeMult: number,
texture: Regl.Texture2D,
logoStrength: number,
blobStrength: number,
blob2Strength: number,
}
function defaultParams(): FeedbackParams {
return {
polarThetaOffset: 0.03,
polarRadiusOffset: 0.99,
drawRadius: 0.15,
borderAmp: 0.1,
sinAmp: 0.3,
cosAmp: 0.3,
timeMult: 0.1,
texture: regl.texture(),
logoStrength: 1.0,
blobStrength: 1.0,
blob2Strength: 1.0,
};
}
const params = defaultParams();
const feedback = regl({
frag: `
precision highp float;
uniform sampler2D texture;
uniform sampler2D logo;
uniform float time;
uniform float polarThetaOffset;
uniform float polarRadiusOffset;
uniform float drawRadius;
uniform float sinAmp;
uniform float cosAmp;
uniform float borderAmp;
uniform float logoStrength;
uniform float blobStrength;
uniform float blob2Strength;
uniform float pixelRatio;
varying vec2 uv;
void blob(in vec2 xy, in float phase, in float strength, inout vec4 color) {
float t = time + phase;
vec2 blobCoord = xy - vec2(sin(t) * sinAmp, cos(t) * cosAmp);
float dist = distance(xy, vec2(sin(t) * sinAmp, cos(t) * cosAmp));
float b = atan(blobCoord.y, blobCoord.x) + t * 2.0;
float c = dist < (drawRadius + sin(b*10.0) * borderAmp) ? 1.0 : 0.0;
color += vec4(c,c,c,1.0) * strength;
}
void get_logo(inout vec4 color) {
vec2 center = vec2(0.5, 0.5);
vec2 lxy = (uv-center) * 4.0;
vec2 luv = (lxy * 0.5) + 0.5;
vec4 c = luv.x >= 0.0 && luv.x < 1.0 && luv.y >= 0.0 && luv.y < 1.0 ? texture2D(logo, luv) : vec4(0.0, 0.0, 0.0, 0.0);
color += vec4(c.xyz * c.w, 1.0) * logoStrength;
}
void main() {
// Get feedback portion
vec2 xy = (uv-vec2(0.5)) * 2.0;
vec2 polar = vec2(sqrt(xy.x*xy.x+xy.y*xy.y), atan(xy.y, xy.x));
polar.x *= polarRadiusOffset;
polar.y += polarThetaOffset;
vec2 offset = vec2(polar.x * cos(polar.y), polar.x * sin(polar.y));
float oldY = offset.y;
offset *= 0.5;
offset += 0.5;
vec2 diff = xy - offset;
vec4 oldC = texture2D(texture, offset);
// Add some new shiz
vec4 newC = vec4(0.0, 0.0, 0.0, 1.0);
blob(xy, 0.0, blobStrength, newC);
blob(xy, 3.14, blobStrength * blob2Strength, newC);
get_logo(newC);
gl_FragColor = newC + vec4(oldC.xyz * vec3(0.98+sin(time)*0.01, 0.97+sin(time*1.5)*0.01, 0.99), 1.0+cos(time)*0.01) ;
}
`,
vert: `
precision mediump float;
attribute vec2 position;
varying vec2 uv;
void main () {
uv = position;
gl_Position = vec4(2.0 * position - 1.0, 0, 1);
}
`,
depth: {
enable: false,
},
attributes: {
position: [
-2, 0,
0, -2,
2, 2]
},
uniforms: {
pixelRatio: (_ctx: any) => _ctx.pixelRatio,
texture: (_ctx: any, props: FeedbackParams) => props.texture,
logo: () => imageTexture,
logoStrength: regl.prop<FeedbackParams, 'logoStrength'>('logoStrength'),
blobStrength: regl.prop<FeedbackParams, 'blobStrength'>('blobStrength'),
blob2Strength: regl.prop<FeedbackParams, 'blob2Strength'>('blob2Strength'),
time: ({tick}: {tick: number}, props: FeedbackParams) => props.timeMult * tick,
polarThetaOffset: (_ctx: any, props: FeedbackParams) => props.polarThetaOffset,
polarRadiusOffset: (_ctx: any, props: FeedbackParams) => props.polarRadiusOffset,
drawRadius: (_ctx: any, props: FeedbackParams) => props.drawRadius,
borderAmp: (_ctx: any, props: FeedbackParams) => props.borderAmp,
sinAmp: (_ctx: any, props: FeedbackParams) => props.sinAmp,
cosAmp: (_ctx: any, props: FeedbackParams) => props.cosAmp,
},
count: 3
});
regl.frame(() => {
regl.clear({ color: [0,0,0,1]});
feedback(params);
params.texture({ copy: true, min: 'linear', mag: 'linear' });
});
const gui = new dat.GUI();
gui.add(params, 'polarThetaOffset', -0.5, 0.5);
gui.add(params, 'polarRadiusOffset', 0.9, 1.0);
gui.add(params, 'drawRadius', 0.0, 0.3);
gui.add(params, 'borderAmp', 0.0, 0.1);
gui.add(params, 'sinAmp', 0.0, 1.0);
gui.add(params, 'cosAmp', 0.0, 1.0);
gui.add(params, 'timeMult', 0.0, 0.2);
gui.add(params, 'logoStrength', 0.0, 1.0);
gui.add(params, 'blobStrength', 0.0, 1.0);
gui.add(params, 'blob2Strength', 0.0, 1.0);
gui.remember(params);
async function hookMidi() {
const midiAccess = await (navigator as any).requestMIDIAccess();
listenToAll(midiAccess);
midiAccess.onstatechange = (e: any) => {
listenToAll(midiAccess);
}
}
function listenToAll(midiAccess: any) {
for (const input of Array.from(midiAccess.inputs.values())) {
console.log('hooked');
(input as any).onmidimessage = handleMIDIMessage;
}
}
function handleMIDIMessage(midiMessage: any) {
console.log(midiMessage.data);
switch (midiMessage.data[0]) {
case 176: // CC
handleCC(midiMessage.data[1], midiMessage.data[2]);
break;
case 144:
handleNoteOn(midiMessage.data[1], midiMessage.data[2]);
break;
case 128:
handleNoteOff(midiMessage.data[1], midiMessage.data[2]);
break;
}
gui.updateDisplay();
}
function handleCC(index: number, value: number) {
const zeroToOne = (value / 127.0);
const negOneToOne = (zeroToOne - 0.5) * 2.0;
switch (index) {
case 0:
params.timeMult = zeroToOne * 0.1 + 0.02;
break;
case 1:
params.drawRadius = zeroToOne * 0.3;
break;
case 2:
params.borderAmp = zeroToOne * 0.1;
break;
case 3:
params.blobStrength = zeroToOne;
break;
case 6:
params.polarThetaOffset = negOneToOne * 0.15;
break;
case 7:
params.polarRadiusOffset = (zeroToOne * 0.1) + 0.9;
break;
case 8:
params.sinAmp = zeroToOne;
break;
case 9:
params.cosAmp = zeroToOne;
break;
}
}
let oldBlobStrength = 0.0;
function handleNoteOn(index: number, value: number) {
switch (index) {
case 19:
break;
case 36:
oldBlobStrength = params.blobStrength;
params.logoStrength = 1.0;
params.blobStrength = 0.0;
break;
}
}
function handleNoteOff(index: number, value: number) {
switch (index) {
case 36:
params.logoStrength = 0.0;
params.blobStrength = oldBlobStrength;
break;
}
}
hookMidi();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment