 	return c;
 }
 
-float blurcircle(vec2 p, float r, float b)
+float insideblurcircle(vec2 p, float r, float b)
 {
-	float r_ = dist(p);
+	float r_ = length(p);
 	return mix(1.0, 0.0, saturate((r_ - r + b)/(b*2)));
 }
 
-float iblurcircle(vec2 p, float r, float b)
+float outsideblurcircle(vec2 p, float r, float b)
 {
-	float r_ = dist(p);
-	return mix(0.0, 1.0, saturate((r_ - r + b)/(b*2)));
+	return 1.0 - insideblurcircle(p, r, b);
 }
 
-vec4 box(vec2 p, float width, float height, vec4 col)
+vec4 box(vec2 p, float width, float height, vec4 col) // return color if point p is inside origo-centered box with width and height
 {
 	if (p.x<width && p.x>-width && p.y<height && p.y>-height)
 		return col;

	return vec4(0.0);
}

vec4 generate(vec2 pos, float v)
{
	vec2 p = pos*29.0-14.5;
	float r = dist(p);

	vec4 col = vec4(0.0);

	if (r < 14.5)
	{
		col = grey(0.55, 1.0);

		// inset shade
		col = overlay(col, grey(0.0, 0.85*iblurcircle(p + vec2(0.0, 1.5), 13.5, 1.2)));

		// darken bottom quarter
		col = overlay(col, bgshade(p));

		// shader under knob
		col = overlay(col, grey(-0.15, 1.0*blurcircle(p + vec2(0.0, 1.0), 9.5, 2.0)));

		col = overlay(col, bgbox(p, 90.0, 2.0));
		col = overlay(col, bgbox(p, 90.0+135.0, 3.0));
		col = overlay(col, bgbox(p, 90.0-135.0, 3.0));

		col = overlay(col, inrange(r, 13.5, 14.5)*grey(0.3, 1.0));
		col = overlay(col, inrange(r, 9.5, 10.5)*grey(0.3, 1.0));

		col = overlay(col, inside(r, 9.5)*grey(1.0, 1.0));

		vec2 sp = p + vec2(0.0, -3.5);
		col.rgb -= 0.2*inside(r, 7.5)*exp(-dist(sp)*dist(sp)*0.03);

		col.rgb += inrange(r, 7.5, 9.5)*2.0*pow(dot(p/15.0, vec2(0.0, 1.0)*1.0), 3.0);

		col = overlay(col, box((translate(rotate(p, degtorad(90.0+135.0 - 270.0*v)), vec2(4.0, 0.0))), 2.5, 1.0, grey(0.0, 1.0)));

//		col = grey(0.4, blurcircle(p, 0.2, 1.1));
	}

// grid
//	if (fract(p.x + 0.5) < 0.06 || fract(p.y+0.5) < 0.06)
//		col = vec4(0.0);

	return col;
}

vec4 gamma(vec4 col)
{
	float gamma = 1.0/2.2;

// generate : knobster -g -k generators/fm8_knob.frag -w 29 -h 29 -o 15 -n 128 -f fm8_knob.png
// display  : knobster -d -k generators/fm8_knob.frag -w 29 -h 29 -o 15

float saturate(float v)
{
	return clamp(v, 0.0, 1.0);
}

float length(vec2 p)
{
	return sqrt(p.x*p.x + p.y*p.y);
}

vec4 grey(float v, float a) // convert value and alpha to vec4 color
{
	return vec4(v*0.97, v, v*1.03, a); // slightly blue teint
}

vec4 overlay(vec4 under, vec4 over) // overlay composition using non-premuliplied color values
{
	vec4 c;

