Archive for January 8th, 2008


Pseudo 3D Distortions, Wave-Morphing

One day, I’ll get around to creating my own real 3D effects.
Unfortunately, I have a lot of learning to do before I reach that point. In the meantime, this kind of thing keeps me happy!

This is what happens when you use a gradient oscillator as the distortion input to a zoom-distort effect. The image gets bent around in interesting ways. The effect I’m working on has the option of overlaying the alpha of the gradient input on top of the image, so the image is not only bent, but also faded in and out, hence the 3D-like look.
VariOsc zoomDistort 01VariOsc zoomDistort 02
VariOsc zoomDistort 05VariOsc zoomDistort 04

Ironically, since it’s all hidden inside the one patch, the composition looks deceptively simple when you open it up in Quartz Composer. It’s only the wires from all the input splitters that mess things up!

VariOsc zoomDistort Controls

The entire effect is done in one Core Image Filter patch, using the new JavaScript option to pass the input image through a number of different filter kernels.

I’m not going to post all the code until I’ve been through it and eliminated all the most obvious errors. I’ve added so many little tweaks and extra little variables to fine-tune things that it’s all got a bit messy!
I will post this little snippet though- it’s a function to create various waveforms using the GLSL smoothstep function (which also works in CI Filter kernel slang). It creates a sinewave, a rounded-off square wave, and up/down exponential sawtooth-like waves. It can’t do triangle or proper linear sawtooth waves, but then I quite like the smooth curves it produces, and they seem to work well as inputs to the distortion effect.

// Variable-geometry saw/square/sine wave
float tb_variSawSineWave(float phase, float shape, float aa, float w1, float w2) {

// Sine Wave
vec4 waveList0;
waveList0.x = 0.0; // left-bottom edge of wave
waveList0.y = 0.5; // left-top edge
waveList0.z = 1.0; // right-bottom edge
waveList0.w = 0.5; // right-top

// Square(ish)
vec4 waveList1;
waveList1.x = 0.25; // left-bottom edge of wave
waveList1.y = waveList1.x + aa; // left-top edge
waveList1.z = 0.75; // right-bottom edge
waveList1.w = waveList1.z - aa; // right-top

// Falling Sawtooth(ish)
vec4 waveList2;
waveList2.x = 0.0; // left-bottom edge of wave
waveList2.y = aa; // left-top edge
waveList2.z = 1.0; // right-bottom edge
waveList2.w = aa; // right-top

// Rising Sawtooth(ish)
vec4 waveList3;
waveList3.x = 0.0; // left-bottom edge of wave
waveList3.y = 1.0 - aa; // left-top edge
waveList3.z = 1.0; // right-bottom edge
waveList3.w = 1.0 - aa; // right-top

// Select wave 1
vec4 wave1 = (w1 == 0.0) ? waveList0 :
		(w1 == 1.0) ? waveList1 :
		(w1 == 2.0) ? waveList2 :
// Select wave 2
vec4 wave2 = (w2 == 0.0) ? waveList0 :
		(w2 == 1.0) ? waveList1 :
		(w2 == 2.0) ? waveList2 :

vec4 waveOut = mix(wave1, wave2, shape);

return smoothstep(waveOut.x,waveOut.y,phase)*smoothstep(waveOut.z,waveOut.w,phase);

The key is that you can create all four waveforms using just four points. I realised I could therefore store the parameters for each waveform type as a vec4 array, then mix between them before feeding the output to the smoothstep functions, and create a proper morph from one wave to the next (rather than just a crossfade).

Next, I’d like to tweak the code so I can do a proper morph between the rectangular and polar versions of the waveform, so rather than have a menu to select ‘Vertical’, ‘Horizontal’ and ‘Polar’, I’ll just have ‘Angle’ and ‘Rectangular to Polar’ sliders.

I’ll also add the ability to modulate the oscillator with another oscillator. I’d like to try to emulate audio Frequency, Phase and Amplitude modulation. Don’t know how it will look, to be honest, but I’m intrigued to find out how far I can carry-across concepts from the audio world.I’m going to have to find a way to display code with proper formatting. One of the things I was most pleased to discover while working on this one was a way of formatting ternary conditionals using tabs so they’re much more readable. Of course, I can’t show that on the blog, annoyingly…

I’ve discovered how to use the sourcecode formatting option. There isn’t a preset for GLSL, so the colouring isn’t the same as it appears in QC, but it’s an improvement (see above code).

January 2008


Blog Stats

  • 492,858 hits