Godot Version
4.2.1
Question
I got this shader that gives this fog effect, the problem I have with it, is when the character moves the fog doesnt move(not that it should, it doesnt have the code!) and i have no idea how to make that effect with code, can someone help? this is the code for shader:
shader_type canvas_item;
// Credit for the original shader goes to Gonkee: https://github.com/Gonkee/Gonkees-Shaders/blob/master/fog.shader
// Pixelate by Godot Shaders: https://godotshaders.com/shader/pixelate/
uniform vec4 color : source_color;
uniform int OCTAVES = 10;
uniform bool enable_pixelation = true;
uniform int pixelation_amount = 150;
uniform sampler2D fog_mask; // Texture mask for fog control
uniform vec2 fog_direction = vec2(1.0, 1.0); // Use -1 and 1 values to change direction. Increase the speed in that direction with values higher/lower than 1
uniform bool scroll_noise_tex = false;
uniform vec2 noise_scroll_direction = vec2(1.0, 0.0); // Direction to scroll the noise texture
// Noise texture
uniform sampler2D noise_texture: repeat_enable, filter_nearest;
// Fog density
uniform float density: hint_range(0.0, 1.0) = 0.25;
// Fog speed
uniform vec2 speed = vec2(0.02, 0.01);
float rand(vec2 coord){
return fract(sin(dot(coord, vec2(56, 78)) * 1000.0) * 1000.0);
}
float noise(vec2 coord){
vec2 i = floor(coord);
vec2 f = fract(coord);
float a = rand(i);
float b = rand(i + vec2(1.0, 0.0));
float c = rand(i + vec2(0.0, 1.0));
float d = rand(i + vec2(1.0, 1.0));
vec2 cubic = f * f * (3.0 - 2.0 * f);
return mix(a, b, cubic.x) + (c - a) * cubic.y * (1.0 - cubic.x) + (d - b) * cubic.x * cubic.y;
}
float fbm(vec2 coord){
float value = 0.0;
float scale = 0.5;
for(int i = 0; i < OCTAVES; i++){
value += noise(coord) * scale;
coord *= 2.0;
scale *= 0.5;
}
return value;
}
void fragment() {
vec2 uv = UV + speed * TIME;
// Sample the noise texture
float noise = texture(noise_texture, uv).r;
// Convert the noise from the (0.0, 1.0) range to the (-1.0, 1.0) range
// and clamp it between 0.0 and 1.0 again
float fog = clamp(noise * 2.0 - 1.0, 0.0, 1.0);
// Apply the fog effect
COLOR.a *= fog * density;
vec2 grid_uv = UV;
if (enable_pixelation) {
grid_uv = round(UV * float(pixelation_amount)) / float(pixelation_amount);
}
// Compute noise based on pixelated or non-pixelated coordinates
vec2 coord = grid_uv * 5.0;
// Scroll the noise texture if enabled
if (scroll_noise_tex) {
coord += noise_scroll_direction * TIME;
}
vec2 motion = vec2(fbm(coord + fog_direction * TIME*.5));
float final = fbm(coord + motion);
// Get the fog density from the texture mask
float mask_value = texture(fog_mask, UV).r; // Assuming the mask is grayscale
// Modulate the fog density by the mask value
final *= mask_value;
// Use the alpha value of the color to control the overall fog opacity
COLOR = vec4(color.rgb, final * color.a * 0.5);
}
and I did try to ask chat gpt what to do and it told me to write this line of code in the map, but it didnt work at all, it just made the fog thicker:
extends Node2D
@onready var setfog = $CanvasLayer/ColorRect2 # ColorRect for the fog's visual
@onready var char = $player # Reference to the player node
@onready var fogshader = $CanvasLayer/ColorRect # ColorRect for the fog shader
var last_position = Vector2.ZERO
var player_move_direction = Vector2.ZERO # To track player movement direction
# Fog movement speed multiplier (increase to make the fog move faster)
var fog_speed_multiplier = 2.0 # Increase this value for faster fog movement
# Called when the node enters the scene tree for the first time
func _ready():
# Ensure the fog shader has a ShaderMaterial assigned
var shader_material = ShaderMaterial.new()
shader_material.shader = load("res://Scenes/test_tile.gdshader") # Update with your shader path
fogshader.material = shader_material
last_position = char.position # Set the initial position of the player
# Called every frame to update the fog and movement
func _process(delta):
update_fog_opacity(delta)
update_fog_movement(delta)
# Update fog opacity based on player's vertical movement
func update_fog_opacity(delta):
var direction = char.position - last_position
last_position = char.position # Update the last position to the current position
if direction.y < 0: # Moving up
setfog.color = Color(1, 1, 1, max(0.1, setfog.color.a - 0.05 * delta)) # Reduce opacity
elif direction.y > 0: # Moving down
setfog.color = Color(1, 1, 1, min(1.0, setfog.color.a + 0.05 * delta)) # Increase opacity
# Update the fog movement based on the player's direction
func update_fog_movement(delta):
# Calculate the movement direction from the player's current and last positions
player_move_direction = (char.position - last_position).normalized()
# Invert the direction to make the fog move opposite of the player
var fog_direction = -player_move_direction * fog_speed_multiplier # Multiply by fog speed multiplier
# Update shader parameter for fog movement direction
var shader_material = fogshader.material as ShaderMaterial
if shader_material:
shader_material.set_shader_parameter("player_move_direction", fog_direction) # Pass the inverted direction to the shader