Lesbian

Yeah, we did it again. Experimenting with more dynamic wind, you can expect my full-on empirical model another 8 months from now.

5/31/26 – Updated to include basic smoothstep filtering

Instructions

  1. Add plane mesh, keep size as default 2 x 2
  2. Subdivide a million times
  3. Under Node3D Transform, set X scale to 5/3 (about 1.667)
  4. Apply shader directly to the affected area
Shader code
shader_type spatial;
render_mode cull_disabled;

uniform int flag_type : hint_enum("Sunset (5)", "Sunset (7)", "Butch", "Femme", "Labrys", "Rainbow") = 0;
/**
 * Pin left edge of the flag, assumes you're using a default 2 x 2 plane
*/
uniform bool pin = true;
/**
 * Contract length based on wind strength and frequency
*/
uniform bool length_contraction = true;

group_uniforms Wind;
uniform float strength : hint_range(0.0, 1.0) = 0.5;
/**
 * Wind speed given as periods per second
*/
uniform float speed = 1.5;
uniform float angle : hint_range(-0.8, 0.8) = 0.2;
/**
 * Wind frequency given as number of folds
*/
uniform float frequency : hint_range(1.0, 4.0) = 2.0;
uniform float phase = 0.0;
/**
 * Per-axis strength multiplier
*/
uniform vec3 multiplier = vec3(1.25, 1.0, -0.5);
group_uniforms;

void vertex() {
	float time = speed * 2.0 * PI * TIME + phase;
	
	float ripple_strength = strength * 0.15;
	if (pin) {
		// Falloff ripple strength from left edge
		ripple_strength *= smoothstep(-1.0, -0.5, VERTEX.x);
		
		// Bend at left edge
		float bend = -(VERTEX.z * VERTEX.z) + 1.0;
		float bend_strength = strength * (0.15 + sin(time + VERTEX.x) * 0.05);
		bend_strength *= smoothstep(1.0, -1.0, VERTEX.x);
		VERTEX.x += bend * bend_strength;
		
		// Pinch at right edge
		float pinch = VERTEX.x * 0.5 + 0.5;
		VERTEX.z /= 1.0 + pinch * strength * 0.1;
		
		// Length contraction from left edge
		if (length_contraction) {
			float contraction = 1.0 + (strength * frequency) * 0.05;
			VERTEX.x += 1.0;
			VERTEX.x /= contraction;
			VERTEX.x -= 1.0;
		}
	}
	else {
		// Length contraction from center
		if (length_contraction) {
			float contraction = 1.0 + (strength * frequency) * 0.05;
			VERTEX.x /= contraction;
		}
	}
	
	// Swayin' in the breeze
	float a = PI * frequency;
	float b = -time;
	float t = VERTEX.x * cos(angle) + VERTEX.z * sin(angle);
	float f_t = ripple_strength * sin(a * t + b);
	float df_dt = ripple_strength * a * cos(a * t + b);
	VERTEX += f_t * multiplier;
	NORMAL.xz = vec2(-df_dt * multiplier.y);
}

// Specify aspect ratio to prevent squashing/stretching on flags with patterns
#define aspect 5.0 / 3.0

// --- Colors ---

#define black vec3(0.0)
#define white vec3(1.0)
#define butch_vermilion vec3(0.665387, 0.026241, 0.0)
#define butch_orange vec3(0.863157, 0.181164, 0.020288)
#define butch_apricot vec3(1.0, 0.323143, 0.093059)
#define butch_peach vec3(1.0, 0.610495, 0.246201)
#define butch_yellow vec3(1.0, 0.417885, 0.002731)
#define butch_dark_goldenrod vec3(0.3564, 0.158961, 0.0)
#define femme_red_violet vec3(0.366252, 0.0, 0.122138)
#define femme_pink_lavender vec3(0.462076, 0.093058, 0.278894)
#define femme_pink vec3(0.637596, 0.122138, 0.371237)
#define femme_pearl vec3(0.775822, 0.412542, 0.623960)
#define femme_coral vec3(0.558340, 0.074213, 0.090841)
#define femme_red vec3(0.254152, 0.011612, 0.0)
#define labrys_lavender vec3(0.318546, 0.033104, 0.318546)
#define pride_red vec3(0.775822, 0.000911, 0.000911)
#define pride_orange vec3(1.0, 0.262251, 0.0)
#define pride_yellow vec3(1.0, 0.846873, 0.0)
#define pride_green vec3(0.0, 0.215860, 0.019382)
#define pride_blue vec3(0.028426, 0.291770, 0.701101)
#define pride_purple vec3(0.177888, 0.002124, 0.242281)
#define nonspecific_navy vec3(0.022173, 0.011612, 0.149959)

