UPDATE (2014.06.25): a Twirl effect demo is also available with GLSL Hacker. Visit this thread for more information.
Today a new pixel hack for our shader library: the popular swirl (or whirl) effect, as usual coded in GLSL. You should be able to use the swirl effect in any OpenGL app with few modification. The principle of the swirl effect is to rotate the texture coordinates.
I quickly coded a small GeeXLab demo to show the whirl post processing filter in action. You can interactively tweak the different parameters (radius, angle and swirl center position). The demo is available in GeeXLab code samples pack (PostFX_Swirl/ folder). You can download the complete code sample pack from this page or here:
[download#40#image]
Webmasters: hotlinking is not allowed (that will cause an error message), please use the post url as download link
You need the latest version of GeeXlab to run this demo. Start GeeXLab and load (or drag and drop) DEMO.xml in GeeXLab. That’s all.
I only tested the swirl GLSL effect with a Radeon card (HD 5850) + Cat 11.4 but it should work fine on NVIDIA boards. If it’s not the case, feel free to leave a comment.
Now the complete post processing swirl / whirl shader in GLSL:
[Vertex_Shader] void main() { gl_Position = ftransform(); gl_TexCoord[0] = gl_MultiTexCoord0; } [Pixel_Shader] // Scene buffer uniform sampler2D tex0; // Currently not used in this demo! uniform float time; // GeeXLab built-in uniform, width of // the current render target uniform float rt_w; // GeeXLab built-in uniform, height of // the current render target uniform float rt_h; // Swirl effect parameters uniform float radius = 200.0; uniform float angle = 0.8; uniform vec2 center = vec2(400.0, 300.0); vec4 PostFX(sampler2D tex, vec2 uv, float time) { vec2 texSize = vec2(rt_w, rt_h); vec2 tc = uv * texSize; tc -= center; float dist = length(tc); if (dist < radius) { float percent = (radius - dist) / radius; float theta = percent * percent * angle * 8.0; float s = sin(theta); float c = cos(theta); tc = vec2(dot(tc, vec2(c, -s)), dot(tc, vec2(s, c))); } tc += center; vec3 color = texture2D(tex0, tc / texSize).rgb; return vec4(color, 1.0); } void main (void) { vec2 uv = gl_TexCoord[0].st; gl_FragColor = PostFX(tex0, uv, time); }
Source of the shader: I adapted this swirl WebGL code (too easy I know...) for GeeXLab.
Here is an explanation of the maths behind this effect:
http://adrianboeing.blogspot.com/2011/01/twist-effect-in-webgl.html
Thanks Adrian. I’ll test your code asap!
This has groundbreaking real-life applications such as screensavers, screensavers and screensavers.