Merge pull request #69900 from Chaosus/vs_particles_optimize

Optimize a code generation of visual shader particles
This commit is contained in:
Rémi Verschelde 2022-12-11 11:52:13 +01:00
commit e81c81732a
No known key found for this signature in database
GPG key ID: C3336907360768E1
2 changed files with 77 additions and 72 deletions

View file

@ -2066,10 +2066,9 @@ Error VisualShader::_write_node(Type type, StringBuilder *p_global_code, StringB
}
if (!node_code.is_empty()) {
r_code += "\n";
r_code += "\n\n";
}
r_code += "\n"; //
r_processed.insert(p_node);
return OK;
@ -2366,71 +2365,62 @@ void VisualShader::_update_shader() const {
String global_compute_code;
if (shader_mode == Shader::MODE_PARTICLES) {
bool has_start = !code_map[TYPE_START].is_empty();
bool has_start_custom = !code_map[TYPE_START_CUSTOM].is_empty();
bool has_process = !code_map[TYPE_PROCESS].is_empty();
bool has_process_custom = !code_map[TYPE_PROCESS_CUSTOM].is_empty();
bool has_collide = !code_map[TYPE_COLLIDE].is_empty();
shader_code += "void start() {\n";
if (has_start || has_start_custom) {
shader_code += " uint __seed = __hash(NUMBER + uint(1) + RANDOM_SEED);\n";
shader_code += " vec3 __diff = TRANSFORM[3].xyz - EMISSION_TRANSFORM[3].xyz;\n";
shader_code += " float __radians;\n";
shader_code += " vec3 __vec3_buff1;\n";
shader_code += " vec3 __vec3_buff2;\n";
shader_code += " float __scalar_buff1;\n";
shader_code += " float __scalar_buff2;\n";
shader_code += " int __scalar_ibuff;\n";
shader_code += " vec4 __vec4_buff;\n";
shader_code += " vec3 __ndiff = normalize(__diff);\n\n";
}
if (has_start) {
shader_code += " {\n";
shader_code += code_map[TYPE_START].replace("\n ", "\n ");
shader_code += " }\n";
if (has_start_custom) {
shader_code += " \n";
}
}
shader_code += " uint __seed = __hash(NUMBER + uint(1) + RANDOM_SEED);\n";
shader_code += "\n";
shader_code += " {\n";
shader_code += code_map[TYPE_START].replace("\n ", "\n ");
shader_code += " }\n";
if (has_start_custom) {
shader_code += " \n";
shader_code += " {\n";
shader_code += code_map[TYPE_START_CUSTOM].replace("\n ", "\n ");
shader_code += " }\n";
}
shader_code += "}\n\n";
shader_code += "void process() {\n";
if (has_process || has_process_custom || has_collide) {
shader_code += "void process() {\n";
shader_code += " uint __seed = __hash(NUMBER + uint(1) + RANDOM_SEED);\n";
shader_code += " vec3 __vec3_buff1;\n";
shader_code += " vec3 __diff = TRANSFORM[3].xyz - EMISSION_TRANSFORM[3].xyz;\n";
shader_code += " vec3 __ndiff = normalize(__diff);\n\n";
}
shader_code += " {\n";
String tab = " ";
if (has_collide) {
shader_code += " if (COLLIDED) {\n\n";
shader_code += code_map[TYPE_COLLIDE].replace("\n ", "\n ");
if (has_process) {
shader_code += " } else {\n\n";
tab += " ";
shader_code += "\n";
if (has_process || has_collide) {
shader_code += " {\n";
}
String tab = " ";
if (has_collide) {
shader_code += " if (COLLIDED) {\n\n";
shader_code += code_map[TYPE_COLLIDE].replace("\n ", "\n ");
if (has_process) {
shader_code += " } else {\n\n";
tab += " ";
}
}
if (has_process) {
shader_code += code_map[TYPE_PROCESS].replace("\n ", "\n " + tab);
}
if (has_collide) {
shader_code += " }\n";
}
if (has_process || has_collide) {
shader_code += " }\n";
}
}
if (has_process) {
shader_code += code_map[TYPE_PROCESS].replace("\n ", "\n " + tab);
}
if (has_collide) {
shader_code += " }\n";
}
shader_code += " }\n";
if (has_process_custom) {
shader_code += " {\n\n";
shader_code += code_map[TYPE_PROCESS_CUSTOM].replace("\n ", "\n ");
shader_code += " }\n";
}
if (has_process_custom) {
if (has_process || has_collide) {
shader_code += " \n";
}
shader_code += " {\n";
shader_code += code_map[TYPE_PROCESS_CUSTOM].replace("\n ", "\n ");
shader_code += " }\n";
}
shader_code += "}\n\n";
shader_code += "}\n\n";
}
global_compute_code += "float __rand_from_seed(inout uint seed) {\n";
global_compute_code += " int k;\n";

View file

@ -374,13 +374,13 @@ String VisualShaderNodeParticleMeshEmitter::_generate_code(VisualShader::Type p_
if (is_output_port_connected(p_index)) {
switch (p_port_type) {
case PORT_TYPE_VECTOR_2D: {
code += vformat(" %s = texelFetch(%s, ivec2(__scalar_ibuff, 0), 0).xy;\n", p_output_vars[p_index], make_unique_id(p_type, p_id, p_texture_name));
code += vformat(" %s = texelFetch(%s, ivec2(__scalar_ibuff, 0), 0).xy;\n", p_output_vars[p_index], make_unique_id(p_type, p_id, p_texture_name));
} break;
case PORT_TYPE_VECTOR_3D: {
if (mode_2d) {
code += vformat(" %s = texelFetch(%s, ivec2(__scalar_ibuff, 0), 0).xy;\n", p_output_vars[p_index], make_unique_id(p_type, p_id, p_texture_name));
code += vformat(" %s = texelFetch(%s, ivec2(__scalar_ibuff, 0), 0).xy;\n", p_output_vars[p_index], make_unique_id(p_type, p_id, p_texture_name));
} else {
code += vformat(" %s = texelFetch(%s, ivec2(__scalar_ibuff, 0), 0).xyz;\n", p_output_vars[p_index], make_unique_id(p_type, p_id, p_texture_name));
code += vformat(" %s = texelFetch(%s, ivec2(__scalar_ibuff, 0), 0).xyz;\n", p_output_vars[p_index], make_unique_id(p_type, p_id, p_texture_name));
}
} break;
default:
@ -392,25 +392,27 @@ String VisualShaderNodeParticleMeshEmitter::_generate_code(VisualShader::Type p_
String VisualShaderNodeParticleMeshEmitter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
String code;
code += " __scalar_ibuff = int(__rand_from_seed(__seed) * 65535.0) % " + itos(position_texture->get_width()) + ";\n";
code += " {\n";
code += " int __scalar_ibuff = int(__rand_from_seed(__seed) * 65535.0) % " + itos(position_texture->get_width()) + ";\n";
code += _generate_code(p_type, p_id, p_output_vars, 0, "mesh_vx", VisualShaderNode::PORT_TYPE_VECTOR_3D);
code += _generate_code(p_type, p_id, p_output_vars, 1, "mesh_nm", VisualShaderNode::PORT_TYPE_VECTOR_3D);
if (is_output_port_connected(2) || is_output_port_connected(3)) {
code += vformat(" __vec4_buff = texelFetch(%s, ivec2(__scalar_ibuff, 0), 0);\n", make_unique_id(p_type, p_id, "mesh_col"));
code += vformat(" vec4 __vec4_buff = texelFetch(%s, ivec2(__scalar_ibuff, 0), 0);\n", make_unique_id(p_type, p_id, "mesh_col"));
if (is_output_port_connected(2)) {
code += " " + p_output_vars[2] + " = __vec4_buff.rgb;\n";
code += " " + p_output_vars[2] + " = __vec4_buff.rgb;\n";
}
if (is_output_port_connected(3)) {
code += " " + p_output_vars[3] + " = __vec4_buff.a;\n";
code += " " + p_output_vars[3] + " = __vec4_buff.a;\n";
}
}
code += _generate_code(p_type, p_id, p_output_vars, 4, "mesh_uv", VisualShaderNode::PORT_TYPE_VECTOR_2D);
code += _generate_code(p_type, p_id, p_output_vars, 5, "mesh_uv2", VisualShaderNode::PORT_TYPE_VECTOR_2D);
code += " }\n";
return code;
}
@ -737,6 +739,8 @@ VisualShaderNodeParticleMeshEmitter::VisualShaderNodeParticleMeshEmitter() {
color_texture.instantiate();
uv_texture.instantiate();
uv2_texture.instantiate();
simple_decl = false;
}
// VisualShaderNodeParticleMultiplyByAxisAngle
@ -879,22 +883,26 @@ bool VisualShaderNodeParticleConeVelocity::has_output_port_preview(int p_port) c
String VisualShaderNodeParticleConeVelocity::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
String code;
code += " __radians = radians(" + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ");\n";
code += " __scalar_buff1 = __rand_from_seed_m1_p1(__seed) * __radians;\n";
code += " __scalar_buff2 = __rand_from_seed_m1_p1(__seed) * __radians;\n";
code += " __vec3_buff1 = " + (p_input_vars[0].is_empty() ? "vec3" + (String)get_input_port_default_value(0) : p_input_vars[0]) + ";\n";
code += " __scalar_buff1 += __vec3_buff1.z != 0.0 ? atan(__vec3_buff1.x, __vec3_buff1.z) : sign(__vec3_buff1.x) * (PI / 2.0);\n";
code += " __scalar_buff2 += __vec3_buff1.z != 0.0 ? atan(__vec3_buff1.y, abs(__vec3_buff1.z)) : (__vec3_buff1.x != 0.0 ? atan(__vec3_buff1.y, abs(__vec3_buff1.x)) : sign(__vec3_buff1.y) * (PI / 2.0));\n";
code += " __vec3_buff1 = vec3(sin(__scalar_buff1), 0.0, cos(__scalar_buff1));\n";
code += " __vec3_buff2 = vec3(0.0, sin(__scalar_buff2), cos(__scalar_buff2));\n";
code += " __vec3_buff2.z = __vec3_buff2.z / max(0.0001, sqrt(abs(__vec3_buff2.z)));\n";
code += " " + p_output_vars[0] + " = normalize(vec3(__vec3_buff1.x * __vec3_buff2.z, __vec3_buff2.y, __vec3_buff1.z * __vec3_buff2.z));\n";
code += " {\n";
code += " float __radians = radians(" + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ");\n";
code += " float __scalar_buff1 = __rand_from_seed_m1_p1(__seed) * __radians;\n";
code += " float __scalar_buff2 = __rand_from_seed_m1_p1(__seed) * __radians;\n";
code += " vec3 __vec3_buff1 = " + (p_input_vars[0].is_empty() ? "vec3" + (String)get_input_port_default_value(0) : p_input_vars[0]) + ";\n";
code += " __scalar_buff1 += __vec3_buff1.z != 0.0 ? atan(__vec3_buff1.x, __vec3_buff1.z) : sign(__vec3_buff1.x) * (PI / 2.0);\n";
code += " __scalar_buff2 += __vec3_buff1.z != 0.0 ? atan(__vec3_buff1.y, abs(__vec3_buff1.z)) : (__vec3_buff1.x != 0.0 ? atan(__vec3_buff1.y, abs(__vec3_buff1.x)) : sign(__vec3_buff1.y) * (PI / 2.0));\n";
code += " __vec3_buff1 = vec3(sin(__scalar_buff1), 0.0, cos(__scalar_buff1));\n";
code += " vec3 __vec3_buff2 = vec3(0.0, sin(__scalar_buff2), cos(__scalar_buff2));\n";
code += " __vec3_buff2.z = __vec3_buff2.z / max(0.0001, sqrt(abs(__vec3_buff2.z)));\n";
code += " " + p_output_vars[0] + " = normalize(vec3(__vec3_buff1.x * __vec3_buff2.z, __vec3_buff2.y, __vec3_buff1.z * __vec3_buff2.z));\n";
code += " }\n";
return code;
}
VisualShaderNodeParticleConeVelocity::VisualShaderNodeParticleConeVelocity() {
set_input_port_default_value(0, Vector3(1, 0, 0));
set_input_port_default_value(1, 45.0);
simple_decl = false;
}
// VisualShaderNodeParticleRandomness
@ -1086,21 +1094,26 @@ String VisualShaderNodeParticleAccelerator::get_input_port_name(int p_port) cons
String VisualShaderNodeParticleAccelerator::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
String code;
code += " {\n";
switch (mode) {
case MODE_LINEAR:
code += " " + p_output_vars[0] + " = length(VELOCITY) > 0.0 ? " + "normalize(VELOCITY) * " + (p_input_vars[0].is_empty() ? "vec3" + (String)get_input_port_default_value(0) : p_input_vars[0]) + " * mix(1.0, __rand_from_seed(__seed), " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ") : vec3(0.0);\n";
code += " " + p_output_vars[0] + " = length(VELOCITY) > 0.0 ? " + "normalize(VELOCITY) * " + (p_input_vars[0].is_empty() ? "vec3" + (String)get_input_port_default_value(0) : p_input_vars[0]) + " * mix(1.0, __rand_from_seed(__seed), " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ") : vec3(0.0);\n";
break;
case MODE_RADIAL:
code += " " + p_output_vars[0] + " = length(__diff) > 0.0 ? __ndiff * " + (p_input_vars[0].is_empty() ? "vec3" + (String)get_input_port_default_value(0) : p_input_vars[0]) + " * mix(1.0, __rand_from_seed(__seed), " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ") : vec3(0.0);\n";
code += " vec3 __diff = TRANSFORM[3].xyz - EMISSION_TRANSFORM[3].xyz;\n";
code += " vec3 __ndiff = normalize(__diff);\n\n";
code += " " + p_output_vars[0] + " = length(__diff) > 0.0 ? __ndiff * " + (p_input_vars[0].is_empty() ? "vec3" + (String)get_input_port_default_value(0) : p_input_vars[0]) + " * mix(1.0, __rand_from_seed(__seed), " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ") : vec3(0.0);\n";
break;
case MODE_TANGENTIAL:
code += " __vec3_buff1 = cross(__ndiff, normalize(" + (p_input_vars[2].is_empty() ? "vec3" + (String)get_input_port_default_value(2) : p_input_vars[2]) + "));\n";
code += " " + p_output_vars[0] + " = length(__vec3_buff1) > 0.0 ? normalize(__vec3_buff1) * (" + (p_input_vars[0].is_empty() ? "vec3" + (String)get_input_port_default_value(0) : p_input_vars[0]) + " * mix(1.0, __rand_from_seed(__seed), " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ")) : vec3(0.0);\n";
code += " vec3 __diff = TRANSFORM[3].xyz - EMISSION_TRANSFORM[3].xyz;\n";
code += " vec3 __ndiff = normalize(__diff);\n\n";
code += " vec3 __vec3_buff1 = cross(__ndiff, normalize(" + (p_input_vars[2].is_empty() ? "vec3" + (String)get_input_port_default_value(2) : p_input_vars[2]) + "));\n";
code += " " + p_output_vars[0] + " = length(__vec3_buff1) > 0.0 ? normalize(__vec3_buff1) * (" + (p_input_vars[0].is_empty() ? "vec3" + (String)get_input_port_default_value(0) : p_input_vars[0]) + " * mix(1.0, __rand_from_seed(__seed), " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ")) : vec3(0.0);\n";
break;
default:
break;
}
code += " }\n";
return code;
}
@ -1125,6 +1138,8 @@ VisualShaderNodeParticleAccelerator::VisualShaderNodeParticleAccelerator() {
set_input_port_default_value(0, Vector3(1, 1, 1));
set_input_port_default_value(1, 0.0);
set_input_port_default_value(2, Vector3(0, -9.8, 0));
simple_decl = false;
}
// VisualShaderNodeParticleOutput