Thumper: a WebGL demo

Thumper is a shader driven by frequency modulation, rendered to a single quad. I put this together using iq’s Shader Toy and used a track from Akira Kiteshi called “Boom N Pow”. Below, I describe briefly how it works.

There are four basic components that create the effect:

1) A procedural texture
2) Radial blur
3) Plane deformation
4) Frequency modulation

Smooshy Squares

The procedural texture (the function “cube” in the shader) is generated by taking the [-1, 1] coordinate of the current fragment and modding it’s x and y components to determine if either is in an active column. If so, the pixel value is white. This creates white horizontal and vertical bars leaving grid of black squares. The basic formula is:

float value = 0.0;

if (floor(mod(p.x*10.0, 2.0)) == 0)
value = 1.0;

if (floor(mod(p.y*10.0, 2.0)) == 0)
value = 1.0;

vec4 color = vec4(value, value, value, 1.0);

Multiplying times 10.0 and modding by 2.0 means we should end up turning on and off in large blocks, the value 10 controls the size of the grid squares. The floor() call is necessary because we’re dealing with floats, an epsilon value could be used to make the transition smoother, but I wanted hard edges. The x and y values are then manipulated over time (t0) to cause the squares to strech and compress. The effect is stable in p.y, but the frequency of p.x is modulated (t0*cos(sin(t0*3.)*t0*.01)) to cause the variation in the horizontal compression over time.

Adding the Bounce

The radial blur is based on iq’s old school radial blur effect in the Shader Toy. The basic idea is to calculate a direction vector and layer the color of the current pixel by sampling in that direction over a given number of steps. If you look at iq’s example, this is the vector d, the color is “total” variable and each step is reduced in weight with the “w” variable.

In Thumper, two direction variables (d1 & d2) are used, pointing in opposite directions. Then, the mix() function is applied to interpolate between these direction to a heavily modulated sin function:

vec2 d = mix(d1, d2,.5+.5*sin(sin(sin(t0)*t0)*t0));

The value .5 + .5 * sin(...) is necessary to keep the value in the range [0, 1], which keeps the mix() call sane.

Warpy & Melty

The plane deformation (the function "deform" in the shader) is what causes the warping/bubbling effect. This is also based on iq's radial blur shader, with some added frequency modulation to spice it up a bit.

What's happening here is the fragment point (p) is being mapped into (sin, sin) space. Then, properties of this new vector are used to manipulate the original point, p, which is finally used to sample the procedural texture. The end result is the texture deformed by a two dimensional wave.

If you look at the source code, the value "r" is roughly the amount of displacement in local space, which is multiplied by p again, essentially mapping back into fragment space. sin(t0) is added to the resulting value to layer on some additional movement.

The Seizure Test

Frequency modulation is, as it says, the act of modulating the frequency of a function. In this case, the function is sin() or cos() and I'm using the same functions again to modulate their own frequency, such as sin(sin(t)*t). The great and terrible thing about FM is that it continues to change over time. This can be desirable for creating variation, but ultimately you need some control for long running effects.

To get this control, I used a constant period variable, T = 20. Each function uses this variable slightly differently, but the idea is that it provides a basis for cutting off the frequency modulation. Without it, the effect has a tendency to spiral off into seizure inducing chaos.

If you look at my usage of the limiter, it basically resets after some period, which wouldn't work well for a smooth effect. However, since this effect was intended to be spastic, the jerkiness of the reset kind of adds something nice :)

Timing & Audio

Although it may look like this is doing beat detection, it's not. The audio and video just happen to sync up due to some very loose planning. I know dub step is created primarily using frequency modulation, so I hoped the end effect would sync to the music and I think it worked out okay.

On the other hand, the timing truly *is* synced to the music. I used the HTML5 audio tag to get a notification of when the song was loded. The shader takes a uniform parameter "time" which is driven by the the current time of the audio tag. So when you scrub through the song, the visual effect stays in sync, as you would expect.

Conclusion

So there you have it, very little code is needed to produce this effect, essentially, the shader does all the work. I have to give major props to iq, this demo really looks good because of the tricks I learned from looking at his shader toy code.

Tagged Tags: , , , on June 17, 2011 at 9:18 pm

The Wii and Johnny Chung Lee

A friend sent me this link recently to this guy who is doing amazing hacks with the Wii remote. He has an example of head tracking to create desktop VR that is pretty incredible.

You can check it out here.

Tagged Tags: , on December 27, 2007 at 5:03 pm

Worlds Biggest Botnets

“There’s a new peer-to-peer based botnet emerging that could blow the notorious Storm away in size and sophistication, according to researchers, and it’s a direct result of how Storm has changed the botnet game, with more powerful and wily botnets on the horizon. This article provides a peek at the ‘new Storm’ and reveals the three biggest botnets in the world (including Storm) — and what makes them tick and what they are after.”

Tagged on November 11, 2007 at 4:01 pm