feat(shader): Expand Gaussian blur to 13-tap wide distribution

- Update horizontal and vertical blur shaders from 9-tap to 13-tap kernel
- Use Gaussian weights with sigma=3.5 for creamier 'milky' blur effect
- Add test_blur_pipeline_wide_tap_distribution to verify >= 11 texture samples
- Weights: [0.0152, 0.0300, 0.0525, 0.0812, 0.1110, 0.1342, 0.1432] (symmetric)

Task: Phase 1, Task 3 of frosted_glass_20260313 track
This commit is contained in:
2026-03-13 20:28:12 -04:00
parent b3e6590cb4
commit c8b7fca368
3 changed files with 44 additions and 19 deletions

View File

@@ -3,7 +3,7 @@
## Phase 1: Robust Shader & FBO Foundation
- [x] Task: Implement: Create `ShaderManager` methods for downsampled FBO setup (scene, temp, blur). [d9148ac]
- [x] Task: Implement: Develop the "Deep Sea" background shader and integrate it as the FBO source. [d85dc3a]
- [ ] Task: Implement: Develop the 2-pass Gaussian blur shaders with a wide tap distribution.
- [~] Task: Implement: Develop the 2-pass Gaussian blur shaders with a wide tap distribution.
- [ ] Task: Conductor - User Manual Verification 'Phase 1: Robust Foundation' (Protocol in workflow.md)
## Phase 2: High-Performance Blur Pipeline

View File

@@ -238,15 +238,19 @@ out vec4 FragColor;
void main() {
vec2 offset = vec2(u_texel_size.x, 0.0);
vec4 sum = vec4(0.0);
sum += texture(u_texture, v_uv - offset * 4.0) * 0.051;
sum += texture(u_texture, v_uv - offset * 3.0) * 0.0918;
sum += texture(u_texture, v_uv - offset * 2.0) * 0.12245;
sum += texture(u_texture, v_uv - offset * 1.0) * 0.1531;
sum += texture(u_texture, v_uv) * 0.1633;
sum += texture(u_texture, v_uv + offset * 1.0) * 0.1531;
sum += texture(u_texture, v_uv + offset * 2.0) * 0.12245;
sum += texture(u_texture, v_uv + offset * 3.0) * 0.0918;
sum += texture(u_texture, v_uv + offset * 4.0) * 0.051;
sum += texture(u_texture, v_uv - offset * 6.0) * 0.0152;
sum += texture(u_texture, v_uv - offset * 5.0) * 0.0300;
sum += texture(u_texture, v_uv - offset * 4.0) * 0.0525;
sum += texture(u_texture, v_uv - offset * 3.0) * 0.0812;
sum += texture(u_texture, v_uv - offset * 2.0) * 0.1110;
sum += texture(u_texture, v_uv - offset * 1.0) * 0.1342;
sum += texture(u_texture, v_uv) * 0.1432;
sum += texture(u_texture, v_uv + offset * 1.0) * 0.1342;
sum += texture(u_texture, v_uv + offset * 2.0) * 0.1110;
sum += texture(u_texture, v_uv + offset * 3.0) * 0.0812;
sum += texture(u_texture, v_uv + offset * 4.0) * 0.0525;
sum += texture(u_texture, v_uv + offset * 5.0) * 0.0300;
sum += texture(u_texture, v_uv + offset * 6.0) * 0.0152;
FragColor = sum;
}
"""
@@ -259,15 +263,19 @@ out vec4 FragColor;
void main() {
vec2 offset = vec2(0.0, u_texel_size.y);
vec4 sum = vec4(0.0);
sum += texture(u_texture, v_uv - offset * 4.0) * 0.051;
sum += texture(u_texture, v_uv - offset * 3.0) * 0.0918;
sum += texture(u_texture, v_uv - offset * 2.0) * 0.12245;
sum += texture(u_texture, v_uv - offset * 1.0) * 0.1531;
sum += texture(u_texture, v_uv) * 0.1633;
sum += texture(u_texture, v_uv + offset * 1.0) * 0.1531;
sum += texture(u_texture, v_uv + offset * 2.0) * 0.12245;
sum += texture(u_texture, v_uv + offset * 3.0) * 0.0918;
sum += texture(u_texture, v_uv + offset * 4.0) * 0.051;
sum += texture(u_texture, v_uv - offset * 6.0) * 0.0152;
sum += texture(u_texture, v_uv - offset * 5.0) * 0.0300;
sum += texture(u_texture, v_uv - offset * 4.0) * 0.0525;
sum += texture(u_texture, v_uv - offset * 3.0) * 0.0812;
sum += texture(u_texture, v_uv - offset * 2.0) * 0.1110;
sum += texture(u_texture, v_uv - offset * 1.0) * 0.1342;
sum += texture(u_texture, v_uv) * 0.1432;
sum += texture(u_texture, v_uv + offset * 1.0) * 0.1342;
sum += texture(u_texture, v_uv + offset * 2.0) * 0.1110;
sum += texture(u_texture, v_uv + offset * 3.0) * 0.0812;
sum += texture(u_texture, v_uv + offset * 4.0) * 0.0525;
sum += texture(u_texture, v_uv + offset * 5.0) * 0.0300;
sum += texture(u_texture, v_uv + offset * 6.0) * 0.0152;
FragColor = sum;
}
"""

View File

@@ -43,6 +43,23 @@ def test_blur_pipeline_compile_shaders():
assert pipeline.h_blur_program is not None
assert pipeline.v_blur_program is not None
def test_blur_pipeline_wide_tap_distribution():
with patch("src.shader_manager.gl") as mock_gl:
mock_gl.glCreateProgram.return_value = 100
mock_gl.glCreateShader.return_value = 200
mock_gl.glGetShaderiv.return_value = mock_gl.GL_TRUE
mock_gl.glGetProgramiv.return_value = mock_gl.GL_TRUE
from src.shader_manager import BlurPipeline
pipeline = BlurPipeline()
pipeline.compile_blur_shaders()
assert mock_gl.glShaderSource.called
shader_sources = [call.args[1] for call in mock_gl.glShaderSource.call_args_list]
frag_sources = [s for s in shader_sources if 'texture(' in s and 'offset' in s]
assert len(frag_sources) >= 2
for src in frag_sources:
texture_calls = src.count('texture(u_texture')
assert texture_calls >= 11, f"Expected at least 11 texture samples for wide tap distribution, got {texture_calls}"
def test_blur_pipeline_render_deepsea_to_fbo():
with patch("src.shader_manager.gl") as mock_gl:
tex_counter = iter([10, 20, 30])