April 24, 2014

Class project - torus knot

My goodness, it's been a while since I've posted in here.

My intrigue for shader programming hasn't left me, but the semester is nearing to a close and things are very busy now.  But we had a final project in my Rendering class where we were required to implement either bump mapping or environment mapping and I chose the latter.

I've been really interested in mathematical shapes.  I wanted to implement a 3D Julia set but I can only use VBOs to implement the geometry and the professor thought it would be too difficult, so I implemented a torus knot instead.  It wasn't easy either but at least it was doable.

I'll attach a video later but here's a screenshot:


Basically the camera rotates around the knot and the knot rotates along two of its axes.  It looks pretty cool, I wish I was able to implement clouds in the fragment shader and it would be really cool.

April 02, 2014

Drawing circle with GLSL

I'm still dabbling with really simple GLSL code but I finally understand how to draw a circle so I'll just write it down before I forget.

Here's the code:

void main(void)
{
vec2 p = (2.0 * gl_FragCoord.xy - iResolution.xy) / min(iResolution.x, iResolution.y);
float h = length(p.xy);
float alpha = smoothstep(0.99, 1.0, h);

gl_FragColor = vec4(mix(vec3(0.0), vec3(h), alpha), 1.0);
}

So p basically just scales down the coordinates of our current fragment so it's kind of like normalized device coordinates but accounts for the window dimensions.

I think h just measures the length of the current fragment from the center of the screen (note that the center of the screen is 0,0).  Can also think of it as the radius.

And alpha is set to 0.0 if the length (we can also think of it as radius) is less than 0.99, set to 1.0 if the radius is greater than 1.0.  Between it's interpolated between a very small value (meaning the edge of the circle will be sharp, not blurry).

And finally we set the fragment color.  Remember that the mix function takes two vectors (basically two candidates for the fragment's color) and an alpha value, that we can think of the weight of the second vector.  For this code it's all or nothing for each vector - as explained above, if the current fragment is within the radius of the circle then h will have been set to 0, so vec3(0.0), which is black, will be drawn.  If the current fragment is outside of the radius then h will have been set to 1, so vec(h) (which is [1.0, 1.0, 1.0]) is what will be drawn, which is the part outside the circle.

Not posting a picture of a circle because we all already know what it looks like.