Amoeba Dance (2007)


Soundtrack “Caliper Remote” by Autechre (from LP5 – 1998)
Interactivity tests:

GLSL code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/************** generic cartesian spherical conversion functions ***************/
struct spherical {
float r, phi, theta;
};

spherical cartesianToSpherical(vec3 cPoint) {
spherical sCoords;
float xyLen = length(cPoint.xy);
sCoords.r = length(cPoint);
sCoords.phi = acos(cPoint.z / sCoords.r);
sCoords.theta = atan(cPoint.x, cPoint.y);
return sCoords;
}

vec3 sphericalToCartesian(spherical sPoint) {
vec3 cCoords;
cCoords.x = sPoint.r * sin(sPoint.phi) * cos(sPoint.theta);
cCoords.y = sPoint.r * sin(sPoint.phi) * sin(sPoint.theta);
cCoords.z = sPoint.r * cos(sPoint.phi);
return cCoords;
}
/*************************************************************/

uniform float RadMod;

uniform vec2 count;
uniform vec2 phase;
uniform vec2 amount;

/************* simple scaling function, adds to the radius ***********/
// takes a spherical coordinates as parameter
// and returns spherical coordinates
spherical radialDistort(spherical sPoint, float RadMod) {
sPoint.r += RadMod;
return sPoint;
}

/************* modulates radius based on theta and phi ***********/
// takes a spherical coordinates as parameter
// and returns spherical coordinates by writing to the same parameter
// did it like that just to try out the in/out keywords
void radialDistort2(inout spherical sPoint) {
sPoint.r += sin(sPoint.phi * count.x + phase.x) * amount.x;
sPoint.r += cos(sPoint.theta * count.y + phase.y) * amount.y;
}

void main()
{
spherical sphereCoords = cartesianToSpherical(gl_Vertex.xyz);

// this function just scales and returns the new spherical coordinates in the function
sphereCoords = radialDistort(sphereCoords, RadMod);

// this function does some other stuff and writes the spherical coordinates back to the same variable
// did it like that just to try out the in/out keywords
radialDistort2(sphereCoords);

// convert modified spherical coordindates back to cartesian
vec3 outCoords = sphericalToCartesian(sphereCoords);
gl_Position = gl_ModelViewProjectionMatrix * vec4(outCoords, 1.0);

// lighting
vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
vec3 lightDir = normalize(vec3(gl_LightSource[0].position));
float NdotL = max(dot(normal, lightDir), 0.0);
vec4 diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
gl_FrontColor = NdotL * diffuse;

// add fake lighting based on radius;
gl_FrontColor = gl_FrontColor * 0.5 + (abs(sphereCoords.r)-RadMod) * 0.5;
}
Interactive sound-reactive installation
1ch HD video, microphone, custom software
Duration: N/A
Dimensions: variable

An experiment in audio reactive organisms. The piece is completely realtime and driven by audio analysis with no post production or timeline animations.

Technical information

Written entirely in GLSL (as a vertex shader) in Quartz Composer 3.0 and controlled via VDMX. The GLSL code is below: a few functions to convert between cartesian and spherical coordinates, and then a radial distortion function. I noticed that when not using any distortion at all, but just mapping cartesian to spherical and back to cartesian again the sphere is not perfectly round but ever so slightly squared. I’m guessing this is due to rounding errors on the GPU.

Acknowledgements

Thanks to Alex ‘Toneburst’ for encouraging me into GLSL.

Related keywords

audio reactive, generative visuals, glsl, installation, open source, quartz composer, vdmx