Skip to content
This repository was archived by the owner on Jun 5, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions addons/post_processing/node/children/particle_storm.tscn
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[gd_scene load_steps=3 format=3 uid="uid://c0d4h1un0350r"]

[ext_resource type="Shader" path="res://addons/post_processing/shaders/particle_storm.gdshader" id="1_wnruh"]

[sub_resource type="ShaderMaterial" id="ShaderMaterial_particle_storm"]
shader = ExtResource("1_wnruh")
shader_parameter/particle_color = Color(0.87, 0.78, 0.6, 1)
shader_parameter/wind_direction = Vector2(1, 0.2)
shader_parameter/wind_speed = 1.0
shader_parameter/intensity = 0.5
shader_parameter/chaos = 1.075
shader_parameter/scale = 1.0
shader_parameter/density = 1.0

[node name="particle_storm" type="CanvasLayer"]
visible = false

[node name="data" type="ColorRect" parent="."]
material = SubResource("ShaderMaterial_particle_storm")
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
12 changes: 12 additions & 0 deletions addons/post_processing/node/post_process.gd
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ enum EffectType {
GRAIN,
OUTLINE,
PALETTE,
PARTICLE_STORM,
PIXELATE,
SCREEN_SHAKE,
SPEED_LINES,
Expand Down Expand Up @@ -112,6 +113,14 @@ func _update_shader_parameters( _type : EffectType, _material : Material) -> voi
_material.set_shader_parameter("clip_warp", configuration.clip_warp)
_material.set_shader_parameter("vignette_intensity", configuration.vignette_intensity)
_material.set_shader_parameter("vignette_opacity", configuration.vignette_opacity)
EffectType.PARTICLE_STORM: # Add new case
_material.set_shader_parameter("particle_color", configuration.particle_storm_color)
_material.set_shader_parameter("wind_direction", configuration.particle_storm_wind_direction)
_material.set_shader_parameter("wind_speed", configuration.particle_storm_wind_speed)
_material.set_shader_parameter("intensity", configuration.particle_storm_intensity)
_material.set_shader_parameter("chaos", configuration.particle_storm_chaos)
_material.set_shader_parameter("scale", configuration.particle_storm_scale)
_material.set_shader_parameter("density", configuration.particle_storm_density)
_:
push_error("Unhandled/Invalid EffectType: " + str(_type))

Expand Down Expand Up @@ -150,6 +159,8 @@ func _check_shader_visibility(_type: EffectType) -> bool:
return configuration.SpeedLines
EffectType.VIGNETTE:
return configuration.Vignette
EffectType.PARTICLE_STORM:
return configuration.particle_storm
_:
push_error("Unhandled/Invalid EffectType: " + str(_type))
return false
Expand All @@ -172,6 +183,7 @@ func _ready():
_add_canvas_layer_children("res://addons/post_processing/node/children/color_correction.tscn", EffectType.COLOR_CORRECTION)
_add_canvas_layer_children("res://addons/post_processing/node/children/pixelate.tscn", EffectType.PIXELATE)
_add_canvas_layer_children("res://addons/post_processing/node/children/palette.tscn", EffectType.PALETTE)
_add_canvas_layer_children("res://addons/post_processing/node/children/particle_storm.tscn", EffectType.PARTICLE_STORM)

var null_effects: PackedStringArray = []
for e in effects:
Expand Down
43 changes: 39 additions & 4 deletions addons/post_processing/resource/no_effects_example.tres
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,6 @@ Outline = false
OutlineColor = Color(0, 0, 0, 1)
OutlineThreshold = 0.0
OutlineBlend = 0.01
ScreenShake = false
ScreenShakePower = 0.1
AnalogMonitor = false
AnalogMonitorResolution = Vector2(256, 256)
Grain = false
GrainPower = 75
CircularWaves = false
Expand All @@ -47,3 +43,42 @@ SpeedLinesColor = Color(1, 1, 1, 1)
SpeedLinesCount = 2
SpeedLineDensity = 0.072
SpeedLineSpeed = 20
particle_storm = false
particle_storm_color = Color(0.87, 0.78, 0.6, 1)
particle_storm_intensity = 0.5
particle_storm_chaos = 1.0
particle_storm_scale = 1.0
particle_storm_density = 1.0
particle_storm_wind_direction = Vector2(1, 0.2)
particle_storm_wind_speed = 1.0
ColorCorrection = false
ColorCorrectionTint = Color(0, 0, 0, 1)
ColorCorrectionBrightness = 0.0
ColorCorrectionSaturation = 0.0
Palette = false
Pixelate = false
PixelatePixelSize = 8
CRT = false
overlay = false
scanlines_opacity = 0.4
scanlines_width = 0.25
grille_opacity = 0.3
pixelate = true
roll_speed = 8.0
roll_size = 15.0
roll_variation = 1.8
distort_intensity = 0.05
noise_opacity = 0.4
noise_speed = 5.0
static_noise_intensity = 0.06
aberration = 0.03
brightness = 1.4
discolor = true
warp_amount = 1.0
clip_warp = false
vignette_intensity = 0.4
vignette_opacity = 0.5
AnalogMonitor = false
AnalogMonitorResolution = Vector2(256, 256)
ScreenShake = false
ScreenShakePower = 0.1
35 changes: 35 additions & 0 deletions addons/post_processing/resource/post_processing_configuration.gd
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,41 @@ class_name PostProcessingConfiguration extends Resource
set(value):
SpeedLineSpeed = value
reload = true
@export_subgroup("Particle Storm")
@export var particle_storm: bool:
set(value):
particle_storm = value
reload = true
@export var particle_storm_color: Color = Color(0.87, 0.78, 0.60, 1.0):
set(value):
particle_storm_color = value
reload = true
@export_range(0.0, 10.0) var particle_storm_intensity = 0.5:
set(value):
particle_storm_intensity = value
reload = true
@export_range(0.0, 10.0) var particle_storm_chaos = 1.0:
set(value):
particle_storm_chaos = value
reload = true
@export_range(0.5, 10.0) var particle_storm_scale = 1.0:
set(value):
particle_storm_scale = value
reload = true
@export_range(0.0, 10.0) var particle_storm_density = 1.0:
set(value):
particle_storm_density = value
reload = true
@export var particle_storm_wind_direction = Vector2(1.0, 0.2):
set(value):
particle_storm_wind_direction = value
reload = true
@export_range(0.1, 5.0) var particle_storm_wind_speed = 1.0:
set(value):
particle_storm_wind_speed = value
reload = true



@export_group("Display")
@export_subgroup("Color Correction")
Expand Down
95 changes: 95 additions & 0 deletions addons/post_processing/shaders/particle_storm.gdshader
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
shader_type canvas_item;

// Visual appearance parameters
uniform vec4 particle_color : source_color = vec4(0.87, 0.78, 0.60, 1.0);
uniform vec2 wind_direction = vec2(1.0, 0.2); // Normalized direction vector
uniform float wind_speed = 1.0; // Movement speed multiplier
uniform float intensity = 0.5; // Overall particle visibility
uniform float chaos = 1.0; // Swirl movement intensity
uniform float scale = 1.0; // UV coordinate scaling factor
uniform float density = 1.0; // Particles per cell multiplier

// Generates a stable pseudo-random 2D vector from a 2D input
vec2 hash22(vec2 seed_position) {
vec3 hash_input = fract(vec3(seed_position.xyx) * vec3(443.897, 441.423, 437.195));
hash_input += dot(hash_input, hash_input.yzx + 19.19);
return fract((hash_input.xx + hash_input.yz) * hash_input.zy);
}

// Calculates particle position based on time and initial conditions
vec2 get_particle_pos(vec2 cell_position, float particle_index, float current_time) {
// Generate initial position using cell and particle index
vec2 initial_position = hash22(cell_position + particle_index * 123.456);

// Generate unique movement characteristics for this particle
vec2 particle_characteristics = hash22(initial_position * 123.456);
float velocity_variation = 0.7 + particle_characteristics.x * 0.6;

// Calculate wind-driven movement
vec2 wind_offset = wind_direction * current_time * velocity_variation;

// Calculate swirling motion parameters
float swirl_phase = current_time * (0.5 + particle_characteristics.y * 0.5);
float swirl_amplitude = 0.1 + particle_characteristics.x * 0.1;
vec2 swirl_offset = vec2(
sin(swirl_phase + initial_position.y * 6.28),
cos(swirl_phase + initial_position.x * 6.28)
) * swirl_amplitude * chaos;

// Combine movements and wrap around unit space
return fract(initial_position + wind_offset + swirl_offset);
}

// Renders a single square particle with soft edges
float get_pixel(vec2 current_uv, vec2 particle_center) {
vec2 distance_to_center = abs(current_uv - particle_center);

// Base particle size with scale adjustment
float particle_size = 0.04 / scale;

// Create soft-edged square shape
float square_distance = max(distance_to_center.x, distance_to_center.y);
return 1.0 - smoothstep(particle_size * 0.8, particle_size, square_distance);
}

void fragment() {
// Transform UV coordinates to scaled space
vec2 scaled_uv = UV * scale;
vec2 current_cell = floor(scaled_uv);
vec2 cell_local_uv = fract(scaled_uv);

// Calculate time-based movement
float current_time = TIME * wind_speed;

float total_sand_density = 0.0;

// Calculate particle count based on density parameter
float particles_per_cell = floor(4.0 + density * 12.0);

// Render particles from current and neighboring cells
for (float x = -1.0; x <= 1.0; x++) {
for (float y = -1.0; y <= 1.0; y++) {
vec2 neighbor_offset = vec2(x, y);
vec2 neighbor_cell = current_cell + neighbor_offset;

// Generate and render all particles in this cell
for (float particle_idx = 0.0; particle_idx < particles_per_cell; particle_idx++) {
vec2 particle_pos = get_particle_pos(neighbor_cell, particle_idx, current_time);
vec2 world_pos = (particle_pos + neighbor_offset);

// Accumulate particle density
total_sand_density += get_pixel(cell_local_uv, world_pos) * 0.25;
}
}
}

// Apply intensity and clamp to valid range
total_sand_density *= intensity;
total_sand_density = clamp(total_sand_density, 0.0, 1.0);

// Quantize density for sharper particle appearance
total_sand_density = floor(total_sand_density * 6.0) / 6.0;

// Output final color with transparency
COLOR = vec4(particle_color.rgb, total_sand_density * particle_color.a);
}