USA Flag

A U.S. flag shader, following the official proportions so everything is accurate.
Replace ceil functions with smoothstep for anti-aliasing.
Ratio: 1.9

No code copied, only used for guidance.
resources:
https://en.wikipedia.org/wiki/Flag_of_the_United_States
Inigo Quilez :: computer graphics, mathematics, shaders, fractals, demoscene and more

Shader code
shader_type canvas_item;

//https://en.wikipedia.org/wiki/Flag_of_the_United_States#Colors
const vec3 OLD_GLORY_RED = vec3(.698, .132, .203);
const vec3 Old_GLORY_BLUE = vec3(.234, .233, .430);
const vec3 WHITE = vec3(1.);

//https://en.wikipedia.org/wiki/Flag_of_the_United_States#Specifications
const float UNION_W = 2./5.;
const float UNION_H = 7./13.;
const float FLAG_RATIO = 1.9;
const uint STAR_GRID_X = 12u;
const uint STAR_GRID_Y = 10u;
const float STAR_DIAM = 4./5.; //4/5th of 1 stripe

//https://iquilezles.org/articles/distfunctions2d/
float sdfstar(in vec2 uv, in float r )
{
    const vec2 v1 = vec2(cos(PI/5.), -sin(PI/5.));
    const vec2 v2 = vec2(-cos(PI/5.), -sin(PI/5.));
    const vec2 v3 = vec2(sin(PI/10.), -cos(PI/10.));

    uv = vec2(abs(uv.x), -uv.y);
    uv -= 2.0 * max(dot(v1, uv), 0.0) * v1;
    uv -= 2.0 * max(dot(v2, uv), 0.0) * v2;
    uv.x = abs(uv.x);
    uv.y -= r;

    float d = dot(uv, v3);
    float cl = clamp(d, 0.0, tan(PI/5.) * r);
    vec2 cs = v3 * cl;
    float dist = length(uv - cs);
    float side = sign(uv.y * v3.x - uv.x * v3.y);

    return 1.0-ceil(dist * side);
}

float stripes(in float d, in float n)
{
	return ceil(sin(d*PI*n));
}

vec3 union(in vec2 uv)
{
	//star diam
	const float UNION_STRIPES = 7.0;
	const float UNION_STAR_ROWS = 5.0;
	float s = STAR_DIAM * (UNION_STAR_ROWS / UNION_STRIPES); //≈ 0.0615 abs | 0.571 relative

	//cell ratio
	float ux = FLAG_RATIO * UNION_W; 		// 0.76 abs
	float uy = 1.0 * UNION_H; 			// ≈ 0.5385 abs

	float gx = ux / float(STAR_GRID_X); 		// ≈ 0.06333 abs
	float gy = uy / float(STAR_GRID_Y); 		// ≈ 0.05385 abs

	float cell_ratio = gx / gy; 			// ≈ 1.176

	//star grid
	const uvec2 GRID_A = uvec2(6,5);
	const uvec2 GRID_B = uvec2(5,4);
	vec2 grid_uv = uv * vec2(GRID_A);

	vec2 g1 = fract(grid_uv) - 0.5;
	g1 *= vec2(2.0);
	g1.x *= cell_ratio;
    float s1 = sdfstar(g1, s);

	vec2 g2 = grid_uv - vec2(0.5);
	g2 = clamp(g2 ,vec2(0.0),vec2(GRID_B));
	g2 = fract(g2) - 0.5;
	g2 *= vec2(2.0);
	g2.x *= cell_ratio;
    float s2 = sdfstar(g2, s);

	float stars = max(s1, s2);

    vec3 col = mix(Old_GLORY_BLUE, WHITE, stars);

    return col;
}

void fragment() {
    vec2 uv = UV;

	float s = stripes(uv.y, 13.0);
	vec3 col = mix(WHITE,OLD_GLORY_RED,s);

    float u_mask = step(uv.x, UNION_W) * step(uv.y, UNION_H);
	vec2 u_uv = uv / vec2(UNION_W, UNION_H);

    col = mix(col, union(u_uv), u_mask);

    COLOR.xyz = col;
}
Live Preview
The shader code and all code snippets in this post are under CC0 license and can be used freely without the author's permission. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

Related shaders

guest

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
TheLoneInitiate
2 months ago

MURICA