pub const BLUR_FRAG: &str = r#"
#version 330 core
in vec2 v_uv;
out vec4 frag_color;
uniform sampler2D u_texture;
uniform vec2 u_texel_size;
uniform vec2 u_direction;
uniform float u_sigma;
// Fixed 9-tap kernel weights + offsets (radius 4, precomputed for sigma≈1.5)
// For variable sigma, you'd compute these on the CPU and upload as uniforms.
const int N_TAPS = 5;
const float OFFSETS[5] = float[](0.0, 1.3846153846, 3.2307692308, 5.0769230769, 6.9230769231);
const float WEIGHTS[5] = float[](0.2270270270, 0.3162162162, 0.0702702703, 0.0162162162, 0.0054054054);
void main() {
vec4 result = texture(u_texture, v_uv) * WEIGHTS[0];
for (int i = 1; i < N_TAPS; ++i) {
vec2 off = u_direction * u_texel_size * OFFSETS[i] * (u_sigma / 1.5);
result += texture(u_texture, v_uv + off) * WEIGHTS[i];
result += texture(u_texture, v_uv - off) * WEIGHTS[i];
}
frag_color = result;
}
"#;Expand description
GLSL fragment shader source for the separable Gaussian blur pass.
Expects:
u_texture: sampler2D — input texture
u_texel_size: vec2 — 1/resolution
u_direction: vec2 — (1,0) for H, (0,1) for V
u_sigma: float — Gaussian sigma in pixels