(since shadertoy doesn't allow more than a couple of lines in the description and I don't want to put all the stuff into the comment section there, I abuse the blog here)
For everybody new - or not so new - to shaders, hear this:
Browse and use ShaderToy !
Not only is it just bloody amazing what you find there, it's veeeeeery educational.
And easy to use. No hassle with setting up the GPU pipeline yourself - you only need a WebGL capable browser (most are). The interactive compiler displays errors right after the faulty code lines.
Minor nuisance for me was the sometimes "restrictive" behaviour of GLSL (coming from HLSL), but that's not deal breaking.
After experimenting with signed distance functions in 3D with my SlimDX/HLSL stuff I was curious about 2D. So I found this (thank you Marteen):
Very nice. Basic shapes with contours and the usual combiners. Improved with lighting and shadows. Expanding on this, experimenting with polygons and stars, I wanted to put it to the test with something less abstract. Anybody remember Spirograph ? The math around this (pun intended) is already endless. I didn't even know about roulettes before.
But let's start simple. There's a very old discovery from a Persian astronomer: Tusi-Couple.
Here a short protocol of the progress:
Needed individual colouring for the shapes (Marteen's sample combines all shapes to one SDF). Experimenting with arbitrary blending, too (blend function).
Animate the inner circle/wheel within the the outer. Just basic trigonometry. To make it more clear I colored both circles "Wheel of Fortune"-style (see radial function).
- Choose some point on the inner wheel, mark it with a point. I chose a star shape for this.
- Track the ellipse path. Since I got no clue how to derive that yet, I simply trial-and-errored.
- Only got a filled ellipse (or rather: used a transformed circle). Found a real ellipse and used that to generate an outline (ellipse and ellipseLine functions)
- The ellipse line produced some artifacts at the main axis. Needed some tweaking. Still not perfect, goes havoc in the degenerate case. Now use lineDist in that case.
- Hmmmm, cogs would be nice. Splitting the polygon function into circleMod (to get normalized angle part) and using polyShape for laying cyclic functions around a circle. The current implementation using a simple sinus is actually NOT a clean SDF. It works well enough though - and I expect a correct implementation to be quite challenging.
- Added spokes and bars to give even more of a mechanical/gear feeling. Steampunk rules.
- Challenge: Derive ellipse path automatically. I feared the worst. Ellipses are usually a bitch - algebraically. But in this case I found that one can exploit the simplicity of the Tusi-couple and derive the major/minor axis directly (see final if-clause within sceneDist function. Not yet commented)
- Add some light and make the thing scale with the viewport correctly (shadertoy has fullscreen capability).
- TODO: Choose 2nd point with mouse. This should be possible with additional input/buffer logic of the shadertoy setup. Haven't dug into it just yet. For now one can change the point at the start of the shader code, though (relativePos constant).
If you're interested in SDFs I recommend this as a starting point: Distance functions. Quílez has more to offer, of course. He is also quite active on shadertoy. Rewriting classic games for instance. Wow.
PS: Oh my, there are even sound shaders : https://www.shadertoy.com/view/MtGSWc