Preserve origin vector on TRANSFORM matrix at scale/rotation changing for visual shader particles

This commit is contained in:
Chaosus 2024-10-20 12:13:26 +03:00
parent 44fa552343
commit 46ac0ddf79
2 changed files with 27 additions and 13 deletions

View file

@ -2914,12 +2914,12 @@ void VisualShader::_update_shader() const {
global_compute_code += " return mat3(vec3(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s), vec3(oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s), vec3(oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c));\n";
global_compute_code += "}\n\n";
global_compute_code += "mat4 __build_rotation_mat4(vec3 axis, float angle) {\n";
global_compute_code += "mat4 __build_rotation_mat4(vec3 axis, float angle, vec4 origin) {\n";
global_compute_code += " axis = normalize(axis);\n";
global_compute_code += " float s = sin(angle);\n";
global_compute_code += " float c = cos(angle);\n";
global_compute_code += " float oc = 1.0 - c;\n";
global_compute_code += " return mat4(vec4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0), vec4(oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0), vec4(oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0), vec4(0, 0, 0, 1));\n";
global_compute_code += " return mat4(vec4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0), vec4(oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0), vec4(oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0), origin);\n";
global_compute_code += "}\n\n";
global_compute_code += "vec2 __get_random_unit_vec2(inout uint seed) {\n";

View file

@ -1403,24 +1403,38 @@ String VisualShaderNodeParticleOutput::generate_code(Shader::Mode p_mode, Visual
rotation_axis = 5;
rotation = 6;
}
String op;
if (shader_type == VisualShader::TYPE_START) {
op = "*=";
} else {
op = "=";
}
if (!p_input_vars[rotation].is_empty()) { // rotation_axis & angle_in_radians
String axis;
String axis;
if (!p_input_vars[rotation].is_empty()) { // rotation_axis
if (p_input_vars[rotation_axis].is_empty()) {
axis = "vec3(0, 1, 0)";
} else {
axis = p_input_vars[rotation_axis];
}
code += tab + "TRANSFORM " + op + " __build_rotation_mat4(" + axis + ", " + p_input_vars[rotation] + ");\n";
}
if (!p_input_vars[scale].is_empty()) { // scale
code += tab + "TRANSFORM " + op + " mat4(vec4(" + p_input_vars[scale] + ", 0, 0, 0), vec4(0, " + p_input_vars[scale] + ", 0, 0), vec4(0, 0, " + p_input_vars[scale] + ", 0), vec4(0, 0, 0, 1));\n";
if (shader_type == VisualShader::TYPE_PROCESS) {
if (!p_input_vars[rotation].is_empty()) { // angle_in_radians
if (!p_input_vars[scale].is_empty()) { // scale
code += tab + "TRANSFORM = ";
code += "mat4(vec4(1, 0, 0, 0), vec4(0, 1, 0, 0), vec4(0, 0, 1, 0), TRANSFORM[3])";
code += " * ";
code += "mat4(vec4(" + p_input_vars[scale] + ", 0, 0, 0), vec4(0, " + p_input_vars[scale] + ", 0, 0), vec4(0, 0, " + p_input_vars[scale] + ", 0), vec4(0, 0, 0, 1))";
code += " * ";
code += "__build_rotation_mat4(" + axis + ", " + p_input_vars[rotation] + ", vec4(0, 0, 0, 1));\n";
} else {
code += tab + "TRANSFORM = __build_rotation_mat4(" + axis + ", " + p_input_vars[rotation] + ", TRANSFORM[3]);\n";
}
} else if (!p_input_vars[scale].is_empty()) { // scale
code += tab + "TRANSFORM = mat4(vec4(" + p_input_vars[scale] + ", 0, 0, 0), vec4(0, " + p_input_vars[scale] + ", 0, 0), vec4(0, 0, " + p_input_vars[scale] + ", 0), TRANSFORM[3]);\n";
}
} else {
if (!p_input_vars[scale].is_empty()) { // scale
code += tab + "TRANSFORM *= mat4(vec4(" + p_input_vars[scale] + ", 0, 0, 0), vec4(0, " + p_input_vars[scale] + ", 0, 0), vec4(0, 0, " + p_input_vars[scale] + ", 0), vec4(0.0, 0.0, 0.0, 1.0));\n";
}
if (!p_input_vars[rotation].is_empty()) { // angle_in_radians
code += tab + "TRANSFORM *= __build_rotation_mat4(" + axis + ", " + p_input_vars[rotation] + ", vec4(0, 0, 0, 1));\n";
}
}
}
if (!p_input_vars[0].is_empty()) { // Active (end).