Grid Shader
A grid shader. This shader can do impressive effects such as ripple and implosion.
You can use it like that:
# — Ripple —
func trigger_ripple_effect(pos: Vector2, ripple_speed := 1200, thickness := 300, strength := 380):
if not is_instance_valid(background_shader_material): return
var current_time = Time.get_ticks_msec() / 1000.0
background_shader_material.set_shader_parameter(“ripple_speed”, ripple_speed)
background_shader_material.set_shader_parameter(“ripple_thickness”, thickness)
background_shader_material.set_shader_parameter(“ripple_peak_strength”, strength)
ripple_origins.push_front(pos)
ripple_start_times.push_front(current_time)
if ripple_origins.size() > MAX_PULSES:
ripple_origins.pop_back()
ripple_start_times.pop_back()
background_shader_material.set_shader_parameter(“active_pulse_count”, ripple_origins.size())
background_shader_material.set_shader_parameter(“ripple_origin_world”, ripple_origins)
background_shader_material.set_shader_parameter(“ripple_start_time”, ripple_start_times)
# — Implosion —
func trigger_implosion_effect(pos: Vector2, speed := 1000, thickness := 800, strength := 900):
if not is_instance_valid(background_shader_material): return
var current_time = Time.get_ticks_msec() / 1000.0
background_shader_material.set_shader_parameter(“implosion_speed”, speed)
background_shader_material.set_shader_parameter(“implosion_thickness”, thickness)
background_shader_material.set_shader_parameter(“implosion_peak_strength”, strength)
implosion_origins.push_front(pos)
implosion_start_times.push_front(current_time)
if implosion_origins.size() > MAX_PULSES:
implosion_origins.pop_back()
implosion_start_times.pop_back()
background_shader_material.set_shader_parameter(“active_pulse_count”, max(ripple_origins.size(), implosion_origins.size()))
background_shader_material.set_shader_parameter(“implosion_origin_world”, implosion_origins)
background_shader_material.set_shader_parameter(“implosion_start_time”, implosion_start_times)
You also need to set up its world.
Shader code
// Made by ZiexDev.
shader_type canvas_item;
// === GRID CONFIG ===
uniform vec4 grid_color : source_color = vec4(0.04, 0.05, 0.12, 1.0);
uniform float grid_spacing = 50.0;
uniform float line_thickness = 1.0;
// === GRID WORLD POS/BOUNDS ===
uniform vec2 grid_visual_world_pos = vec2(0.0, 0.0);
uniform vec2 grid_visual_world_size = vec2(1920.0, 1080.0);
uniform float global_time_sec;
// === MAX PULSES ===
const int MAX_PULSES = 3;
uniform int active_pulse_count;
// === PULSE DATA ===
uniform vec2 ripple_origin_world[MAX_PULSES];
uniform float ripple_start_time[MAX_PULSES];
uniform vec2 implosion_origin_world[MAX_PULSES];
uniform float implosion_start_time[MAX_PULSES];
// === SHARED PULSE CONFIG ===
uniform float ripple_speed = 1200.0;
uniform float ripple_thickness = 70.0;
uniform float ripple_peak_strength = 45.0;
uniform float implosion_speed = 1000.0;
uniform float implosion_thickness = 80.0;
uniform float implosion_peak_strength = 60.0;
void fragment() {
vec2 world_pos = grid_visual_world_pos + (UV * grid_visual_world_size);
vec2 displacement = vec2(0.0);
float effect_strength = 0.0;
for (int i = 0; i < MAX_PULSES; i++) {
if (i >= active_pulse_count) break;
// === RIPPLE ===
float dt_ripple = global_time_sec - ripple_start_time[i];
if (dt_ripple > 0.0) {
float dist = distance(world_pos, ripple_origin_world[i]);
float wave_front = dt_ripple * ripple_speed;
if (dist >= (wave_front - ripple_thickness) && dist <= wave_front) {
float t = (dist - (wave_front - ripple_thickness)) / ripple_thickness;
float strength = (t * t) * (1.0 - t);
float fade = max(1.0 - dist / 1500.0, 0.0);
vec2 dir = normalize(world_pos - ripple_origin_world[i]);
displacement += dir * (strength * ripple_peak_strength * fade);
effect_strength = max(effect_strength, strength * fade);
}
}
// === IMPLOSION ===
float dt_impl = global_time_sec - implosion_start_time[i];
if (dt_impl > 0.0) {
float dist = distance(world_pos, implosion_origin_world[i]);
float wave_front = dt_impl * implosion_speed;
if (dist >= (wave_front - implosion_thickness) && dist <= wave_front) {
float t = (dist - (wave_front - implosion_thickness)) / implosion_thickness;
float strength = (t * t) * (1.0 - t);
float fade = max(1.0 - dist / 1800.0, 0.0);
vec2 dir = normalize(world_pos - implosion_origin_world[i]);
displacement -= dir * (strength * implosion_peak_strength * fade);
effect_strength = max(effect_strength, strength * fade);
}
}
}
vec2 grid_coord = world_pos + displacement;
float x_mod = mod(grid_coord.x, grid_spacing);
float y_mod = mod(grid_coord.y, grid_spacing);
float alpha = 0.0;
if (x_mod < line_thickness || grid_spacing - x_mod < line_thickness ||
y_mod < line_thickness || grid_spacing - y_mod < line_thickness) {
alpha = 1.0;
}
alpha *= (1.0 - (effect_strength * effect_strength));
alpha = clamp(alpha, 0.0, 1.0);
vec4 color = grid_color * (1.0 + effect_strength * 3.0);
COLOR = mix(vec4(0.0), color, alpha);
}
// Made by ZiexDev.
