summaryrefslogtreecommitdiff
path: root/shaders/post/bloom.glsl
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-29 07:41:35 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:16 -0300
commit411d0b6059192b75853e220e1242b694ae461a3e (patch)
tree50f8bb207f3cdda497bdd84658a2d3ea74b4bc2b /shaders/post/bloom.glsl
parentda920ca49e3f5d1649e811bbdc3ddba482c6aae4 (diff)
parent5526c68beec454cfe607a579723b97b4848e7d3a (diff)
downloadpardes-411d0b6059192b75853e220e1242b694ae461a3e.tar.gz
pardes-411d0b6059192b75853e220e1242b694ae461a3e.zip
Merge: 9P rounds 9-17 + render DPI, dark tints, G4-G10
Diffstat (limited to 'shaders/post/bloom.glsl')
-rw-r--r--shaders/post/bloom.glsl40
1 files changed, 40 insertions, 0 deletions
diff --git a/shaders/post/bloom.glsl b/shaders/post/bloom.glsl
new file mode 100644
index 00000000..d54a0aac
--- /dev/null
+++ b/shaders/post/bloom.glsl
@@ -0,0 +1,40 @@
+// Bloom: the brightest ink glows, a little. The glow itself is made by the
+// shell at half resolution and below (bloom-down, bloom-up: a dual Kawase
+// filter over a bright pass, in linear light) and arrives here in
+// pardesBloom; this pass adds it to the frame. Only true highlights pass
+// the threshold, and the strength stays in ยง8.2's budget (at most 5%) and
+// under pardesCap, so no text or selection loses contrast below its own or
+// 4.5. Tags, grips, notices and the cursor are left alone (pardesSpare).
+// It is a Shadertoy file: pardes puts its prefix before it.
+
+layout(set = 2, binding = 1) uniform sampler2D pardesBloom;
+
+float strength() { return min(pardesByLevel(0.02, 0.035, 0.05), pardesCap); }
+
+vec3 toLinear(vec3 c) {
+ return mix(pow((c + 0.055) / 1.055, vec3(2.4)), c / 12.92, lessThanEqual(c, vec3(0.04045)));
+}
+
+vec3 toSrgb(vec3 c) {
+ c = max(c, vec3(0.0));
+ return mix(1.055 * pow(c, vec3(1.0 / 2.4)) - 0.055, c * 12.92, lessThanEqual(c, vec3(0.0031308)));
+}
+
+float ign(vec2 p) {
+ return fract(52.9829189 * fract(dot(p, vec2(0.06711056, 0.00583715))));
+}
+
+void mainImage(out vec4 fragColor, in vec2 fragCoord) {
+ vec2 uv = fragCoord / iResolution.xy;
+ vec4 frame = texture(iChannel0, uv);
+ if (pardesSpared(fragCoord)) {
+ fragColor = frame;
+ return;
+ }
+ vec3 glow = texture(pardesBloom, uv).rgb;
+ vec3 col = toLinear(frame.rgb) + glow * strength();
+ vec3 srgb = toSrgb(col);
+ // Dithered: a glow's long falloff never bands.
+ srgb += (ign(fragCoord) - 0.5) / 255.0 * step(1e-4, dot(glow, vec3(1.0)));
+ fragColor = vec4(clamp(srgb, 0.0, 1.0), frame.a);
+}