1
0
mirror of https://github.com/godotengine/godot.git synced 2025-12-05 17:15:09 +00:00

Fix NaN populating ParticleProcessMaterial Transform

Use of normalize will cause transform matrix slices to be populated with NaN when the scale value was zero on the previous compute step.

Resolves this bug by adding a `normalize_or_else` function. Parameters are `_in`, and `_else`, with the former being the argument to test to see if it is a zero vec3, and the latter the vec3 to use in the event of `_in` being the zero vec.

closes #97680
closes #97621
This commit is contained in:
Derrick Melton
2024-10-06 00:40:03 -07:00
parent 6a76f18f77
commit c1b067f83c

View File

@@ -465,6 +465,13 @@ void ParticleProcessMaterial::_update_shader() {
code += "}\n\n";
}
code += "vec3 normalize_or_else(vec3 _in, const vec3 _else) {\n";
code += " if (_in == vec3(0.0)) {\n";
code += " return _else;\n";
code += " }\n";
code += " return normalize(_in);\n";
code += "}\n\n";
code += "vec4 rotate_hue(vec4 current_color, float hue_rot_angle) {\n";
code += " float hue_rot_c = cos(hue_rot_angle);\n";
code += " float hue_rot_s = sin(hue_rot_angle);\n";
@@ -1071,24 +1078,25 @@ void ParticleProcessMaterial::_update_shader() {
code += " TRANSFORM[2] = vec4(0.0, 0.0, 1.0, 0.0);\n";
}
} else {
//TODO Fix so 0 scaling on all axes doesn't break during normalization
// Orient particle Y towards velocity.
if (particle_flags[PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY]) {
code += " if (length(final_velocity) > 0.0) {\n";
code += " TRANSFORM[1].xyz = normalize(final_velocity);\n";
code += " TRANSFORM[1].xyz = normalize_or_else(final_velocity, vec3(0.0, 1.0, 0.0));\n";
code += " } else {\n";
code += " TRANSFORM[1].xyz = normalize(TRANSFORM[1].xyz);\n";
code += " TRANSFORM[1].xyz = normalize_or_else(TRANSFORM[1].xyz, vec3(0.0, 1.0, 0.0));\n";
code += " }\n";
code += " if (TRANSFORM[1].xyz == normalize(TRANSFORM[0].xyz)) {\n";
code += " TRANSFORM[0].xyz = normalize(cross(normalize(TRANSFORM[1].xyz), normalize(TRANSFORM[2].xyz)));\n";
code += " TRANSFORM[2].xyz = normalize(cross(normalize(TRANSFORM[0].xyz), normalize(TRANSFORM[1].xyz)));\n";
code += " if (TRANSFORM[1].xyz == normalize_or_else(TRANSFORM[0].xyz, vec3(1.0, 0.0, 0.0))) {\n";
code += " TRANSFORM[0].xyz = normalize_or_else(cross(TRANSFORM[1].xyz, TRANSFORM[2].xyz), vec3(1.0, 0.0, 0.0));\n";
code += " TRANSFORM[2].xyz = normalize_or_else(cross(TRANSFORM[0].xyz, TRANSFORM[1].xyz), vec3(0.0, 0.0, 1.0));\n";
code += " } else {\n";
code += " TRANSFORM[2].xyz = normalize(cross(normalize(TRANSFORM[0].xyz), normalize(TRANSFORM[1].xyz)));\n";
code += " TRANSFORM[0].xyz = normalize(cross(normalize(TRANSFORM[1].xyz), normalize(TRANSFORM[2].xyz)));\n";
code += " TRANSFORM[2].xyz = normalize_or_else(cross(TRANSFORM[0].xyz, TRANSFORM[1].xyz), vec3(0.0, 0.0, 1.0));\n";
code += " TRANSFORM[0].xyz = normalize_or_else(cross(TRANSFORM[1].xyz, TRANSFORM[2].xyz), vec3(1.0, 0.0, 0.0));\n";
code += " }\n";
} else {
code += " TRANSFORM[0].xyz = normalize(TRANSFORM[0].xyz);\n";
code += " TRANSFORM[1].xyz = normalize(TRANSFORM[1].xyz);\n";
code += " TRANSFORM[2].xyz = normalize(TRANSFORM[2].xyz);\n";
code += " TRANSFORM[0].xyz = normalize_or_else(TRANSFORM[0].xyz, vec3(1.0, 0.0, 0.0));\n";
code += " TRANSFORM[1].xyz = normalize_or_else(TRANSFORM[1].xyz, vec3(0.0, 1.0, 0.0));\n";
code += " TRANSFORM[2].xyz = normalize_or_else(TRANSFORM[2].xyz, vec3(0.0, 0.0, 1.0));\n";
}
// Turn particle by rotation in Y.
if (particle_flags[PARTICLE_FLAG_ROTATE_Y]) {