Archive for February, 2008


Patching Marathon, GPU Branching

After a patching marathon, I’ve finally completed my conversion of Desaxismundi’s 55 Maths Surfaces into individual GLSL patches. That’s 55 patches, each with 13 connections…
You can do the maths if you like; all I know is that’s a lot of little yellow leads. This program is going to give me RSI…

I did manage to keep things relatively tidy, by grouping the GLSL patches into 6 Macros. Demultiplexer patches were used to switch on the appropriate macro, then enable the correct GLSL patch within the active macro. I initially attempted the switching using JavaScript, but it turned out to be easier to achieve using Demultiplexers and some very simple maths.

The reason for all this is that, after making a few enquiries, I’ve discovered that graphics hardware tends to have ‘issues’ with branching logic. Apparently, some GPUs actually evaluate the result of both (or all) results, then chooses which result to use. This meant that in the case of some of the surface shaders I’d put together previously, the GPU was attempting to compute 10 different positions for each vertex- which is obviously not a Good Thing, in terms of efficiency. It seemed the only safe solution was to separate each surface calculation into its own discrete GLSL shader patch. Hence my patching hell….

The result, however, promises to be well worth the effort. The composition certainly seems to run a lot more smoothly now. It’s looking good. The only thing left to do is to iron-out the massive scale differences between some of the surfaces, probably by applying a second transform matrix to the result of the vertex position calculation. I think I’ll hold off on that for the moment, though.



My attempt to emulate VVVVs Spreading functions, when applied to an iterated GLSL patch.
Because QC can’t do multiple GLSL shaders, each iteration contains a Render In Image patch, so it’s not a very efficient composition. Also, since each GLSL shader is rendered to a 2D image, there’s no way of compositing the different slices together in a genuine 3D space- hence I’ve made them all semi transparent, trying to make a feature of a limitation.

Pseudo Spreads 01Pseudo Spreads 02
Pseudo Spreads 03Pseudo Spreads 04
Pseudo Spreads 05


The Best Thing About Quartz Composer

… and the worst thing….

Quartz Composer Spaghetti 02


SuperShape 2D CIFilter Sourcecode

Based on supershape formula

CIFilter conversion by alx at toneburst, 2008

////    SUPERSHAPE 2D     ////

vec2 super2D(float m, float n1, float n2, float n3, float val)
	float r;
	float t1, t2;
	float a = 1.0, b = 1.0;
	t1 = cos(m * val / 4.0) / a;
	t1 = abs(t1);
	t1 = pow(t1, n2);
	t2 = sin(m * val / 4.0) / b;
	t2 = abs(t2);
	t2 = pow(t2, n3);
	r = pow(t1 + t2, 1.0 / n1);
	r = 1.0 / r;
	vec2 xy = (abs(r) == 0.0) ?	vec2(0.0,0.0) : 
							vec2(r * cos(val),r * sin(val));
 	// Output
 	return xy;  

////      MAIN LOOP       ////

kernel vec4 superShape_2D(	float M, float N1, float N2, float N3,
						float Scale, float Twist, float Width,
						float Zoom, vec2 Center,
						float PolarMix, float CartesianMix, float PolarCartesianMix,
						float ColorTable, __color Color, sampler LUT)
	// Sampler dimensions
	vec2 dims = samplerSize(LUT);
	// Normalised coord of current pixel of LUT texture (0.0 > 1.0)
	vec2 xy = samplerCoord(LUT) / dims;
	// Centered coords (-1.0 > 1.0) + center-offset
	vec2 xyCenter = ((2.0 * xy - 1.0) + Center) * Zoom;
	// Polar coords (angle)
	float phi = (atan(xyCenter.y,xyCenter.x));
	// Distance from center (including offset)
	float r = distance(xyCenter,vec2(0.0,0.0) + Center);
	/* Create value to send to superShape function */
	// Mix polar-coordinate values phi and r
	float polar = mix(phi,r,PolarMix);
	// Mix cartesian coordinate X and Y values
	float cartesian = mix(xyCenter.x,xyCenter.y,CartesianMix);
	// Mix the mixed values
	float polarCartesian = mix(polar,cartesian,PolarCartesianMix)  * Scale + Twist;
	// Send value to superShape function
	vec2 point = super2D(M,N1,N2,N3,polarCartesian);
	// Distance between current pixel and superShape result for this pixel
	float dist = distance(xyCenter,point);
	// Scale distance
	float distSmooth = smoothstep(Width,0.0,dist);
	// Output
	return sample(LUT, vec2(distSmooth,ColorTable) * dims) * Color;

More Maths Surfaces

I’m working my way through Desaxismundi’s Maths Surface shader collection, adding them to to my Quartz Composer file.

I’ve also added controls, and my usual Smooth patches, for added niceness.

Maths Surfaces 06Maths Surfaces 07
Maths Surfaces 08Maths Surfaces 09


Maths Surfaces

HLSL to GLSL conversion of Desaxismundi’s VVVV Maths surfaces shaders.

I really like the simple lighting on this shader. Desaxismundi has removed all the normal-calculation he had in an earlier version of the shader, so you can’t really use more realistic lighting. I actually quite like the flat-shaded ‘graphic’ look, though.

Maths Surfaces 01Maths Surfaces 02
Maths Surfaces 03Maths Surfaces 04
Maths Surfaces 05Maths Surfaces 06

The plan is to try to use multiple Render In Image  patches with nested GLSL shaders, to composite multiple shaders on top of each other. Before I can do that effectively, I’ll have to get my head around 3D transformation matrices (gulp)…


More 2D Supershapes

Same basic code, only this time, the colours are retreived from a two-dimensional lookup table, so you can fade from one set of colours to another.

I don’t seem to be be getting the obvious natural forms I got with the previous versions (like the starfish at the bottom-right of the last post). Not quite sure what I’ve changed that would cause this difference. On the other hand, I’ve made a lot of tweaks to the code, and to the ranges of the various controls, so it’s probably a combination of things.

This version also adds some extra controls, so the effect can be driven not just by the polar coordinate ‘phi’ (angle) values, as was the case in the original code, but also from the r (polar radius), X and Y values, or any mix of the four.

2D Supershapes LUT 062D Supershapes LUT 04
2D Supershapes LUT 032D Supershapes LUT 02
2D Supershapes LUT 012D Supershapes LUT 06
2D Supershapes LUT 072D Supershapes LUT 08

Still to do:
• Better lookup table
• Find some way of smoothing the edge of the phi value to eliminate the nasty hard edge you tend to get between the minimum and maximum value for the angle coordinate. You can see what I mean in the screenshot on the right of the 2nd-last row. You can’t eliminate the problem completely, as it’s inherent in the way polar coordinates work, but I think it should be possible to do some kind of crossfade to at least dull the edge of the line. There’s also a slight but annoying glitch going from the centre, horizontally to the right edge. It’s just visible on this same screenshot, and I think it may be a bug in the Render In Image patch.


  • RT @qikipedia: "Anyone who is capable of getting themselves made President should on no account be allowed to do the job." DOUGLAS ADAMS 2 days ago
  • RT @_psonice: @johnreppion Did they really put Paul Nuttal's orgasm face on the bus? That has to be photoshopped. 1 week ago
  • RT @_psonice: Also happened by Lacy's Caves. Good spot. Path was washed away further up, nearly lost a bollock to barb wire going round. Wo… 1 week ago
February 2008
« Jan   Mar »


Blog Stats

  • 470,063 hits