Gaussian blur for Godot 4.3 Canvase layer

I made it with Chat GPT … I don’t know how it works … but i know that Chat GPT needed alot of help to get here so here you go …

 

EDIT: the one pass shader made my fps go down from 700 to 16 … so i updated it to 2 pass shader and a static kernel … this got things back up to 400 fps … not great for a blur but this is my best

you will have to create a canvase stack and 2 shader one vertical and the other horzantail … it is a smiple uncomment in the code … I also added a soft blur transtion to non blured … the varubles are exproted and the preview tells the full story …

Shader code
// A Gaussian blur shader for Godot 4.3
shader_type canvas_item;


uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap;

// The radius of the blur effect (number of pixels to blur, NOT USED).
uniform int blur_radius : hint_range(1, 32) = 8;

// Controls the intensity of the blur. (NOT USED)
uniform float blur_strength : hint_range(0.1, 10.0) = 10.0;

// Direction of the fade: 0 = left, 1 = right, 2 = top, 3 = bottom.
uniform int fade_direction : hint_range(0, 3) = 0;

// Sets the cutoff point for the blur fade (0.0 to 1.0).
uniform float fade_cutoff : hint_range(0.0, 1.0) = 0.2;

// Controls the sharpness of the fade transition.
uniform float fade_intensity : hint_range(0.1, 10.0) = 2.0;


// Calculated with with blur_radius of 32 and blur_strength of 10 (16 works nice as well)
const float gaussian_32[32] = float[](
    0.039940,0.039741,0.039149,0.038183,0.036869,0.035247,0.033361,0.031261,
	0.029002,0.026639,0.024225,0.021810,0.019441,0.017157,0.014990,0.012967,
	0.011105,0.009416,0.007904,0.006569,0.005405,0.004403,0.003552,0.002836,
	0.002242,0.001755,0.001360,0.001043,0.000792,0.000596,0.000444,0.000327
);

// Precomputed weights for the Gaussian kernel. (NOT USED)
float gaussian_weight(float i, float sigma) {
    return exp(-0.5 * (i * i) / (sigma * sigma));
}

// Precomputes the weights for the Gaussian kernel.
void calculate_kernel(out float kernel[32], int radius, float sigma) {
    float sum = 0.0;
    for (int i = 0; i <= radius; i++) {
        kernel[i] = gaussian_weight(float(i), sigma);
        sum += i == 0 ? kernel[i] : 2.0 * kernel[i];
    }
    for (int i = 0; i <= radius; i++) {
        kernel[i] /= sum;
    }
}

// Computes the fade factor based on the direction and UV coordinates.
float calculate_fade(vec2 uv) {
    float fade = 0.0;
    if (fade_direction == 0) {
        fade = uv.x; // Left to right
    } else if (fade_direction == 1) {
        fade = 1.0 - uv.x; // Right to left
    } else if (fade_direction == 2) {
        fade = uv.y; // Top to bottom
    } else {
        fade = 1.0 - uv.y; // Bottom to top
    }

    // Normalize fade based on cutoff and intensity.
    if (fade < fade_cutoff) {
        return 1.0; // Full blur
    }

    // Scale fade factor smoothly to 0 at the edge.
    fade = (fade - fade_cutoff) / (1.0 - fade_cutoff);
    return clamp(pow(1.0 - fade*2.0, fade_intensity), 0.0, 1.0);
}




void fragment() {
    vec2 resolution = SCREEN_PIXEL_SIZE;
    vec2 uv = SCREEN_UV;
	
	
	// Calculate the fade factor.
    float fade_factor = calculate_fade(uv);
    // Gaussian kernel weights.
    float kernel[32] ;//= gaussian_32; // remove this varuble and enable the next line
    calculate_kernel(kernel, blur_radius, blur_strength);
	
	 vec4 final_color = vec4(0.0);
	
    // Horizontal blur pass.
    //for (int i = -blur_radius; i <= blur_radius; i++) {
        //final_color += texture(SCREEN_TEXTURE, uv + vec2(0.0, float(i)) * resolution).rgba * kernel[abs(i)];
    //}


    // Vertical blur pass.
    for (int i = -blur_radius; i <= blur_radius; i++) {
        final_color += texture(SCREEN_TEXTURE, uv + vec2(0.0, float(i)) * resolution).rgba * kernel[abs(i)];
    }
	
	
	// One pass blur ... ***VERY BAD PROFORMANCE***
    //for (int x = -blur_radius; x <= blur_radius; x++) {
        //for (int y = -blur_radius; y <= blur_radius; y++) {
            //float weight = kernel[abs(x)] * kernel[abs(y)];
            //vec2 offset = vec2(float(x), float(y)) * resolution;
            //final_color += texture(SCREEN_TEXTURE, uv + offset).rgb * weight;
        //}
    //}

    // Output the blurred color.
	float alpha = fade_factor; // Transparency is tied to the fade factor.
	final_color.a = fade_factor;
	COLOR = final_color;
}
Tags
blur, gaussian blur
The shader code and all code snippets in this post are under CC0 license and can be used freely without the author's permission. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

Related shaders

Gaussian Blur

Gaussian Blur

Web Safe Darkened Gaussian Blur

Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments