ShaderToMP4

HomeAccueil / ExamplesExemples

Two-pass separable blurFlou séparable en deux passes

Common defines the scene; A draws it, B blurs it horizontally, the final image blurs vertically and adds the sharp original.Common définit la scène ; A la dessine, B la floute horizontalement, l'image finale floute verticalement et ajoute l'original net.

Two-pass separable blur / Flou séparable en deux passes

CategoryCatégorie: Multiple passesPasses multiples - flou_en_deux_passes.glsl - 24 lineslignes - File on GitHubFichier sur GitHub

In the program: Examples, choose it, Add to the list. Or copy the code into a file next to the program and drop it on the window.Dans le programme : Exemples, choisissez-le, Ajouter à la liste. Ou copiez le code dans un fichier et glissez-le sur la fenêtre.

This example uses several passes: the files below go together.Cet exemple utilise plusieurs passes : les fichiers ci-dessous vont ensemble.

CodeCode

flou_en_deux_passes.glsl

// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (C) 2026 Patrick JAILLET

// fr: Flou séparable en deux passes — Common définit la scène ; A la dessine, B la floute horizontalement, l'image finale floute verticalement et ajoute l'original net.
// en: Two-pass separable blur — Common defines the scene; A draws it, B blurs it horizontally, the final image blurs vertically and adds the sharp original.

// iChannel0=bufferB
// iChannel1=bufferA
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 px = 1.0 / iResolution.xy;
    vec2 uv = fragCoord * px;
    vec3 blur = vec3(0.0);
    float wsum = 0.0;
    for (int i = -8; i <= 8; i++) {
        float w = exp(-float(i * i) / 24.0);
        blur += w * texture(iChannel0, uv + vec2(0.0, float(i)) * px * 2.0).rgb;
        wsum += w;
    }
    blur /= wsum;
    vec3 sharp = texture(iChannel1, uv).rgb;
    float split = 0.5 + 0.3 * sin(iTime * 0.5);
    fragColor = vec4(uv.x < split ? sharp : blur + sharp * 0.3, 1.0);
}

flou_en_deux_passes.bufferA.glsl

// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (C) 2026 Patrick JAILLET

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    fragColor = vec4(scene((fragCoord - 0.5 * iResolution.xy) / iResolution.y), 1.0);
}

flou_en_deux_passes.bufferB.glsl

// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (C) 2026 Patrick JAILLET

// iChannel0=bufferA
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 px = 1.0 / iResolution.xy;
    vec2 uv = fragCoord * px;
    vec3 acc = vec3(0.0);
    float wsum = 0.0;
    for (int i = -8; i <= 8; i++) {
        float w = exp(-float(i * i) / 24.0);
        acc += w * texture(iChannel0, uv + vec2(float(i), 0.0) * px * 2.0).rgb;
        wsum += w;
    }
    fragColor = vec4(acc / wsum, 1.0);
}

flou_en_deux_passes.common.glsl

// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (C) 2026 Patrick JAILLET

vec3 scene(vec2 uv) {
    vec3 col = vec3(0.02, 0.03, 0.08);
    for (int i = 0; i < 6; i++) {
        float f = float(i);
        vec2 c = 0.35 * vec2(cos(iTime * 0.7 + f * 1.05), sin(iTime * 0.9 + f * 2.1));
        col += (0.5 + 0.5 * cos(f + vec3(0.0, 2.0, 4.0))) * smoothstep(0.08, 0.0, length(uv - c));
    }
    return col;
}