Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cell Fluid Dynamics trail effect #5996

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
f7cb57e
Delete src/microbe_stage/Membrane.tscn
AverageNerdz Mar 9, 2025
17af9e1
Revamped Membrane.tscn and uploaded the new script
AverageNerdz Mar 9, 2025
91f3b07
Added shader attached to the ripple script
AverageNerdz Mar 9, 2025
bd124c8
Update MembraneWaterRipple.cs
AverageNerdz Mar 9, 2025
4522184
Delete src/microbe_stage/MembraneWaterRipple.cs
AverageNerdz Mar 9, 2025
d77ad10
Add files via upload
AverageNerdz Mar 9, 2025
ac03a15
Update MembraneWaterRipple.cs
AverageNerdz Mar 9, 2025
8deaf30
Delete src/microbe_stage/MembraneWaterRipple.cs
AverageNerdz Mar 9, 2025
6477983
Add files via upload
AverageNerdz Mar 9, 2025
42ac241
Delete src/microbe_stage/MembraneWaterRipple.cs
AverageNerdz Mar 9, 2025
b625242
Add files via upload
AverageNerdz Mar 9, 2025
218d381
Delete src/microbe_stage/MembraneWaterRipple.cs
AverageNerdz Mar 9, 2025
6f50e7e
Add files via upload
AverageNerdz Mar 9, 2025
e5027ac
Update MembraneWaterRipple.cs
AverageNerdz Mar 9, 2025
8bb5e02
Delete src/microbe_stage/MembraneWaterRipple.cs
AverageNerdz Mar 9, 2025
f7b0628
Add files via upload
AverageNerdz Mar 9, 2025
f2efe0e
Delete src/microbe_stage/MembraneWaterRipple.cs
AverageNerdz Mar 9, 2025
d26cbc9
Add files via upload
AverageNerdz Mar 9, 2025
74d4e64
Delete src/microbe_stage/MembraneWaterRipple.cs
AverageNerdz Mar 9, 2025
5f0c559
Add files via upload
AverageNerdz Mar 9, 2025
1380043
Delete src/microbe_stage/MembraneWaterRipple.cs
AverageNerdz Mar 9, 2025
c662589
Add files via upload
AverageNerdz Mar 9, 2025
c168487
Delete src/microbe_stage/MembraneWaterRipple.cs
AverageNerdz Mar 9, 2025
d067d8f
Add files via upload
AverageNerdz Mar 9, 2025
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
182 changes: 182 additions & 0 deletions shaders/MembraneWaterRipple.gdshader
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
shader_type spatial;
render_mode blend_mix, depth_prepass_alpha, cull_back, diffuse_lambert;

uniform vec4 water_color : source_color = vec4(0.0, 0.0, 0.0, 0.02); // Almost completely transparent background
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our shaders should also use our C# naming convention so this should be converted to use pascalCase naming convention rather than snake_case. Also the trailing comments should be changed to be comments on the line before what they are commenting on to match Thrive style.

uniform float ripple_strength = 0.8; // Increased for more pronounced ripples
uniform float time_offset = 0.0;
uniform float movement_speed = 0.0;
uniform vec2 movement_direction = vec2(0.0, 0.0);
uniform float phase = 0.2;
uniform float attenuation = 0.998; // regulates viscositi - Higher values = less viscous, longer lasting ripples

// Wave height calculation with improved long-distance propagation
float wave_height(vec2 position, vec2 center, float time, float elapsed) {
// Distance from wave origin
float dist = length(position - center);

// Primary wave
float speed = 2.0; // VISCOSITY: Higher speed = less viscous appearance
float frequency = 1.5;
float amplitude = 0.6 * exp(-0.05 * dist); // VISCOSITY: Lower exp decay factor = less viscous appearance
float primary_wave = amplitude * sin(dist * frequency - time * speed);

// Add subtle harmonic overtones for more natural water movement
float harmonic1 = 0.12 * sin(dist * frequency * 1.5 - time * speed * 1.3) * exp(-0.1 * dist);
float harmonic2 = 0.08 * sin(dist * frequency * 0.7 - time * speed * 0.7) * exp(-0.07 * dist);

// Combine waves with logarithmic decay for more distant propagation
float combined = primary_wave + harmonic1 + harmonic2;

// Use a gentler time decay for much longer lasting effect
// VISCOSITY: Lower elapsed decay (0.25) = less viscous water with longer-lasting ripples
// VISCOSITY: Lower distance decay (0.08) = ripples travel further like less viscous fluid
return combined * exp(-elapsed * 0.25) * exp(-0.08 * dist);
}

