Fixes to CPU particles for performance and avoiding NaNs.

This commit is contained in:
Juan Linietsky 2018-10-08 00:51:48 -03:00
parent b17e71b6e5
commit 14494dddd0
4 changed files with 52 additions and 35 deletions

View File

@ -4066,35 +4066,37 @@ void RasterizerStorageGLES3::multimesh_allocate(RID p_multimesh, int p_instances
multimesh->data.resize(format_floats * p_instances);
float *dataptr = multimesh->data.ptrw();
for (int i = 0; i < p_instances * format_floats; i += format_floats) {
int color_from = 0;
int custom_data_from = 0;
if (multimesh->transform_format == VS::MULTIMESH_TRANSFORM_2D) {
multimesh->data.write[i + 0] = 1.0;
multimesh->data.write[i + 1] = 0.0;
multimesh->data.write[i + 2] = 0.0;
multimesh->data.write[i + 3] = 0.0;
multimesh->data.write[i + 4] = 0.0;
multimesh->data.write[i + 5] = 1.0;
multimesh->data.write[i + 6] = 0.0;
multimesh->data.write[i + 7] = 0.0;
dataptr[i + 0] = 1.0;
dataptr[i + 1] = 0.0;
dataptr[i + 2] = 0.0;
dataptr[i + 3] = 0.0;
dataptr[i + 4] = 0.0;
dataptr[i + 5] = 1.0;
dataptr[i + 6] = 0.0;
dataptr[i + 7] = 0.0;
color_from = 8;
custom_data_from = 8;
} else {
multimesh->data.write[i + 0] = 1.0;
multimesh->data.write[i + 1] = 0.0;
multimesh->data.write[i + 2] = 0.0;
multimesh->data.write[i + 3] = 0.0;
multimesh->data.write[i + 4] = 0.0;
multimesh->data.write[i + 5] = 1.0;
multimesh->data.write[i + 6] = 0.0;
multimesh->data.write[i + 7] = 0.0;
multimesh->data.write[i + 8] = 0.0;
multimesh->data.write[i + 9] = 0.0;
multimesh->data.write[i + 10] = 1.0;
multimesh->data.write[i + 11] = 0.0;
dataptr[i + 0] = 1.0;
dataptr[i + 1] = 0.0;
dataptr[i + 2] = 0.0;
dataptr[i + 3] = 0.0;
dataptr[i + 4] = 0.0;
dataptr[i + 5] = 1.0;
dataptr[i + 6] = 0.0;
dataptr[i + 7] = 0.0;
dataptr[i + 8] = 0.0;
dataptr[i + 9] = 0.0;
dataptr[i + 10] = 1.0;
dataptr[i + 11] = 0.0;
color_from = 12;
custom_data_from = 12;
}
@ -4109,14 +4111,14 @@ void RasterizerStorageGLES3::multimesh_allocate(RID p_multimesh, int p_instances
} cu;
cu.colu = 0xFFFFFFFF;
multimesh->data.write[i + color_from + 0] = cu.colf;
dataptr[i + color_from + 0] = cu.colf;
custom_data_from = color_from + 1;
} else if (multimesh->color_format == VS::MULTIMESH_COLOR_FLOAT) {
multimesh->data.write[i + color_from + 0] = 1.0;
multimesh->data.write[i + color_from + 1] = 1.0;
multimesh->data.write[i + color_from + 2] = 1.0;
multimesh->data.write[i + color_from + 3] = 1.0;
dataptr[i + color_from + 0] = 1.0;
dataptr[i + color_from + 1] = 1.0;
dataptr[i + color_from + 2] = 1.0;
dataptr[i + color_from + 3] = 1.0;
custom_data_from = color_from + 4;
}
@ -4130,13 +4132,13 @@ void RasterizerStorageGLES3::multimesh_allocate(RID p_multimesh, int p_instances
} cu;
cu.colu = 0;
multimesh->data.write[i + custom_data_from + 0] = cu.colf;
dataptr[i + custom_data_from + 0] = cu.colf;
} else if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_FLOAT) {
multimesh->data.write[i + custom_data_from + 0] = 0.0;
multimesh->data.write[i + custom_data_from + 1] = 0.0;
multimesh->data.write[i + custom_data_from + 2] = 0.0;
multimesh->data.write[i + custom_data_from + 3] = 0.0;
dataptr[i + custom_data_from + 0] = 0.0;
dataptr[i + custom_data_from + 1] = 0.0;
dataptr[i + custom_data_from + 2] = 0.0;
dataptr[i + custom_data_from + 3] = 0.0;
}
}

