Merge pull request #69900 from Chaosus/vs_particles_optimize
Optimize a code generation of visual shader particles
This commit is contained in:
commit
e81c81732a
@ -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";
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user