Skip to content

Commit 0e5b47e

Browse files
QbieShaySplizard
authored andcommitted
Fixed cpuparticles randomness regression caused by godotengine#92089
1 parent 83e066c commit 0e5b47e

File tree

4 files changed

+49
-35
lines changed

4 files changed

+49
-35
lines changed

scene/2d/cpu_particles_2d.cpp

+16-13
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "cpu_particles_2d.h"
3232
#include "cpu_particles_2d.compat.inc"
3333

34+
#include "core/math/random_number_generator.h"
3435
#include "scene/2d/gpu_particles_2d.h"
3536
#include "scene/resources/atlas_texture.h"
3637
#include "scene/resources/canvas_item_material.h"
@@ -769,30 +770,30 @@ void CPUParticles2D::_particles_process(double p_delta) {
769770
}
770771

771772
p.seed = seed + uint32_t(i) + i + cycle;
772-
uint32_t _seed = p.seed;
773+
rng->set_seed(p.seed);
773774

774-
p.angle_rand = rand_from_seed(_seed);
775-
p.scale_rand = rand_from_seed(_seed);
776-
p.hue_rot_rand = rand_from_seed(_seed);
777-
p.anim_offset_rand = rand_from_seed(_seed);
775+
p.angle_rand = rng->randf();
776+
p.scale_rand = rng->randf();
777+
p.hue_rot_rand = rng->randf();
778+
p.anim_offset_rand = rng->randf();
778779

779780
if (color_initial_ramp.is_valid()) {
780-
p.start_color_rand = color_initial_ramp->get_color_at_offset(rand_from_seed(_seed));
781+
p.start_color_rand = color_initial_ramp->get_color_at_offset(rng->randf());
781782
} else {
782783
p.start_color_rand = Color(1, 1, 1, 1);
783784
}
784785

785-
real_t angle1_rad = direction.angle() + Math::deg_to_rad((rand_from_seed(_seed) * 2.0 - 1.0) * spread);
786+
real_t angle1_rad = direction.angle() + Math::deg_to_rad((rng->randf() * 2.0 - 1.0) * spread);
786787
Vector2 rot = Vector2(Math::cos(angle1_rad), Math::sin(angle1_rad));
787-
p.velocity = rot * Math::lerp(parameters_min[PARAM_INITIAL_LINEAR_VELOCITY], parameters_max[PARAM_INITIAL_LINEAR_VELOCITY], (real_t)rand_from_seed(_seed));
788+
p.velocity = rot * Math::lerp(parameters_min[PARAM_INITIAL_LINEAR_VELOCITY], parameters_max[PARAM_INITIAL_LINEAR_VELOCITY], rng->randf());
788789

789790
real_t base_angle = tex_angle * Math::lerp(parameters_min[PARAM_ANGLE], parameters_max[PARAM_ANGLE], p.angle_rand);
790791
p.rotation = Math::deg_to_rad(base_angle);
791792

