Skip to content

Commit c1b067f

Browse files
committed
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 godotengine#97680 closes godotengine#97621
1 parent 6a76f18 commit c1b067f

File tree

1 file changed

+18
-10
lines changed

1 file changed

+18
-10
lines changed

scene/resources/particle_process_material.cpp

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,13 @@ void ParticleProcessMaterial::_update_shader() {
465465
code += "}\n\n";
466466
}
467467

468+
code += "vec3 normalize_or_else(vec3 _in, const vec3 _else) {\n";
469+
code += " if (_in == vec3(0.0)) {\n";
470+
code += " return _else;\n";
471+
code += " }\n";
472+
code += " return normalize(_in);\n";
473+
code += "}\n\n";
474+
468475
code += "vec4 rotate_hue(vec4 current_color, float hue_rot_angle) {\n";
469476
code += " float hue_rot_c = cos(hue_rot_angle);\n";
470477
code += " float hue_rot_s = sin(hue_rot_angle);\n";
@@ -1071,24 +1078,25 @@ void ParticleProcessMaterial::_update_shader() {
10711078
code += " TRANSFORM[2] = vec4(0.0, 0.0, 1.0, 0.0);\n";
10721079
}
10731080
} else {
1081+
//TODO Fix so 0 scaling on all axes doesn't break during normalization
10741082
// Orient particle Y towards velocity.
10751083
if (particle_flags[PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY]) {
10761084
code += " if (length(final_velocity) > 0.0) {\n";
1077-
code += " TRANSFORM[1].xyz = normalize(final_velocity);\n";
1085+
code += " TRANSFORM[1].xyz = normalize_or_else(final_velocity, vec3(0.0, 1.0, 0.0));\n";
10781086
code += " } else {\n";
1079-
code += " TRANSFORM[1].xyz = normalize(TRANSFORM[1].xyz);\n";
1087+
code += " TRANSFORM[1].xyz = normalize_or_else(TRANSFORM[1].xyz, vec3(0.0, 1.0, 0.0));\n";
10801088
code += " }\n";
1081-
code += " if (TRANSFORM[1].xyz == normalize(TRANSFORM[0].xyz)) {\n";
1082-
code += " TRANSFORM[0].xyz = normalize(cross(normalize(TRANSFORM[1].xyz), normalize(TRANSFORM[2].xyz)));\n";
1083-
code += " TRANSFORM[2].xyz = normalize(cross(normalize(TRANSFORM[0].xyz), normalize(TRANSFORM[1].xyz)));\n";
1089+
code += " if (TRANSFORM[1].xyz == normalize_or_else(TRANSFORM[0].xyz, vec3(1.0, 0.0, 0.0))) {\n";
1090+
code += " TRANSFORM[0].xyz = normalize_or_else(cross(TRANSFORM[1].xyz, TRANSFORM[2].xyz), vec3(1.0, 0.0, 0.0));\n";
1091+
code += " TRANSFORM[2].xyz = normalize_or_else(cross(TRANSFORM[0].xyz, TRANSFORM[1].xyz), vec3(0.0, 0.0, 1.0));\n";
10841092
code += " } else {\n";
1085-
code += " TRANSFORM[2].xyz = normalize(cross(normalize(TRANSFORM[0].xyz), normalize(TRANSFORM[1].xyz)));\n";
1086-
code += " TRANSFORM[0].xyz = normalize(cross(normalize(TRANSFORM[1].xyz), normalize(TRANSFORM[2].xyz)));\n";
1093+
code += " TRANSFORM[2].xyz = normalize_or_else(cross(TRANSFORM[0].xyz, TRANSFORM[1].xyz), vec3(0.0, 0.0, 1.0));\n";
1094+
code += " TRANSFORM[0].xyz = normalize_or_else(cross(TRANSFORM[1].xyz, TRANSFORM[2].xyz), vec3(1.0, 0.0, 0.0));\n";
10871095
code += " }\n";
10881096
} else {
1089-
code += " TRANSFORM[0].xyz = normalize(TRANSFORM[0].xyz);\n";
1090-
code += " TRANSFORM[1].xyz = normalize(TRANSFORM[1].xyz);\n";
1091-
code += " TRANSFORM[2].xyz = normalize(TRANSFORM[2].xyz);\n";
1097+
code += " TRANSFORM[0].xyz = normalize_or_else(TRANSFORM[0].xyz, vec3(1.0, 0.0, 0.0));\n";
1098+
code += " TRANSFORM[1].xyz = normalize_or_else(TRANSFORM[1].xyz, vec3(0.0, 1.0, 0.0));\n";
1099+
code += " TRANSFORM[2].xyz = normalize_or_else(TRANSFORM[2].xyz, vec3(0.0, 0.0, 1.0));\n";
10921100
}
10931101
// Turn particle by rotation in Y.
10941102
if (particle_flags[PARTICLE_FLAG_ROTATE_Y]) {

0 commit comments

Comments
 (0)