// --- SDF operations ---
// https://iquilezles.org/articles/distfunctions/

float op_add(float f1, float f2) {
	return min(f1, f2);
}

float op_sub(float f1, float f2) {
	return max(f1, -f2);
}

float op_onion(float f, float thickness) {
	return abs(f) - thickness;
}

// --- SDF primitives ---
// https://iquilezles.org/articles/distfunctions2d/

float sd_circle(vec2 p, float r) {
	return length(p) - r;
}

float sd_segment(vec2 p, vec2 a, vec2 b) {
	vec2 pa = p - a;
	vec2 ba = b - a;
	float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);
	return length(pa - ba * h);
}

float sd_box( in vec2 p, in vec2 b ) {
	vec2 d = abs(p) - b;
	return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0);
}

float sd_cross(vec2 p, vec2 b, float r) {
	p = abs(p); 
	p = (p.y > p.x) ? p.yx : p.xy;
	vec2 q = p - b;
	float k = max(q.y, q.x);
	vec2 w = (k > 0.0) ? q : vec2(b.y - p.x, -k);
	return sign(k) * length(max(w, 0.0)) + r;
}

float sd_equilateral_triangle(vec2 p, float r) {
	const float k = sqrt(3.0);
	p.x = abs(p.x) - r;
	p.y = p.y + r / k;
	if (p.x + k * p.y > 0.0) p = vec2(p.x - k * p.y, -k * p.x - p.y) / 2.0;
	p.x -= clamp(p.x, -2.0 * r, 0.0);
	return -length(p) * sign(p.y);
}

float sd_venus(vec2 p, float thickness, float ring_radius, float cross_size) {
	float ring = op_onion(sd_circle(p, ring_radius), thickness);
	float d_cross = sd_cross(p + vec2(0.0, ring_radius + cross_size + thickness / 2.0), vec2(cross_size, thickness), 0.0);
	return op_add(ring, d_cross);
}

// --- Flags ---

vec3 color_sunset_5(vec2 uv, float delta) {
	vec3 color = butch_vermilion;
	color = mix(color, butch_apricot, smoothstep(1.0 / 5.0 - delta, 1.0 / 5.0 + delta, uv.y));
	color = mix(color, white, smoothstep(2.0 / 5.0 - delta, 2.0 / 5.0 + delta, uv.y));
	color = mix(color, femme_pink, smoothstep(3.0 / 5.0- delta, 3.0 / 5.0 + delta, uv.y));
	color = mix(color, femme_red_violet, smoothstep(4.0 / 5.0 - delta, 4.0 / 5.0 + delta, uv.y));
	return color;
}

vec3 color_sunset_7(vec2 uv, float delta) {
	vec3 color = butch_vermilion;
	color = mix(color, butch_orange, smoothstep(1.0 / 7.0 - delta, 1.0 / 7.0 + delta, uv.y));
	color = mix(color, butch_apricot, smoothstep(2.0 / 7.0 - delta, 2.0 / 7.0 + delta, uv.y));
	color = mix(color, white, smoothstep(3.0 / 7.0 - delta, 3.0 / 7.0 + delta, uv.y));
	color = mix(color, femme_pink, smoothstep(4.0 / 7.0 - delta, 4.0 / 7.0 + delta, uv.y));
	color = mix(color, femme_pink_lavender, smoothstep(5.0 / 7.0 - delta, 5.0 / 7.0 + delta, uv.y));
	color = mix(color, femme_red_violet, smoothstep(6.0 / 7.0 - delta, 6.0 / 7.0 + delta, uv.y));
	return color;
}

