summaryrefslogtreecommitdiff
path: root/shaders/gl_bloom_composite_fragment.glsl
blob: 5977e9135bbb206156bd88738febd4c0a5e366a6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
out vec4 outcolor;
in vec2 frag_texture_coord;

uniform sampler2D crt_texture;
uniform sampler2D bloom_texture;
uniform float bloom_strength;
uniform vec2 bloom_size;
uniform vec2 src_image_size;
uniform vec2 viewport_size;

void main() {
	vec3 crt_color = texture(crt_texture, frag_texture_coord).rgb;
	vec3 bloom_color = texture(bloom_texture, frag_texture_coord).rgb;

	// Calculate warp boundary mask to clip bloom outside CRT area
	vec2 ipos = frag_texture_coord * viewport_size;
	// Convert to normalized device coordinates [-1, 1]
	vec2 pos = ipos * (2.0 / viewport_size) - vec2(1.0);
	// Apply barrel distortion
	vec2 warp = vec2(1.0 / 24.0, 1.0 / 16.0);
	pos *= vec2(1.0 + (pos.y * pos.y) * warp.x, 1.0 + (pos.x * pos.x) * warp.y);
	// Convert back to UV
	vec2 uv = (pos + vec2(1.0)) * 0.5;

	// Rounded corner cutoff (CRT bezel effect) - only clips the corners
	float corner_radius = 0.05;  // Radius of corner rounding (0.0 = sharp corners, 0.2 = very rounded)
	vec2 edge_distance = abs(pos) - vec2(1.0 - corner_radius);
	float dist = length(max(edge_distance, 0.0));

	// Antialiased edge using smoothstep (creates soft 1-2 pixel transition)
	float edge_softness = 0.003;  // Controls antialiasing width (smaller = sharper)
	float mask = smoothstep(corner_radius + edge_softness, corner_radius - edge_softness, dist);

	// Also check bounds
	mask *= (uv.x >= 0.0 && uv.x <= 1.0 && uv.y >= 0.0 && uv.y <= 1.0) ? 1.0 : 0.0;

	outcolor = vec4((crt_color + bloom_color * bloom_strength) * mask, 1.0);
}