Screen fog with camera offset
A shader heavily based on this code: https://godotshaders.com/shader/screen-smoke-fog/ by TheHyper-Dev
It adds an additional layer of noise that can move on different direction.
It also can take the camera position and offset into account, for games with moving cameras. With the original shader code, the fog moved along with the camera, giving a weird effect. This code tries to remedy that, by allowing to move the camera and fog staying in the same place.
Remember to add both noise textures. I recommend to add a noise texture with lower frequency on “noise_texture_1” and higher frequency on “noise_texture_2, both with seamless set to 1.0.
Also, tweak with camera_position_speed and camera_offset_speed to match your camera speed.
Add this shader to a ColorTexture. After that, add a script to the node with something like this:
func _process(_delta: float) -> void: if is_node_ready(): if visible: if camera: material.set_shader_parameter( "camera_position", camera.global_position ) material.set_shader_parameter( "camera_offset", camera.offset ) position = camera.position - get_viewport_rect().size / 2.0 position += camera.offset
Shader code
// Based on https://godotshaders.com/shader/screen-smoke-fog/
shader_type canvas_item;
render_mode blend_mix;
// Stuff related to camera position and offsets
uniform vec2 camera_position;
uniform vec2 camera_offset;
uniform float camera_position_speed: hint_range(0.0, 1.0) = 0.025;
uniform float camera_offset_speed: hint_range(0.0, 1.0) = 0.025;
// Uniforms for customization
uniform sampler2D noise_texture_1 : repeat_enable;
uniform sampler2D noise_texture_2 : repeat_enable;
uniform float noise_blend : hint_range(0.0, 1.0) = 1.0;
uniform float noise_speed_1 : hint_range(0.0, 1.0) = 1.0;
uniform float noise_speed_2 : hint_range(0.0, 1.0) = 1.0;
uniform vec2 noise_dir_1 = vec2(1.0,+1.0);
uniform vec2 noise_dir_2 = vec2(1.0,-1.0);
uniform vec3 smoke_color : source_color = vec3(0.8);
uniform float density : hint_range(0.0, 1.0) = 1.0;
void fragment() {
vec2 offset = ( (camera_position * camera_position_speed) + (camera_offset * camera_offset_speed) );
vec2 time_offset_1 = TIME * noise_dir_1 * noise_speed_1 * 0.1;
vec2 time_offset_2 = TIME * noise_dir_2 * noise_speed_2 * 0.1;
// Create distorted UV and sample final noise
vec2 distorted_uv_1 = UV + time_offset_1 + vec2(offset.x,offset.y * 1.75) * 0.1;
vec2 distorted_uv_2 = UV + time_offset_2 + vec2(offset.x,offset.y * 1.75) * 0.1;
vec4 final_noise_1 = texture(noise_texture_1, distorted_uv_1);
vec4 final_noise_2 = texture(noise_texture_2, distorted_uv_2);
float mixed_noise = mix(final_noise_1, final_noise_2, noise_blend).r;
float smoke_alpha = mixed_noise * density;
// Output color
COLOR = vec4(smoke_color, smoke_alpha);
}

