Archive for November, 2008


In Other News

I’ve started building a synthesizer.

It’s one of these
based on Wilba’s amazingly professional designs, and when it’s finished will (fingers crossed) harness the power of no less than 8 commodore 64 SID chips.

My soldering iron is on the blink, at the moment, though, unfortunately, so I’m not making very fast progress.

If anyone’s interested in seeing how I’m getting on, keep an eye on this thread on the uCapps forum:

I’m no expert on microelectronics, but I’ve done a bit of soldering in the past, and the project is pretty well-documented, so I should be OK.. I hope so, anyway, because I’ve just spent a wedge of money on all the bits!

Here’s some more general info on the project, which has gathered a nice, friendly community around it.
(it’s a frames-based site, which makes bookmarking harder than it should be, but you can get straight to the relevant pages by following the ‘MIDIBox SID V2 Synth’ links on the left). The whole thing has been made possible by the godlike genius of one Thorsten Klose, who developed the MIDIBox platform.

On the off-chance anyone is interested, there’s also a link to a small selection of my musical efforts from the past 10+ years in the links on the right of this blog.


tb SoundFlower at Richie Hawtin Gig

Thanks to Ali M. Demirel

Looks especially cool when it emerges out of the centre of the eye, I think!

Original video


tb SuperFormula

OK, since a couple of people have asked, I’m releasing a version of the Superformula QTZ. It’s by no means complete, but it might be a good starting-point for someone to develop something else, or just refine the controls a bit. No normal-calculation or lighting, but this one has spherical and toroidal modes, for added fun.

‘tb SuperFormula 1.0’ in the widget.


Superformula Toroidal Mapping

Some screenshots of an alternative version of the superformula vertex shader. Where the previous version was based on a applying the superformula equation to a parametric sphere, this version applies the formula to a base torus (doughnut shape).

Again, no normal calculation.

Here’s a code-snippet, from the vertex shader:

// Superformula equation applied to a sphere or torus

vec3 sf3D(in float m, in float n1, in float n2, in float n3,
	in float mb, in float n1b, in float n2b, in float n3b,
	in float theta, in float phi)
	float rt = superFormula(m, n1, n2, n3, theta);
	float rp = superFormula(mb, n1b, n2b, n3b, phi);
	float st = sin(theta);
	float ct = cos(theta);
	float sp = sin(phi);
	float cp = cos(phi);
	vec3 sSphere;
	sSphere.x = rt * ct * rp * cp;
	sSphere.y = rt * st * rp * cp;
	sSphere.z = rp * sp;
	vec3 sTorus;
	sTorus.x = cp * (rp + rt * ct);
	sTorus.y = sp * (rp + rt * ct);
	sTorus.z = rt * st;
	sTorus *= 0.55;
	return (SphereTorus == 0.0) ? sSphere : sTorus;

Superformula Shader, No Lighting

Simplified version of the Superformula shader made by gregsn, sanch and tonfilm for VVVV.

Vertex Shader:

/* ------------------------------------------ 
	3D Superformula shader.
	Original equation by Johan Gielis.
	More info at
	Original Shader implementation by
	gregsn, sanch and tonfilm.
	Written as HLSL shader for VVVV.
	HLSL-GLSL conversion and Quartz Composer setup
	toneburst 2008
	This simplified version has no
	normal-generation or lighting.
------------------------------------------ */

///          Functions          ///

// The basic Superformula equation

