Преглед на файлове

Optimize a code generation of visual shader particles

Yuri Rubinsky преди 2 години
родител
ревизия
bd08f89fd2
променени са 2 файла, в които са добавени 76 реда и са изтрити 71 реда
  1. 39 49
      scene/resources/visual_shader.cpp
  2. 37 22
      scene/resources/visual_shader_particle_nodes.cpp

+ 39 - 49
scene/resources/visual_shader.cpp

@@ -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			");
+			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 += "		} else {\n\n";
-				tab += "	";
+				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";

+ 37 - 22
scene/resources/visual_shader_particle_nodes.cpp

@@ -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