// Physics-based water ripple simulation with enhanced trail and propagation
float simulate_ripples(vec2 position, vec2 direction, float speed, float time) {
// Generate minimal ripples even when barely moving
if (speed < 0.03) speed = 0.03;

// We'll simulate ripples generated at different positions along the movement path
// Ripple origins follow the movement direction
float total_ripple = 0.0;

// Current position of the membrane (origin for new ripples)
vec2 current_pos = vec2(0.0, 0.0);

// Simulate multiple ripple sources from object's recent past positions (longer trail)
for (int i = 0; i < 14; i++) { // VISCOSITY: More iterations = longer trail, less viscous appearance
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm seeing quite a lot of loops and ifs so I would expect this shader to be pretty expensive, so we probably need to have a graphics option to turn this off.

// Previous positions along movement path (farther back in time for larger i)
float time_ago = float(i) * 0.15; // VISCOSITY: Lower factor = ripples closer together, more viscous

// Position of the membrane at time (time - time_ago)
vec2 past_pos = current_pos - direction * speed * 5.0 * time_ago; // VISCOSITY: Higher multiplier = longer trail

// Calculate wave height from this past position
// More recent positions (smaller i) have stronger effect
float wave = wave_height(position, past_pos, time, time_ago);

// If very close to object, create depression (water pushed down by object)
if (i < 1 && length(position - current_pos) < 0.8) {
// Water gets pushed down where object is
float depression = 0.8 * (1.0 - length(position - current_pos) / 0.8);
wave -= depression * 0.5;
}

if (i > 1 && i < 8) {
// Calculate position relative to trail
vec2 to_pos = position - past_pos;
float along_trail = dot(to_pos, direction);
vec2 projected = past_pos + along_trail * direction;
float perp_dist = length(position - projected);

if (along_trail < 0.0 && perp_dist < 3.5 * (1.0 + float(i) * 0.25)) {
float v_angle = 0.2 + float(i) * 0.04;
float v_width = abs(along_trail) * v_angle;
float v_line_dist = abs(perp_dist - v_width);

// Add wake trail ripples with more pronounced pattern
if (v_line_dist < 1.2) {
float wake_intensity = (1.0 - v_line_dist / 1.2) * 0.25 * exp(-float(i) * 0.18);
wave += wake_intensity * sin(along_trail * 2.0 - time * 4.0);
}
}
}

// These create additional subtle ripples that propagate further
if (i > 2) {
// Secondary ripples - smaller, higher frequency waves that propagate further
float secondary_dist = length(position - past_pos);
if (secondary_dist > 2.0 && secondary_dist < 18.0) {
float secondary_wave = 0.18 * sin(secondary_dist * 2.3 - time * 3.0 + float(i)) *
exp(-0.06 * secondary_dist) * exp(-time_ago * 0.2);
wave += secondary_wave;
}

// Tertiary ripples - very subtle, low frequency waves for distant propagation
if (secondary_dist > 4.0 && secondary_dist < 30.0) { // Extended range for longer propagation
float tertiary_wave = 0.1 * sin(secondary_dist * 0.9 - time * 1.5 + float(i) * 0.5) *
exp(-0.025 * secondary_dist) * exp(-time_ago * 0.12);
wave += tertiary_wave;
}
}

// This creates the elongated appearance of ripples behind a moving object
vec2 to_pos = position - past_pos;
float along_dir = dot(to_pos, direction);
if (along_dir < 0.0 && along_dir > -12.0) {
// Stretch factor increases with distance for more pronounced trail
float stretch_factor = min(1.0, -along_dir * 0.1) * 0.3;

// Create stretched ripples that extend behind the movement
float stretched_wave = 0.15 * sin(along_dir * 1.5 - time * 2.0) *
exp(along_dir * 0.1) * exp(-time_ago * 0.3);

// Add elongated wake pattern for more natural water trail
wave += stretched_wave * stretch_factor;
}

// VISCOSITY: Lower time_ago decay factor (0.5) = longer lasting trail, less viscous appearance
total_ripple += wave * (1.0 - time_ago * 0.5);
}

// Add edge fade to prevent hard cutoffs at mesh edges
float edge_dist = min(8.0 - abs(position.x), 8.0 - abs(position.y));
float edge_fade = smoothstep(0.0, 2.0, edge_dist);

// Scale by movement speed and strength with edge fade
return total_ripple * speed * edge_fade;
}

void vertex() {
// Get vertex position in model space
vec2 pos = VERTEX.xz;

// Apply water simulation with enhanced trail
float displacement = simulate_ripples(pos, movement_direction, movement_speed, time_offset);

// Apply height displacement
VERTEX.y += displacement * ripple_strength;

// Calculate normals for proper lighting with finer sampling for detailed ripples
vec3 normal = NORMAL;
if (abs(displacement) > 0.001) {
// Smaller step size for more detailed normals
float step_size = 0.08;
float dx = (simulate_ripples(pos + vec2(step_size, 0.0), movement_direction, movement_speed, time_offset) -
simulate_ripples(pos - vec2(step_size, 0.0), movement_direction, movement_speed, time_offset)) / (2.0 * step_size);
float dz = (simulate_ripples(pos + vec2(0.0, step_size), movement_direction, movement_speed, time_offset) -
simulate_ripples(pos - vec2(0.0, step_size), movement_direction, movement_speed, time_offset)) / (2.0 * step_size);

// Create normal from gradient
vec3 gradient_normal = normalize(vec3(-dx * ripple_strength, 1.0, -dz * ripple_strength));

// Blend normal for smooth transitions
float blend_factor = min(1.0, abs(displacement) * 5.0);
normal = normalize(mix(NORMAL, gradient_normal, blend_factor));
}

NORMAL = normal;
}

