The tunnel effect builds on the circle equation we covered in the introductory XOR bitplasma. However, this time we need to add a two more concepts. First, we need to calculate the angle of each point on the screen, relative to the origin (center of screen). To find this we can use the properties of right-angle triangles, namely the tangent function (tan). That is, the tangent of the angle is equal to opposite over adjacent.
Visualization of the angle for each pixel |
float a = atan(p.y,p.x);
result = a/(3.1416);
Tunnel depth |
Finally to get a good effect we need to apply a texture map. So combining the two coordinates we use the angular coordinate for the "v" coordinate and the depth coordinate as out "u" value.
So the complete code for our tunnel-shader is:
uniform vec2 resolution;
uniform float time;
uniform sampler2D tex;
void main(void)
{
vec2 p = -1.0 + 2.0 * gl_FragCoord.xy / resolution.xy;
vec2 uv;
float a = atan(p.y,p.x);
float r = sqrt(dot(p,p));
uv.x = 0.1/r;
uv.y = a/(3.1416);
vec3 col = texture2D(tex,uv).xyz;
gl_FragColor = vec4(col,1.0);
}
You can see the result below! (You will need a WebGL enabled browser)
As a small extension to this we can progressively change the power of the square function in the circle equation to generate a less and less round "curve", progressively changing the circular tunnel into a square tunnel.
Graph of increasing squares |
So starting from:
float power = 1.0;
float r = pow( pow(p.x*p.x,power) + pow(p.y*p.y,power), 1.0/(2*power) );
We can slowly increase the power until we get a square-like tunnel. The image shows the effect of increasing the power term, the final bottom right two images show the contrast between the round and square-like tunnels.
2 comments:
Easy to follow and well written, thanks!
It seems in your shader text you doesn't use time variable. WebGL tunnel example has rotation how does it work? Could you explain more math background about "tunnel" deformation. I see simple formulas but can't understand how does it works :)
Post a Comment