792793
p.custom[0] = 0.0; // unused
793794
p.custom[1] = 0.0; // phase [0..1]
794795
p.custom[2] = tex_anim_offset * Math::lerp(parameters_min[PARAM_ANIM_OFFSET], parameters_max[PARAM_ANIM_OFFSET], p.anim_offset_rand);
795-
p.custom[3] = (1.0 - rand_from_seed(_seed) * lifetime_randomness);
796+
p.custom[3] = (1.0 - rng->randf() * lifetime_randomness);
796797
p.transform = Transform2D();
797798
p.time = 0;
798799
p.lifetime = lifetime * p.custom[3];
@@ -803,17 +804,17 @@ void CPUParticles2D::_particles_process(double p_delta) {
803804
//do none
804805
} break;
805806
case EMISSION_SHAPE_SPHERE: {
806-
real_t t = Math_TAU * rand_from_seed(_seed);
807-
real_t radius = emission_sphere_radius * rand_from_seed(_seed);
807+
real_t t = Math_TAU * rng->randf();
808+
real_t radius = emission_sphere_radius * rng->randf();
808809
p.transform[2] = Vector2(Math::cos(t), Math::sin(t)) * radius;
809810
} break;
810811
case EMISSION_SHAPE_SPHERE_SURFACE: {
811-
real_t s = rand_from_seed(_seed), t = Math_TAU * rand_from_seed(_seed);
812+
real_t s = rng->randf(), t = Math_TAU * rng->randf();
812813
real_t radius = emission_sphere_radius * Math::sqrt(1.0 - s * s);
813814
p.transform[2] = Vector2(Math::cos(t), Math::sin(t)) * radius;
814815
} break;
815816
case EMISSION_SHAPE_RECTANGLE: {
816-
p.transform[2] = Vector2(rand_from_seed(_seed) * 2.0 - 1.0, rand_from_seed(_seed) * 2.0 - 1.0) * emission_rect_extents;
817+
p.transform[2] = Vector2(rng->randf() * 2.0 - 1.0, rng->randf() * 2.0 - 1.0) * emission_rect_extents;
817818
} break;
818819
case EMISSION_SHAPE_POINTS:
819820
case EMISSION_SHAPE_DIRECTED_POINTS: {
@@ -1523,6 +1524,8 @@ CPUParticles2D::CPUParticles2D() {
15231524
set_amount(8);
15241525
set_use_local_coordinates(false);
15251526

1527+
rng.instantiate();
1528+
15261529
set_param_min(PARAM_INITIAL_LINEAR_VELOCITY, 0);
15271530
set_param_min(PARAM_ANGULAR_VELOCITY, 0);
15281531
set_param_min(PARAM_ORBIT_VELOCITY, 0);

scene/2d/cpu_particles_2d.h

+4
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333

3434
#include "scene/2d/node_2d.h"
3535

36+
class RandomNumberGenerator;
37+
3638
class CPUParticles2D : public Node2D {
3739
private:
3840
GDCLASS(CPUParticles2D, Node2D);
@@ -179,6 +181,8 @@ class CPUParticles2D : public Node2D {
179181

180182
Vector2 gravity = Vector2(0, 980);
181183

184+
Ref<RandomNumberGenerator> rng;
185+
182186
void _update_internal();
183187
void _particles_process(double p_delta);
184188
void _update_particle_data_buffer();

scene/3d/cpu_particles_3d.cpp

+25-22
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "cpu_particles_3d.h"
3232
#include "cpu_particles_3d.compat.inc"
3333

34+
#include "core/math/random_number_generator.h"
3435
#include "scene/3d/camera_3d.h"
3536
#include "scene/3d/gpu_particles_3d.h"
3637
#include "scene/main/viewport.h"
@@ -818,27 +819,27 @@ void CPUParticles3D::_particles_process(double p_delta) {
818819
tex_anim_offset = curve_parameters[PARAM_ANGLE]->sample(tv);
819820
}
820821

821-
p.seed = seed;
822-
uint32_t _seed = seed + uint32_t(1) + i + cycle;
823-
p.angle_rand = rand_from_seed(_seed);
824-
p.scale_rand = rand_from_seed(_seed);
825-
p.hue_rot_rand = rand_from_seed(_seed);
826-
p.anim_offset_rand = rand_from_seed(_seed);
822+
p.seed = seed + uint32_t(1) + i + cycle;
823+
rng->set_seed(p.seed);
824+
p.angle_rand = rng->randf();
825+
p.scale_rand = rng->randf();
826+
p.hue_rot_rand = rng->randf();
827+
p.anim_offset_rand = rng->randf();
827828

828829
if (color_initial_ramp.is_valid()) {
829-
p.start_color_rand = color_initial_ramp->get_color_at_offset(rand_from_seed(_seed));
830+
p.start_color_rand = color_initial_ramp->get_color_at_offset(rng->randf());
830831
} else {
831832
p.start_color_rand = Color(1, 1, 1, 1);
832833
}
833834

834835
if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
835-
real_t angle1_rad = Math::atan2(direction.y, direction.x) + Math::deg_to_rad((rand_from_seed(_seed) * 2.0 - 1.0) * spread);
836+
real_t angle1_rad = Math::atan2(direction.y, direction.x) + Math::deg_to_rad((rng->randf() * 2.0 - 1.0) * spread);
836837
Vector3 rot = Vector3(Math::cos(angle1_rad), Math::sin(angle1_rad), 0.0);
837-
p.velocity = rot * Math::lerp(parameters_min[PARAM_INITIAL_LINEAR_VELOCITY], parameters_max[PARAM_INITIAL_LINEAR_VELOCITY], rand_from_seed(_seed));
838+
p.velocity = rot * Math::lerp(parameters_min[PARAM_INITIAL_LINEAR_VELOCITY], parameters_max[PARAM_INITIAL_LINEAR_VELOCITY], rng->randf());
838839
} else {
839840
//initiate velocity spread in 3D
840-
real_t angle1_rad = Math::deg_to_rad((rand_from_seed(_seed) * (real_t)2.0 - (real_t)1.0) * spread);
841-
real_t angle2_rad = Math::deg_to_rad((rand_from_seed(_seed) * (real_t)2.0 - (real_t)1.0) * ((real_t)1.0 - flatness) * spread);
841+
real_t angle1_rad = Math::deg_to_rad((rng->randf() * (real_t)2.0 - (real_t)1.0) * spread);
842+
real_t angle2_rad = Math::deg_to_rad((rng->randf() * (real_t)2.0 - (real_t)1.0) * ((real_t)1.0 - flatness) * spread);
842843

843844
Vector3 direction_xz = Vector3(Math::sin(angle1_rad), 0, Math::cos(angle1_rad));
844845
Vector3 direction_yz = Vector3(0, Math::sin(angle2_rad), Math::cos(angle2_rad));
@@ -858,14 +859,14 @@ void CPUParticles3D::_particles_process(double p_delta) {
858859
binormal.normalize();
859860
Vector3 normal = binormal.cross(direction_nrm);
860861
spread_direction = binormal * spread_direction.x + normal * spread_direction.y + direction_nrm * spread_direction.z;
861-
p.velocity = spread_direction * Math::lerp(parameters_min[PARAM_INITIAL_LINEAR_VELOCITY], parameters_max[PARAM_INITIAL_LINEAR_VELOCITY], rand_from_seed(_seed));
862+
p.velocity = spread_direction * Math::lerp(parameters_min[PARAM_INITIAL_LINEAR_VELOCITY], parameters_max[PARAM_INITIAL_LINEAR_VELOCITY], rng->randf());
862863
}
863864

864865
real_t base_angle = tex_angle * Math::lerp(parameters_min[PARAM_ANGLE], parameters_max[PARAM_ANGLE], p.angle_rand);
865866
p.custom[0] = Math::deg_to_rad(base_angle); //angle
866867
p.custom[1] = 0.0; //phase
867868
p.custom[2] = tex_anim_offset * Math::lerp(parameters_min[PARAM_ANIM_OFFSET], parameters_max[PARAM_ANIM_OFFSET], p.anim_offset_rand); //animation offset (0-1)
868-
p.custom[3] = (1.0 - rand_from_seed(_seed) * lifetime_randomness);
869+
p.custom[3] = (1.0 - rng->randf() * lifetime_randomness);
869870
p.transform = Transform3D();
870871
p.time = 0;
871872
p.lifetime = lifetime * p.custom[3];
@@ -876,20 +877,20 @@ void CPUParticles3D::_particles_process(double p_delta) {
876877
//do none
877878
} break;
878879
case EMISSION_SHAPE_SPHERE: {
879-
real_t s = 2.0 * rand_from_seed(_seed) - 1.0;
880-
real_t t = Math_TAU * rand_from_seed(_seed);
881-
real_t x = rand_from_seed(_seed);
880+
real_t s = 2.0 * rng->randf() - 1.0;
881+
real_t t = Math_TAU * rng->randf();
882+
real_t x = rng->randf();
882883
real_t radius = emission_sphere_radius * Math::sqrt(1.0 - s * s);
883884
p.transform.origin = Vector3(0, 0, 0).lerp(Vector3(radius * Math::cos(t), radius * Math::sin(t), emission_sphere_radius * s), x);
884885
} break;
885886
case EMISSION_SHAPE_SPHERE_SURFACE: {
886-
real_t s = 2.0 * rand_from_seed(_seed) - 1.0;
887-
real_t t = Math_TAU * rand_from_seed(_seed);
887+
real_t s = 2.0 * rng->randf() - 1.0;
888+
real_t t = Math_TAU * rng->randf();
888889
real_t radius = emission_sphere_radius * Math::sqrt(1.0 - s * s);
889890
p.transform.origin = Vector3(radius * Math::cos(t), radius * Math::sin(t), emission_sphere_radius * s);
890891
} break;
891892
case EMISSION_SHAPE_BOX: {
892-
p.transform.origin = Vector3(rand_from_seed(_seed) * 2.0 - 1.0, rand_from_seed(_seed) * 2.0 - 1.0, rand_from_seed(_seed) * 2.0 - 1.0) * emission_box_extents;
893+
p.transform.origin = Vector3(rng->randf() * 2.0 - 1.0, rng->randf() * 2.0 - 1.0, rng->randf() * 2.0 - 1.0) * emission_box_extents;
893894
} break;
894895
case EMISSION_SHAPE_POINTS:
895896
case EMISSION_SHAPE_DIRECTED_POINTS: {
@@ -933,11 +934,11 @@ void CPUParticles3D::_particles_process(double p_delta) {
933934
case EMISSION_SHAPE_RING: {
934935
real_t radius_clamped = MAX(0.001, emission_ring_radius);
935936
real_t top_radius = MAX(radius_clamped - Math::tan(Math::deg_to_rad(90.0 - emission_ring_cone_angle)) * emission_ring_height, 0.0);
936-
real_t y_pos = rand_from_seed(_seed);
937+
real_t y_pos = rng->randf();
937938
real_t skew = MAX(MIN(radius_clamped, top_radius) / MAX(radius_clamped, top_radius), 0.5);
938939
y_pos = radius_clamped < top_radius ? Math::pow(y_pos, skew) : 1.0 - Math::pow(y_pos, skew);
939-
real_t ring_random_angle = rand_from_seed(_seed) * Math_TAU;
940-
real_t ring_random_radius = Math::sqrt(rand_from_seed(_seed) * (radius_clamped * radius_clamped - emission_ring_inner_radius * emission_ring_inner_radius) + emission_ring_inner_radius * emission_ring_inner_radius);
940+
real_t ring_random_angle = rng->randf() * Math_TAU;
941+
real_t ring_random_radius = Math::sqrt(rng->randf() * (radius_clamped * radius_clamped - emission_ring_inner_radius * emission_ring_inner_radius) + emission_ring_inner_radius * emission_ring_inner_radius);
941942
ring_random_radius = Math::lerp(ring_random_radius, ring_random_radius * (top_radius / radius_clamped), y_pos);
942943
Vector3 axis = emission_ring_axis == Vector3(0.0, 0.0, 0.0) ? Vector3(0.0, 0.0, 1.0) : emission_ring_axis.normalized();
943944
Vector3 ortho_axis;
@@ -1764,6 +1765,8 @@ CPUParticles3D::CPUParticles3D() {
17641765
set_emitting(true);
17651766
set_amount(8);
17661767

1768+
rng.instantiate();
1769+
17671770
set_param_min(PARAM_INITIAL_LINEAR_VELOCITY, 0);
17681771
set_param_min(PARAM_ANGULAR_VELOCITY, 0);
17691772
set_param_min(PARAM_ORBIT_VELOCITY, 0);

scene/3d/cpu_particles_3d.h

+4
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333

3434
#include "scene/3d/visual_instance_3d.h"
3535

36+
class RandomNumberGenerator;
37+
3638
class CPUParticles3D : public GeometryInstance3D {
3739
private:
3840
GDCLASS(CPUParticles3D, GeometryInstance3D);
@@ -190,6 +192,8 @@ class CPUParticles3D : public GeometryInstance3D {
190192

191193
Vector3 gravity = Vector3(0, -9.8, 0);
192194

195+
Ref<RandomNumberGenerator> rng;
196+
193197
void _update_internal();
194198
void _particles_process(double p_delta);
195199
void _update_particle_data_buffer();

0 commit comments

Comments
 (0)