View File

@ -592,7 +592,7 @@ void CPUParticles::_particles_process(float p_delta) {
Vector3 direction_xz = Vector3(Math::sin(angle1_rad), 0, Math::cos(angle1_rad));
Vector3 direction_yz = Vector3(0, Math::sin(angle2_rad), Math::cos(angle2_rad));
direction_yz.z = direction_yz.z / Math::sqrt(direction_yz.z); //better uniform distribution
direction_yz.z = direction_yz.z / MAX(0.0001, Math::sqrt(ABS(direction_yz.z))); //better uniform distribution
Vector3 direction = Vector3(direction_xz.x * direction_yz.z, direction_yz.y, direction_xz.z * direction_yz.z);
direction.normalize();
p.velocity = direction * parameters[PARAM_INITIAL_LINEAR_VELOCITY] * Math::lerp(1.0f, float(Math::randf()), randomness[PARAM_INITIAL_LINEAR_VELOCITY]);
@ -977,6 +977,8 @@ void CPUParticles::_update_particle_data_buffer() {
ptr += 17;
}
can_update = true;
}
#ifndef NO_THREADS
@ -989,8 +991,10 @@ void CPUParticles::_update_render_thread() {
#ifndef NO_THREADS
update_mutex->lock();
#endif
VS::get_singleton()->multimesh_set_as_bulk_array(multimesh, particle_data);
if (can_update) {
VS::get_singleton()->multimesh_set_as_bulk_array(multimesh, particle_data);
can_update = false; //wait for next time
}
#ifndef NO_THREADS
update_mutex->unlock();
@ -1061,6 +1065,8 @@ void CPUParticles::_notification(int p_what) {
}
}
bool processed = false;
if (time == 0 && pre_process_time > 0.0) {
float frame_time;
@ -1073,6 +1079,7 @@ void CPUParticles::_notification(int p_what) {
while (todo >= 0) {
_particles_process(frame_time);
processed = true;
todo -= frame_time;
}
}
@ -1091,6 +1098,7 @@ void CPUParticles::_notification(int p_what) {
while (todo >= frame_time) {
_particles_process(frame_time);
processed = true;
todo -= decr;
}
@ -1098,9 +1106,12 @@ void CPUParticles::_notification(int p_what) {
} else {
_particles_process(delta);
processed = true;
}
_update_particle_data_buffer();
if (processed) {
_update_particle_data_buffer();
}
}
}
@ -1424,6 +1435,8 @@ CPUParticles::CPUParticles() {
flags[i] = false;
}
can_update = false;
set_color(Color(1, 1, 1, 1));
#ifndef NO_THREADS

View File

@ -142,6 +142,8 @@ private:
int fixed_fps;
bool fractional_delta;
volatile bool can_update;
DrawOrder draw_order;
Ref<Mesh> mesh;

View File

@ -308,7 +308,7 @@ void ParticlesMaterial::_update_shader() {
code += " float angle2_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad * (1.0 - flatness);\n";
code += " vec3 direction_xz = vec3(sin(angle1_rad), 0, cos(angle1_rad));\n";
code += " vec3 direction_yz = vec3(0, sin(angle2_rad), cos(angle2_rad));\n";
code += " direction_yz.z = direction_yz.z / sqrt(direction_yz.z); // better uniform distribution\n";
code += " direction_yz.z = direction_yz.z / max(0.0001,sqrt(abs(direction_yz.z))); // better uniform distribution\n";
code += " vec3 direction = vec3(direction_xz.x * direction_yz.z, direction_yz.y, direction_xz.z * direction_yz.z);\n";
code += " direction = normalize(direction);\n";
code += " VELOCITY = direction * initial_linear_velocity * mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n";