vec3 color_butch(vec2 uv, float delta) {
	vec3 color = butch_vermilion;
	color = mix(color, butch_orange, smoothstep(1.0 / 7.0 - delta, 1.0 / 7.0 + delta, uv.y));
	color = mix(color, butch_apricot, smoothstep(2.0 / 7.0 - delta, 2.0 / 7.0 + delta, uv.y));
	color = mix(color, white, smoothstep(3.0 / 7.0 - delta, 3.0 / 7.0 + delta, uv.y));
	color = mix(color, butch_peach, smoothstep(4.0 / 7.0 - delta, 4.0 / 7.0 + delta, uv.y));
	color = mix(color, butch_yellow, smoothstep(5.0 / 7.0 - delta, 5.0 / 7.0 + delta, uv.y));
	color = mix(color, butch_dark_goldenrod, smoothstep(6.0 / 7.0 - delta, 6.0 / 7.0 + delta, uv.y));
	return color;
}

vec3 color_femme(vec2 uv, float delta) {
	vec3 color = femme_red_violet;
	color = mix(color, femme_pink_lavender, smoothstep(1.0 / 7.0 - delta, 1.0 / 7.0 + delta, uv.y));
	color = mix(color, femme_pink, smoothstep(2.0 / 7.0 - delta, 2.0 / 7.0 + delta, uv.y));
	color = mix(color, white, smoothstep(3.0 / 7.0 - delta, 3.0 / 7.0 + delta, uv.y));
	color = mix(color, femme_pearl, smoothstep(4.0 / 7.0 - delta, 4.0 / 7.0 + delta, uv.y));
	color = mix(color, femme_coral, smoothstep(5.0 / 7.0 - delta, 5.0 / 7.0 + delta, uv.y));
	color = mix(color, femme_red, smoothstep(6.0 / 7.0 - delta, 6.0 / 7.0 + delta, uv.y));
	return color;
}

vec3 color_labrys(vec2 uv, float delta) {
	vec3 color = labrys_lavender;
	
	// Transform UV
	vec2 p = uv * 2.0 - 1.0;
	p.x *= aspect;
	delta *= 2.0;
	
	// Triangle
	const vec2 triangle_origin = vec2(0.0, -0.28);
	const float triangle_size = 0.97;
	float triangle = sd_equilateral_triangle(p - triangle_origin, triangle_size);
	color = mix(color, black, smoothstep(delta, -delta, triangle));
	
	// Labrys
	const vec2 head_origin = vec2(0.0, -0.44);
	const float head_radius = 0.55;
	float head = sd_circle(p - head_origin, head_radius);
	head = op_sub(head, sd_circle(abs(p - head_origin) + vec2(0.0, -head_radius * 1.2), head_radius));
	
	const vec2 handle_a = vec2(0.0, 0.56);
	const vec2 handle_b = vec2(0.0, -0.61);
	const float handle_radius = 0.037;
	const vec2 handle_scale = vec2(0.52, 1.0);
	float handle = sd_segment(p * handle_scale, handle_a , handle_b) - handle_radius;
	
	float labrys = op_add(op_sub(head, handle), handle + 0.007);
	color = mix(color, white, smoothstep(delta, -delta, labrys));

	return color;
}