float superFormula(in float m, in float n1, in float n2, in float n3, in float phi)
	vec2 ret;
	float Out;
	float a = 1.0, b = 1.0;
	float t1___ = cos(m * phi / 4.0);
	float t1__ = t1___ / a;
	float t1_ = abs(t1__);
	float t1 = pow(t1_, n2);
	float t2___ = sin(m * phi / 4.0);
	float t2__ = t2___ / b;
	float t2_ = abs(t2__);
	float t2 = pow(t2_, n3);
	float T = t1 + t2;
	Out = pow(T, 1.0 / n1);
	if (abs(Out) == 0.0) {
		Out = 0.0;
	} else {
		Out = 1.0 / Out;

	return Out;

// Superformula equation applied to a sphere

vec3 sfs3DSphere(in float m, in float n1, in float n2, in float n3,
	in float mb, in float n1b, in float n2b, in float n3b,
	in float theta, in float phi)
	float rt = superFormula(m, n1, n2, n3, theta);
	float rp = superFormula(mb, n1b, n2b, n3b, phi);
	float st = sin(theta);
	float ct = cos(theta);
	float sp = sin(phi);
	float cp = cos(phi);
	vec3 Out;
	Out.x = rt * ct * rp * cp;
	Out.y = rt * st * rp * cp;
	Out.z = rp * sp;
	return Out;

///        Tweakables 	    ///

// Superformula 3D parameters (with suggested ranges)
uniform float m;		//	 0 > 24	linear
uniform float n1;		//	20 > 1	exp.out
uniform float n2;		//	 1 > 2	linear
uniform float n3;		//	 1 > 4	linear

uniform float mb;		//	 0 > 24	linear (must be multiples of 4 for 'closed forms')
uniform float n1b;	//	20 > 1	linear
uniform float n2b;	//	 1 > 2	linear
uniform float n3b;	//	 1 > 4	linear

// Pre-Transform Grid
uniform vec2 PreScale;		// Pre-Scale
uniform vec2 PreTranslate;	// Values other than 0 may result in mesh edges not meeting

// 3D pixellate parameters
uniform float QSize;
uniform float QAmt;

// Shading parameters (more options in Fragment Shader)
uniform vec3 LightPosition;

// Variables for simple fake lighting
varying float SimpleLight;

///        MAIN LOOP          ///

void main()
	// Vertex position
	vec4 vertex = gl_Vertex;
	// Pre-Transform vertices
	vertex.xy *= PreScale;		// Pre-scale vertices
	vertex.xy += PreTranslate;	// Pre-translate vertices
	// Superformula vertex displacement = sfs3DSphere(m, n1, n2, n3,mb, n1b, n2b, n3b, vertex.x, vertex.y);
	// 'Quantised' vertex position
	vec3 vertexQ;
	vertexQ = (floor( * QSize) / QSize);
	vertexQ =+ 0.8 * vertexQ;
	// Mix quantised and unquantised vertex positions
	vertex = vec4(mix(,vertexQ,QAmt),1.0);
	// Fake lighting shade value
	SimpleLight = 0.8 * length(;
	// Transform and set texture-coordinates
	vec4 baseTexCoords = gl_TextureMatrix[0] * gl_MultiTexCoord0;
	baseTexCoords.xy *= PreScale;
	gl_TexCoord[0] = baseTexCoords;
	// Output vertex position
	gl_Position = gl_ModelViewProjectionMatrix * vertex;

Fragment Shader:

/* ------------------------------------------ 
	3D Superformula shader.
	More info in Vertex Shader comments.
------------------------------------------ */

///         Tweakables        ///

// Varying variable from Vertex Shader
varying float SimpleLight;

uniform vec4 Color;			// Fragment Shader tweakables
uniform float LUT_Y;			// LUT Y-position
uniform sampler2D LUT;		// Texture input

// Shading + surface controls
uniform float LightRange;		// Light range
uniform float TileSize;			// Texture tile size
uniform sampler2D TileImg;		// Texture Tile

///          Functions 	    ///

// Shading range/dropoff function
float smoothstepVar(in float edge1, in float edge2, in float value)
	float width = edge2 - edge1;
	float phase = (value - edge1) / width;
	phase = clamp(phase, 0.01, 0.99);
	return phase;

///        MAIN LOOP 	    ///

void main()
	vec2 xy = gl_TexCoord[0].xy;
	vec2 phase = fract(xy / TileSize);
	vec4 texTile = texture2D(TileImg, phase);
	// Shading from varying var
	float lookupX = smoothstepVar(0.0, LightRange, SimpleLight);
	// Multiply input Color by Lookup Table color
	vec4 outPix = Color * texture2D(LUT, vec2(lookupX, LUT_Y)) * texTile;
	outPix.a = SimpleLight;
	// Output Fragment color
	gl_FragColor = outPix;

SF snap 061108

I’ve removed all the code for normal-calculation and lighting in this one, which makes the whole thing a lot simpler. I’ll put all that stuff back in again later, but I want to work on a different parameterisation (is that the right word?) first, so stay tuned.


November 2008


Blog Stats

  • 493,214 hits