The Mega Super Awesome Visuals Company

The work of Memo Akten & Collaborators

Amoeba Dance

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

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

 

Due to it’s realtime nature, it can be driven by external audio inputs (such as microphone) for an interactive experience.

Early tests:

 

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.

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;
}

 

Acknowledgements

Many thanks to Alex ‘Toneburst’ for inspiring me into GLSL.

 

Related tags

Audio Reactive, GLSL, Quartz Composer, VDMX