From f666c76a9cd19b1e9b8d45d6c069e65d6fd6ec3f Mon Sep 17 00:00:00 2001 From: Rudolph Bester Date: Tue, 28 May 2024 14:09:08 +0200 Subject: [PATCH] Fixed collided 3D GPU particles sometimes jittering --- drivers/gles3/shaders/particles.glsl | 14 ++++++++------ .../rendering/renderer_rd/shaders/particles.glsl | 12 +++++++----- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/drivers/gles3/shaders/particles.glsl b/drivers/gles3/shaders/particles.glsl index 096f0a57ae69..2591937a1da8 100644 --- a/drivers/gles3/shaders/particles.glsl +++ b/drivers/gles3/shaders/particles.glsl @@ -372,10 +372,10 @@ void main() { float d = vec4_to_float(texture(height_field_texture, uv_pos)) * SDF_MAX_LENGTH; + // Allowing for a small epsilon to allow particle just touching colliders to count as collided + const float EPSILON = 0.001; d -= sdf_particle_size; - - if (d < 0.0) { - const float EPSILON = 0.001; + if (d < EPSILON) { vec2 n = normalize(vec2( vec4_to_float(texture(height_field_texture, uv_pos + vec2(EPSILON, 0.0))) - vec4_to_float(texture(height_field_texture, uv_pos - vec2(EPSILON, 0.0))), vec4_to_float(texture(height_field_texture, uv_pos + vec2(0.0, EPSILON))) - vec4_to_float(texture(height_field_texture, uv_pos - vec2(0.0, EPSILON))))); @@ -400,10 +400,12 @@ void main() { vec3 rel_vec = xform[3].xyz - colliders[i].transform[3].xyz; vec3 local_pos = rel_vec * mat3(colliders[i].transform); + // Allowing for a small epsilon to allow particle just touching colliders to count as collided + const float EPSILON = 0.001; if (colliders[i].type == COLLIDER_TYPE_SPHERE) { float d = length(rel_vec) - (particle_size + colliders[i].extents.x); - if (d < 0.0) { + if (d < EPSILON) { col = true; depth = -d; normal = normalize(rel_vec); @@ -418,7 +420,7 @@ void main() { vec3 closest = min(abs_pos, colliders[i].extents.xyz); vec3 rel = abs_pos - closest; depth = length(rel) - particle_size; - if (depth < 0.0) { + if (depth < EPSILON) { col = true; normal = mat3(colliders[i].transform) * (normalize(rel) * sgn_pos); depth = -depth; @@ -453,7 +455,7 @@ void main() { float y = 1.0 - texture(height_field_texture, uvw_pos.xz).r; - if (y > uvw_pos.y) { + if (y + EPSILON > uvw_pos.y) { //inside heightfield vec3 pos1 = (vec3(uvw_pos.x, y, uvw_pos.z) * 2.0 - 1.0) * colliders[i].extents.xyz; diff --git a/servers/rendering/renderer_rd/shaders/particles.glsl b/servers/rendering/renderer_rd/shaders/particles.glsl index efdf1c2278f4..60c49bacaed7 100644 --- a/servers/rendering/renderer_rd/shaders/particles.glsl +++ b/servers/rendering/renderer_rd/shaders/particles.glsl @@ -528,11 +528,13 @@ void main() { vec3 rel_vec = PARTICLE.xform[3].xyz - FRAME.colliders[i].transform[3].xyz; vec3 local_pos = rel_vec * mat3(FRAME.colliders[i].transform); + // Allowing for a small epsilon to allow particle just touching colliders to count as collided + const float EPSILON = 0.001; switch (FRAME.colliders[i].type) { case COLLIDER_TYPE_SPHERE: { float d = length(rel_vec) - (particle_size + FRAME.colliders[i].extents.x); - if (d < 0.0) { + if (d <= EPSILON) { col = true; depth = -d; normal = normalize(rel_vec); @@ -549,7 +551,7 @@ void main() { vec3 closest = min(abs_pos, FRAME.colliders[i].extents); vec3 rel = abs_pos - closest; depth = length(rel) - particle_size; - if (depth < 0.0) { + if (depth <= EPSILON) { col = true; normal = mat3(FRAME.colliders[i].transform) * (normalize(rel) * sgn_pos); depth = -depth; @@ -588,10 +590,10 @@ void main() { float s = texture(sampler3D(sdf_vec_textures[FRAME.colliders[i].texture_index], SAMPLER_LINEAR_CLAMP), uvw_pos).r; s *= FRAME.colliders[i].scale; s += extra_dist; - if (s < particle_size) { + if (s <= particle_size + EPSILON) { col = true; depth = particle_size - s; - const float EPSILON = 0.001; + normal = mat3(FRAME.colliders[i].transform) * normalize( vec3( @@ -614,7 +616,7 @@ void main() { float y = texture(sampler2D(height_field_texture, SAMPLER_LINEAR_CLAMP), uvw_pos.xz).r; - if (y > uvw_pos.y) { + if (y + EPSILON >= uvw_pos.y) { //inside heightfield vec3 pos1 = (vec3(uvw_pos.x, y, uvw_pos.z) * 2.0 - 1.0) * FRAME.colliders[i].extents;