Back to shaders
Shader test bench
Star.fs
runnable fragment
Complete GLSL fragment shader. Stronghold runs it directly when the browser can compile it.
Code
uniform float size;
uniform float bordersize;
uniform vec4 color1;
uniform vec4 color2;
precision mediump float;
/*{
"CATEGORIES": [
"Geometry"
],
"CREDIT": "by VIDVOX",
"INPUTS": [
{
"DEFAULT": 0.25,
"LABEL": "Size",
"MAX": 1,
"MIN": 0,
"NAME": "size",
"TYPE": "float"
},
{
"DEFAULT": 0.01,
"LABEL": "Stroke Width",
"MAX": 0.1,
"MIN": 0,
"NAME": "bordersize",
"TYPE": "float"
},
{
"DEFAULT": [
1,
0.6,
0.75,
1
],
"LABEL": "Fill Color",
"NAME": "color1",
"TYPE": "color"
},
{
"DEFAULT": [
0,
0,
0,
1
],
"LABEL": "Stroke Color",
"NAME": "color2",
"TYPE": "color"
}
],
"ISFVSN": "2"
}
*/
// Adapted from https://glsl.io/transition/d1f891c5585fc40b55ea
vec2 circlePoint( float ang )
{
ang += 6.28318 * 0.15;
return vec2( cos(ang), sin(ang) );
}
float cross2d( vec2 a, vec2 b )
{
return ( a.x * b.y - a.y * b.x );
}
// quickly knocked together with some math from http://www.pixeleuphoria.com/node/30
float star( vec2 p, float size )
{
if( size <= 0.0 )
{
return 0.0;
}
p /= size;
vec2 p0 = circlePoint( 0.0 );
vec2 p1 = circlePoint( 6.28318 * 1.0 / 5.0 );
vec2 p2 = circlePoint( 6.28318 * 2.0 / 5.0 );
vec2 p3 = circlePoint( 6.28318 * 3.0 / 5.0 );
vec2 p4 = circlePoint( 6.28318 * 4.0 / 5.0 );
// are we on this side of the line
float s0 = ( cross2d( p1 - p0, p - p0 ) );
float s1 = ( cross2d( p2 - p1, p - p1 ) );
float s2 = ( cross2d( p3 - p2, p - p2 ) );
float s3 = ( cross2d( p4 - p3, p - p3 ) );
float s4 = ( cross2d( p0 - p4, p - p4 ) );
// some trial and error math to get the star shape. I'm sure there's some elegance I'm missing.
float s5 = min( min( min( s0, s1 ), min( s2, s3 ) ), s4 );
float s = max( 1.0 - sign( s0 * s1 * s2 * s3 * s4 ) + sign(s5), 0.0 );
s = sign( 2.6 - length(p) ) * s;
return max( s, 0.0 );
}
void main()
{
vec2 p = (gl_FragCoord.xy / u_resolution.xy);
vec2 o = p * 2.0 - 1.0;
float t = size * 1.4;
float c1 = star( o, t );
float c2 = star( o, t - bordersize );
float border = max( c1 - c2, 0.0 );
gl_FragColor = mix(mix(vec4(0.0), color1, c1), color2, border);
}