void fragment() {
// Simple water coloring
float depth_factor = clamp(1.0 - (-VERTEX.y * 0.5), 0.0, 1.0);

// Keep color fully transparent, only showing ripple distortion
vec3 final_color = vec3(0.0, 0.0, 0.0); // Invisible base color

// Basic lighting
float n_dot_l = dot(NORMAL, normalize(vec3(0.4, 0.8, 0.3)));
float view_dot_normal = max(0.0, dot(normalize(VIEW), NORMAL));

// Final coloring - enhance this values to make ripples more visible
float enhanced_highlight = pow(max(0.0, n_dot_l), 8.0) * 0.4;
float enhanced_fresnel = pow(1.0 - view_dot_normal, 2.0) * 0.5;
ALBEDO = final_color + vec3(enhanced_highlight) + vec3(0.8, 0.9, 1.0) * enhanced_fresnel;

SPECULAR = 0.7; // Increased specular to highlight ripples
ROUGHNESS = 0.1; // Decreased roughness for more pronounced reflections
ALPHA = water_color.a;
}
18 changes: 13 additions & 5 deletions src/microbe_stage/Membrane.tscn
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
[gd_scene load_steps=13 format=3 uid="uid://jgcbwcrqbblv"]
[gd_scene load_steps=14 format=3 uid="uid://jgcbwcrqbblv"]

[ext_resource type="Script" uid="uid://bs82n6jeyxhg6" path="res://src/microbe_stage/Membrane.cs" id="1"]
[ext_resource type="Shader" uid="uid://c10kaqsum34o" path="res://shaders/Membrane.gdshader" id="2"]
[ext_resource type="Script" uid="uid://cfo6vubwh8xay" path="res://src/microbe_stage/Membrane.cs" id="1"]
[ext_resource type="Shader" uid="uid://n5en0070niam" path="res://shaders/Membrane.gdshader" id="2"]
[ext_resource type="Texture2D" uid="uid://c4abs1j47umma" path="res://assets/textures/SingleMembrane.png" id="3_mj630"]
[ext_resource type="Texture2D" uid="uid://dnxx08njuvfha" path="res://assets/textures/SingleMembraneDamaged.png" id="4_yioiy"]
[ext_resource type="Texture2D" uid="uid://baxuoyeo83r2u" path="res://assets/textures/dissolve_noise.tres" id="5"]
[ext_resource type="Shader" uid="uid://buhqlk4dv4wy4" path="res://shaders/EngulfEffect.gdshader" id="6_vljlr"]
[ext_resource type="Shader" uid="uid://c331kb4yta46" path="res://shaders/EngulfEffect.gdshader" id="6_vljlr"]
[ext_resource type="Texture2D" uid="uid://bvxwsysj3kj2j" path="res://assets/textures/MembraneNormals.png" id="6_wjsrx"]
[ext_resource type="Shader" uid="uid://duvkpd0301bv0" path="res://shaders/MucocystEffect.gdshader" id="7_grw0d"]
[ext_resource type="Shader" uid="uid://djouei06equ3y" path="res://shaders/MucocystEffect.gdshader" id="7_grw0d"]
[ext_resource type="Script" uid="uid://h7vrv62tr4sx" path="res://src/microbe_stage/MembraneWaterRipple.cs" id="9_water"]

[sub_resource type="BoxMesh" id="1"]
size = Vector3(2, 0.539, 2)
Expand All @@ -25,6 +26,10 @@ shader_parameter/dissolveTexture = ExtResource("5")
shader_parameter/dissolveValue = 0.0
shader_parameter/healthFraction = 0.25
shader_parameter/tint = Color(1, 1, 1, 1)
shader_parameter/water_time = 0.0
shader_parameter/water_strength = 0.03
shader_parameter/water_wiggle = 1.0
shader_parameter/water_color = Color(0, 0.3, 0.6, 0.4)

[sub_resource type="ShaderMaterial" id="ShaderMaterial_p8cmc"]
resource_local_to_scene = true
Expand Down Expand Up @@ -62,3 +67,6 @@ visible = false

[node name="MucocystMesh" type="MeshInstance3D" parent="."]
visible = false

[node name="WaterRipple" type="Node" parent="."]
script = ExtResource("9_water")
Loading