vec3 color_rainbow(vec2 uv, float delta) {
	// Top stripes
	vec3 color = pride_red;
	color = mix(color, pride_orange, smoothstep(1.0 / 6.0 - delta, 1.0 / 6.0 + delta, uv.y));
	color = mix(color, pride_yellow, smoothstep(2.0 / 6.0 - delta, 2.0 / 6.0 + delta, uv.y));

	// Canton
	color = mix(color, nonspecific_navy, smoothstep(2.0 / 5.0 + delta, 2.0 / 5.0 - delta, uv.x));
	
	// Bottom stripes
	color = mix(color, pride_green, smoothstep(3.0 / 6.0 - delta, 3.0 / 6.0 + delta, uv.y));
	color = mix(color, pride_blue, smoothstep(4.0 / 6.0 - delta, 4.0 / 6.0 + delta, uv.y));
	color = mix(color, pride_purple, smoothstep(5.0 / 6.0 - delta, 5.0 / 6.0 + delta, uv.y));
	
	// Transform UV
	vec2 p = uv * 2.0 - 1.0;
	p.y *= -1.0;
	p -= vec2(-0.6, 0.62);
	p.x *= aspect;
	delta *= 2.0;
	
	// Venus symbols
	const float venus_thickness = 0.031;
	const float venus_ring_radius = 0.23;
	const float venus_cross_size = 0.12;
	const float venus_distance = 0.16;
	float venus_1 = sd_venus(p + vec2(venus_distance, 0.0), venus_thickness, venus_ring_radius, venus_cross_size);
	float venus_2 = sd_venus(p - vec2(venus_distance, 0.0), venus_thickness, venus_ring_radius, venus_cross_size);
	float emblem = op_add(venus_1, venus_2);
	color = mix(color, white, smoothstep(delta, -delta, emblem));
	
	return color;
}

void fragment() {
	vec3 color = vec3(0.0);

	float delta = length(dFdx(UV) + dFdy((UV))) * 0.5;
	switch(flag_type) {
		case 0:
			color = color_sunset_5(UV, delta);
			break;
		case 1:
			color = color_sunset_7(UV, delta);
			break;
		case 2:
			color = color_butch(UV, delta);
			break;
		case 3:
			color = color_femme(UV, delta);
			break;
		case 4:
			color = color_labrys(UV, delta);
			break;
		case 5:
			color = color_rainbow(UV, delta);
			break;
	}
	ALBEDO = color;
	
	// Add backlight to simulate translucent fabric
	BACKLIGHT = vec3(0.125);
}
Live Preview
Tags
flag, lesbian, LGBT, lgbtq+, pride
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.

More from tentabrobpy

guest

18 Comments
Oldest
Newest Most Voted
JekSun97
16 days ago

What the… Is this a shader or propaganda?

trinitrotoluene
16 days ago
Reply to  JekSun97

gaydot shaders 🥀

renderlessgames
renderlessgames
6 days ago
Reply to  JekSun97

Mental illness

gurg
gurg
16 days ago

deud……….. is that……………………. L-L-L-L-LESBIANS??!!?!??!??!?!@?!@?#??!??!?!?!! bro. EPIC FAIL!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! *pukes all over my poop*

carmi
carmi
16 days ago

we love it let’s shade

leon
leon
12 days ago

even in the shaders websites lol
ts is so forced

renderlessgames
renderlessgames
6 days ago
Reply to  leon

random colors for mental disorders

Horko
Horko
2 days ago
Reply to  leon

Leon, in case you weren’t aware, many (many) game developers are LGBTQ+. Please take the hatred and bigotry somewhere else.

Last edited 2 days ago by Horko
jesas
jesas
12 days ago

yuck.

thicker
thicker
9 days ago
Reply to  jesas

bro thinks lesbians are yucky XD are you a gayboy lol

Iama Hugh Asoel
Iama Hugh Asoel
9 days ago

Stand for the flag! Support your local lesbian today:
https://www.youtube.com/watch?v=Rf7ROU2_8UA

Last edited 9 days ago by Iama Hugh Asoel
bob
bob
8 days ago

I have no idea why they keep putting woke things in videogames, they need to give me custody of my children again

renderlessgames
renderlessgames
6 days ago
Reply to  bob

Welcome to sodom and gamorrah!

renderlessgames
renderlessgames
6 days ago

I’ll have Things That Don’t Exist for 500

Horko
Horko
2 days ago

Brother, this is a shaders website, we don’t need you spreading your bigotry/hatred. Take this somewhere else, please.

Skellysoft
Skellysoft
5 days ago

Holy shit I love these <3