How to make 2d depth fog?

Godot Version

4.2

Question

Is there a way of making depth fog using the 2d editor ? I always stumble uppon that for fog you need depth and it needs to be 3d… But with the z index in 2d this shouldnt be to much of a big problem, there should be a way to make a shader in 2d that would read the z index…

Something that would make this effect… fog on the background, with the image getting more blured from the Z distance

It’s literally just a blur shader on background elements.

You can set the z_index from a script, and blur the image based on that.
(I haven’t tested it but something like below)

The script to set the z_index shader parameter

var z_index = $Sprite.z_index
$Sprite.material.set_shader_param(‘z_index’,z_index)

The shader which blurs based on that parameter

shader_type canvas_item;

uniform int z_index = 0;

uniform float blur_amount : hint_range(-2.0, 10.0);
uniform float mix_amount : hint_range(0.0, 1.0);
uniform vec4 color_over : hint_color;

void fragment() {
	vec4 blurredTex = textureLod(SCREEN_TEXTURE, SCREEN_UV, blur_amount);
        float z_mix = mix_amount * z_index;
	COLOR = mix(blurredTex, color_over, mix_amount);
}
shader_type canvas_item;

uniform int z_index = 0;

uniform float blur_amount : hint_range(-2.0, 10.0);
uniform float mix_amount : hint_range(0.0, 1.0);
uniform vec4 color_over : hint_color;

void fragment() {
vec4 blurredTex = textureLod(SCREEN_TEXTURE, SCREEN_UV, blur_amount);
float z_mix = mix_amount * z_index;
COLOR = mix(blurredTex, color_over, mix_amount);
}

I cant get this to work ( the image turns black )

It’s literally just a blur shader on background elements.

adding a blur shader its easy but the effect is not the same, i think a mix of pixelated shader + a blur shader would work… I was thinking more of a color rect that could be added on top of everything that foged all background layer beased on distance

1 Like

Any luck on this? I am attempting the same thing

i did this shader…

  1. set the blur, then 2. add a color with amount.
    Unfortunately no luck on the Z, cant get that 3D effect… This is also the only way to apply it to tiles, other way i tried godot applies the shader to every individual tile making everything look square
shader_type canvas_item;
render_mode blend_mix;

uniform float z_index = 0;

uniform float blur_amount : hint_range(-2.0, 10.0);
uniform float mix_amount : hint_range(0.0, 1.0);
uniform vec4 color_over : source_color;
uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap;

void fragment() {
	vec4 blurredTex = textureLod(SCREEN_TEXTURE, SCREEN_UV, blur_amount);
	float z_mix = mix_amount * z_index;
	COLOR = mix(blurredTex, color_over, mix_amount);
}

You may want to use this one instead… The other one uses the engine 3D “textureLod” i think this thing takes a lot of GPU

in the amount box use: 0.002… not 0.2

shader_type canvas_item;
render_mode blend_mix;

uniform float amount = 0.001;
uniform float mix_amount : hint_range(0.0, 10.0);
uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap;
uniform vec4 color_over : source_color;

void fragment() {
	vec4 new_color = texture(SCREEN_TEXTURE, SCREEN_UV);
	vec2 pixel_size = TEXTURE_PIXEL_SIZE;
	
	new_color += texture(SCREEN_TEXTURE, SCREEN_UV + vec2(0, -amount) * pixel_size);
	new_color += texture(SCREEN_TEXTURE, SCREEN_UV + vec2(0, amount) * pixel_size);
	new_color += texture(SCREEN_TEXTURE, SCREEN_UV + vec2(-amount, 0) * pixel_size);
	new_color += texture(SCREEN_TEXTURE, SCREEN_UV + vec2(amount, 0) * pixel_size);
	
	new_color += texture(SCREEN_TEXTURE, SCREEN_UV + vec2(-amount, amount) * pixel_size);
	new_color += texture(SCREEN_TEXTURE, SCREEN_UV + vec2(amount, amount) * pixel_size);
	
	new_color += texture(SCREEN_TEXTURE, SCREEN_UV + vec2(-amount, -amount) * pixel_size);
	new_color += texture(SCREEN_TEXTURE, SCREEN_UV + vec2(amount, -amount) * pixel_size);
	
	COLOR = new_color / mix_amount * color_over;
	//COLOR = mix(new_color, color_over, mix_amount);
}

if anyone has a better solution… ( that does not include applying the shader to all layers individually ) witch i dought anyway… would be nice to know.

1 Like