Monday, January 31, 2011

Twist Effect in WebGL

The twist/twirl effect is achieved with a combination of techniques I've already discussed:
  1. The circle equation, from the XOR bitplasma example
  2. The angle for each pixel, from the Tunnel example.
Radius (r)
Combining these will give us a 'twisting' effect. Unfortunately, this is almost impossible to explain without pictures.

Unlike the previous examples where I used shaders to explain each component, it will be easier to explain this with some graphs. In the graph each color represents a different height, so from our circle-equation we get:
float r = sqrt(dot(p,p))/sqrt(2.0);

From the tangent-equation we get:
float a = atan(p.y,p.x) / (2.0*3.1416);
Angle (a)

Twisting is essentially a spiral, and we can generate a spiral by stepping out a constant amount towards the radius as we progress around a circle. For example, we start at 0 degrees, at 0% of a step away, then move to 45 degrees at 12.5% of a step towards the radius, then move to 90 degrees at 25% of the radius, and so on.

This is shown in the image below:

Now, to generate a twist we can simply add our constant step away (in the form of the 'r'(radius) graph/image) with our rotation around a circle (in the form of the 'a'(angle) graph/image). This generates our final graph:

We use this equation to sample from our texture.
In GLSL shader code, we have:

uniform vec2 resolution;
uniform sampler2D tex;
void main(void) {
vec2 p = -1.0 + 2.0 * gl_FragCoord.xy / resolution.xy;
vec2 uv;
uv.x = r;
uv.y = a+r;
vec3 col = texture2D(tex,uv).xyz;
gl_FragColor = vec4(col,1.0);

Square color texture

To animate our spiral and make it spin, we just need to add a offset to our "a+r" value. To make the spiral scroll the texture "inwards" we can just add an offset to the "r" value.
Twist with the square color texture

This will give us our final animating spiral:


1 comment:

meka said...

Very nice article, the pictures really help understanding the maths, thanks!