Posted on

Chilin – my African friend asked me if I could make a shader to visualise a sound or sine wave with harmonics included, so I wrote this WebGL shadertoy:

In the end, I didn’t quite get there but this shader makes a nice illustration of the theory of additive colours, as various offsets of the sine waves are given their own channel: Red for the main frequency, Green for the second harmonic or octave, and Blue for the third harmonic.

Features: sine waves, pi, mouse input to alter parameters, interference patterns

## Highlights of the code

This is just a normalised sine function of time multiplied by the pixel co-ordinates being rendered.

vec2 S; // speed of fundamental
S.x = (xy.x + xy.y)*(xy.x – xy.y)*0.5; // “velocity potential” a square of the pixel distance so it gets big quick
S.x -= iGlobalTime *timespeed; // animate stream
vec2 sxy = sin(3.14159 * S * 1.0 ); // its a sine wave of time and pi

### The Full Code

```// Concept: an animation of wave harmonics
// show 1st, 2nd, 3rd order harmonics somehow

float divs = 2.2;

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec4 m = iMouse;
if ( m.x == 0. && m.y == 0.) {
m.x = iResolution.x / 2.;
m.y = iResolution.y / 2.;
}
float dist = m.x - ( iResolution.x / 2.0 ); // centererd
float speed = 0.0009; // 0.9 camera movement to plane
float timespeed = 0.1 ; // 0.1 wave movement on the ribbons

// MOUSE: multiple by my or mx to get value between 1 and 2
float my = float( (m.y + iResolution.y ) / iResolution.y );
float mx = float( (m.x + iResolution.y ) / iResolution.x );

float t = 8.0 - speed ;

// divs create staggered / staged division, old setting was divs += t / 0.20;
// let the mouse distance control the zoom
divs += t / ( ( m.x + 2. ) / iResolution.x );

vec2 div = vec2( divs, divs*iResolution.y/iResolution.x );
vec2 uv = fragCoord.xy / iResolution.xy;

// center on screen then pan off:
uv -= 0.1 + (iGlobalTime*0.0001);

float b = 1.0*divs/iResolution.x; // blur over 2.4 pixels

vec2 xy = div*uv;

vec2 S; // speed of fundamental
vec2 S2; // speed of 1st octave
vec2 S3; // speed of 2nd harmonic (perfect fifth?)

S.x = (xy.x + xy.y)*(xy.x - xy.y)*0.5; // "velocity potential"
S2.x = (xy.x + xy.y)*(xy.x - xy.y)*0.5; // "velocity potential"
S3.x = (xy.x + xy.y)*(xy.x - xy.y)*0.5; // "velocity potential"

S.y = xy.x*xy.y; // stream function
S2.y = xy.x*xy.y; // stream function
S3.y = xy.x*xy.y; // stream function

// speed of the dots
S.x -= iGlobalTime *timespeed; // animate stream
S2.x -= iGlobalTime *timespeed + (my * 20. ); // animate stream
S3.x -= iGlobalTime *timespeed + (my * 20.); // animate stream

// HERE IS THE WAVE HARMONICS
// SXY IS FUNDAMENTAL WAVE2 IS 2ND HARMONIC
// sxy is *probably* the main wave
// wave2 is the 2nd harmonic

vec2 sxy = sin(3.14159 * S * 1.0 );
vec2 wave2 = sin(3.14159 * S2 * 2.0 ); // 2.00 is double
vec2 wave3 = sin(3.14159 * S3 * 3.0 ); // 3.00 is double

// w2 is the 2nd harmonic
float a = sxy.x * sxy.y; // combine sine waves using product
float w2 = wave2.x * wave2.y; // combine sine waves using product
float w3 = wave3.x * wave3.y; // combine sine waves using product

// not sure what this does but we will do it to w2, w3 as well
a = 0.5*a + 0.5; // remap to [0..1]
a = smoothstep( 0.85-b, 0.85+b, a ); // threshold

w2 = 0.5*a + 0.5; // remap to [0..1]
w2 = smoothstep( 0.85-b, 0.85+b, a ); // threshold

w3 = 0.5*a + 0.5; // remap to [0..1]
w3 = smoothstep( 0.85-b, 0.85+b, a ); // threshold

float c = sqrt( a ); // correct for gamma
float w2gamma = sqrt( w2 ); // correct for gamma
float w3gamma = sqrt( w3 ); // correct for gamma

float red, green, blue;

red = sxy.x - sxy.y ;
green = wave2.x - wave2.y;
blue = wave3.x - wave3.y;

float crossover = -1.5;

if (red < crossover) {
red = red * -1.;
}
if (green < crossover) {
green = green * -1.;
}
if (blue < crossover) {
blue = blue * -1.;
}

fragColor = vec4( red, green, blue, 1.0);

}```
Posted on

## The Orb – Cycle

A special request from my mate from up Ngawha ways… (stay tuned for HD render)

The Orb – A mandelbulb3d source formulas

Posted on

## Roasting Sun Red Triangle

**UPDATE** Here is a test render of the final scene. Set to 100 Beats by Tomachi.

A 4.9 megapixel Monte Carlo rendering of a frame from my upcoming “Sierpinkski 4” fractal zoom, which has now been rendering for 14 days!

Posted on

## Sierpinski 3D Fractal Still

FINISHED!! 6 weeks of rendering: https://youtu.be/dRdOThrJhmg

Just a casual 20 megapixel render of an animation frame I’m rendering because it’s awesome. This is a Sierpinski 3D fractal done in Mandelbulb3d running under Wine on Mac. 5120 x 3840 likely with no anti-alias set. While it’s not a final-final render, it’s higher res than the main animation will be. Here is the original Mandlebulb3D source file .m3a

File under: Sierpinksi (spelling mistake)

Posted on

## Mandelbulber Sequence 01

Teaching myself how to use Mandelbulber. The image below took about 7 hours to render on my Macbook Pro 13″ with 2.8 GHZ quad core.

It’s a still from the animation below.