Jelajahi Sumber

Add some more fixes to visual shader

Yuri Roubinsky 3 tahun lalu
induk
melakukan
a6e280c5de

+ 8 - 2
doc/classes/VisualShaderNodeParticleRandomness.xml

@@ -8,14 +8,20 @@
 	</tutorials>
 	<members>
 		<member name="op_type" type="int" setter="set_op_type" getter="get_op_type" enum="VisualShaderNodeParticleRandomness.OpType" default="0">
+			A type of operands and returned value.
 		</member>
 	</members>
 	<constants>
 		<constant name="OP_TYPE_SCALAR" value="0" enum="OpType">
+			A floating-point scalar.
 		</constant>
-		<constant name="OP_TYPE_VECTOR" value="1" enum="OpType">
+		<constant name="OP_TYPE_VECTOR_2D" value="1" enum="OpType">
+			A 2D vector type.
 		</constant>
-		<constant name="OP_TYPE_MAX" value="2" enum="OpType">
+		<constant name="OP_TYPE_VECTOR_3D" value="2" enum="OpType">
+			A 3D vector type.
+		</constant>
+		<constant name="OP_TYPE_MAX" value="3" enum="OpType">
 			Represents the size of the [enum OpType] enum.
 		</constant>
 	</constants>

+ 4 - 4
editor/plugins/visual_shader_editor_plugin.cpp

@@ -4783,11 +4783,11 @@ VisualShaderEditor::VisualShaderEditor() {
 
 	// SDF
 	{
-		add_options.push_back(AddOption("ScreenUVToSDF", "SDF", "", "VisualShaderNodeScreenUVToSDF", TTR("Converts screen UV to a SDF."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+		add_options.push_back(AddOption("ScreenUVToSDF", "SDF", "", "VisualShaderNodeScreenUVToSDF", TTR("Converts screen UV to a SDF."), {}, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
 		add_options.push_back(AddOption("SDFRaymarch", "SDF", "", "VisualShaderNodeSDFRaymarch", TTR("Casts a ray against the screen SDF and returns the distance travelled."), {}, -1, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
-		add_options.push_back(AddOption("SDFToScreenUV", "SDF", "", "VisualShaderNodeSDFToScreenUV", TTR("Converts a SDF to screen UV."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+		add_options.push_back(AddOption("SDFToScreenUV", "SDF", "", "VisualShaderNodeSDFToScreenUV", TTR("Converts a SDF to screen UV."), {}, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
 		add_options.push_back(AddOption("TextureSDF", "SDF", "", "VisualShaderNodeTextureSDF", TTR("Performs a SDF texture lookup."), {}, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
-		add_options.push_back(AddOption("TextureSDFNormal", "SDF", "", "VisualShaderNodeTextureSDFNormal", TTR("Performs a SDF normal texture lookup."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+		add_options.push_back(AddOption("TextureSDFNormal", "SDF", "", "VisualShaderNodeTextureSDFNormal", TTR("Performs a SDF normal texture lookup."), {}, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
 	}
 
 	// TEXTURES
@@ -4971,8 +4971,8 @@ VisualShaderEditor::VisualShaderEditor() {
 	add_options.push_back(AddOption("Subtract", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Subtracts 3D vector from 3D vector."), { VisualShaderNodeVectorOp::OP_SUB, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
 
 	add_options.push_back(AddOption("Vector2Constant", "Vector", "Variables", "VisualShaderNodeVec2Constant", TTR("2D vector constant."), {}, VisualShaderNode::PORT_TYPE_VECTOR_2D));
-	add_options.push_back(AddOption("Vector3Constant", "Vector", "Variables", "VisualShaderNodeVec3Constant", TTR("3D vector constant."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D));
 	add_options.push_back(AddOption("Vector2Uniform", "Vector", "Variables", "VisualShaderNodeVec2Uniform", TTR("2D vector uniform."), {}, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+	add_options.push_back(AddOption("Vector3Constant", "Vector", "Variables", "VisualShaderNodeVec3Constant", TTR("3D vector constant."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D));
 	add_options.push_back(AddOption("Vector3Uniform", "Vector", "Variables", "VisualShaderNodeVec3Uniform", TTR("3D vector uniform."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D));
 
 	// SPECIAL

+ 0 - 3
modules/gdscript/editor_templates/VisualShaderNodeCustom/basic.gd

@@ -34,8 +34,5 @@ func _get_output_port_name(port: int) -> String:
 func _get_output_port_type(port: int) -> int:
 	return PORT_TYPE_SCALAR
 
-func _get_global_code(mode: Shader.Mode) -> String:
-	return ""
-
 func _get_code(input_vars: Array[String], output_vars: Array[String], mode: Shader.Mode, type: VisualShader.Type) -> String:
 	return output_vars[0] + " = 0.0;"

+ 0 - 5
modules/mono/editor_templates/VisualShaderNodeCustom/basic.cs

@@ -55,11 +55,6 @@ public partial class VisualShaderNode_CLASS_ : _BASE_
         return 0;
     }
 
-    public override string _GetGlobalCode(Shader.Mode mode)
-    {
-        return "";
-    }
-
     public override string _GetCode(Godot.Collections.Array inputVars, Godot.Collections.Array outputVars, Shader.Mode mode, VisualShader.Type type)
     {
         return "";

+ 9 - 5
scene/resources/visual_shader.cpp

@@ -131,7 +131,7 @@ void VisualShaderNode::set_input_port_default_value(int p_port, const Variant &p
 					} break;
 					case Variant::VECTOR2: {
 						Vector2 pv = p_prev_value;
-						value = Vector3(pv.x, pv.y, 0.0);
+						value = Vector3(pv.x, pv.y, pv.y);
 					} break;
 					case Variant::VECTOR3: {
 						value = p_prev_value;
@@ -289,7 +289,7 @@ String VisualShaderNode::generate_global(Shader::Mode p_mode, VisualShader::Type
 	return String();
 }
 
-String VisualShaderNode::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+String VisualShaderNode::generate_global_per_node(Shader::Mode p_mode, int p_id) const {
 	return String();
 }
 
@@ -472,7 +472,7 @@ String VisualShaderNodeCustom::generate_code(Shader::Mode p_mode, VisualShader::
 	return code;
 }
 
-String VisualShaderNodeCustom::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+String VisualShaderNodeCustom::generate_global_per_node(Shader::Mode p_mode, int p_id) const {
 	String ret;
 	if (GDVIRTUAL_CALL(_get_global_code, p_mode, ret)) {
 		String code = "// " + get_caption() + "\n";
@@ -1485,7 +1485,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
 			class_name = vsnode->get_script_instance()->get_script()->get_path();
 		}
 		if (!r_classes.has(class_name)) {
-			global_code_per_node += vsnode->generate_global_per_node(get_mode(), type, node);
+			global_code_per_node += vsnode->generate_global_per_node(get_mode(), node);
 			for (int i = 0; i < TYPE_MAX; i++) {
 				global_code_per_func[Type(i)] += vsnode->generate_global_per_func(get_mode(), Type(i), node);
 			}
@@ -2146,7 +2146,11 @@ void VisualShader::_update_shader() const {
 		global_compute_code += "	return __rand_from_seed(seed) * (to - from) + from;\n";
 		global_compute_code += "}\n\n";
 
-		global_compute_code += "vec3 __randv_range(inout uint seed, vec3 from, vec3 to) {\n";
+		global_compute_code += "vec2 __randv2_range(inout uint seed, vec2 from, vec2 to) {\n";
+		global_compute_code += "	return vec2(__randf_range(seed, from.x, to.x), __randf_range(seed, from.y, to.y));\n";
+		global_compute_code += "}\n\n";
+
+		global_compute_code += "vec3 __randv3_range(inout uint seed, vec3 from, vec3 to) {\n";
 		global_compute_code += "	return vec3(__randf_range(seed, from.x, to.x), __randf_range(seed, from.y, to.y), __randf_range(seed, from.z, to.z));\n";
 		global_compute_code += "}\n\n";
 

+ 2 - 2
scene/resources/visual_shader.h

@@ -275,7 +275,7 @@ public:
 
 	virtual Vector<VisualShader::DefaultTextureParam> get_default_texture_parameters(VisualShader::Type p_type, int p_id) const;
 	virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
-	virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
+	virtual String generate_global_per_node(Shader::Mode p_mode, int p_id) const;
 	virtual String generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
 	// If no output is connected, the output var passed will be empty. If no input is connected and input is NIL, the input var passed will be empty.
 	virtual String 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 = false) const = 0;
@@ -335,7 +335,7 @@ protected:
 	void _set_input_port_default_value(int p_port, const Variant &p_value);
 
 	virtual String 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 = false) const override;
-	virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
+	virtual String generate_global_per_node(Shader::Mode p_mode, int p_id) const override;
 
 	static void _bind_methods();
 

+ 1 - 1
scene/resources/visual_shader_nodes.cpp

@@ -5694,7 +5694,7 @@ String VisualShaderNodeTextureUniformTriplanar::get_input_port_name(int p_port)
 	return "";
 }
 
-String VisualShaderNodeTextureUniformTriplanar::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+String VisualShaderNodeTextureUniformTriplanar::generate_global_per_node(Shader::Mode p_mode, int p_id) const {
 	String code;
 
 	code += "// TRIPLANAR FUNCTION GLOBAL CODE\n";

+ 1 - 1
scene/resources/visual_shader_nodes.h

@@ -2136,7 +2136,7 @@ public:
 
 	virtual bool is_input_port_default(int p_port, Shader::Mode p_mode) const override;
 
-	virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
+	virtual String generate_global_per_node(Shader::Mode p_mode, int p_id) const override;
 	virtual String generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
 	virtual String 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 = false) const override;
 

+ 111 - 56
scene/resources/visual_shader_particle_nodes.cpp

@@ -39,6 +39,9 @@ int VisualShaderNodeParticleEmitter::get_output_port_count() const {
 }
 
 VisualShaderNodeParticleEmitter::PortType VisualShaderNodeParticleEmitter::get_output_port_type(int p_port) const {
+	if (mode_2d) {
+		return PORT_TYPE_VECTOR_2D;
+	}
 	return PORT_TYPE_VECTOR_3D;
 }
 
@@ -54,6 +57,9 @@ bool VisualShaderNodeParticleEmitter::has_output_port_preview(int p_port) const
 }
 
 void VisualShaderNodeParticleEmitter::set_mode_2d(bool p_enabled) {
+	if (mode_2d == p_enabled) {
+		return;
+	}
 	mode_2d = p_enabled;
 	emit_changed();
 }
@@ -111,7 +117,7 @@ String VisualShaderNodeParticleSphereEmitter::get_input_port_name(int p_port) co
 	return String();
 }
 
-String VisualShaderNodeParticleSphereEmitter::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+String VisualShaderNodeParticleSphereEmitter::generate_global_per_node(Shader::Mode p_mode, int p_id) const {
 	String code;
 
 	code += "vec2 __get_random_point_in_circle(inout uint seed, float radius, float inner_radius) {\n";
@@ -129,7 +135,7 @@ String VisualShaderNodeParticleSphereEmitter::generate_code(Shader::Mode p_mode,
 	String code;
 
 	if (mode_2d) {
-		code += "	" + p_output_vars[0] + " = vec3(__get_random_point_in_circle(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ", " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + "), 0.0);\n";
+		code += "	" + p_output_vars[0] + " = __get_random_point_in_circle(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ", " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ");\n";
 	} else {
 		code += "	" + p_output_vars[0] + " = __get_random_point_in_sphere(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ", " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ");\n";
 	}
@@ -154,11 +160,27 @@ int VisualShaderNodeParticleBoxEmitter::get_input_port_count() const {
 
 VisualShaderNodeParticleBoxEmitter::PortType VisualShaderNodeParticleBoxEmitter::get_input_port_type(int p_port) const {
 	if (p_port == 0) {
+		if (mode_2d) {
+			return PORT_TYPE_VECTOR_2D;
+		}
 		return PORT_TYPE_VECTOR_3D;
 	}
 	return PORT_TYPE_SCALAR;
 }
 
+void VisualShaderNodeParticleBoxEmitter::set_mode_2d(bool p_enabled) {
+	if (mode_2d == p_enabled) {
+		return;
+	}
+	if (p_enabled) {
+		set_input_port_default_value(0, Vector2(), get_input_port_default_value(0));
+	} else {
+		set_input_port_default_value(0, Vector3(), get_input_port_default_value(0));
+	}
+	mode_2d = p_enabled;
+	emit_changed();
+}
+
 String VisualShaderNodeParticleBoxEmitter::get_input_port_name(int p_port) const {
 	if (p_port == 0) {
 		return "extents";
@@ -166,7 +188,7 @@ String VisualShaderNodeParticleBoxEmitter::get_input_port_name(int p_port) const
 	return String();
 }
 
-String VisualShaderNodeParticleBoxEmitter::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+String VisualShaderNodeParticleBoxEmitter::generate_global_per_node(Shader::Mode p_mode, int p_id) const {
 	String code;
 
 	code += "vec2 __get_random_point_in_box2d(inout uint seed, vec2 extents) {\n";
@@ -185,7 +207,7 @@ String VisualShaderNodeParticleBoxEmitter::generate_global_per_node(Shader::Mode
 String VisualShaderNodeParticleBoxEmitter::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;
 	if (mode_2d) {
-		code += "	" + p_output_vars[0] + " = vec3(__get_random_point_in_box2d(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ".xy), 0.0);\n";
+		code += "	" + p_output_vars[0] + " = __get_random_point_in_box2d(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ");\n";
 	} else {
 		code += "	" + p_output_vars[0] + " = __get_random_point_in_box3d(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ");\n";
 	}
@@ -221,7 +243,7 @@ String VisualShaderNodeParticleRingEmitter::get_input_port_name(int p_port) cons
 	return String();
 }
 
-String VisualShaderNodeParticleRingEmitter::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+String VisualShaderNodeParticleRingEmitter::generate_global_per_node(Shader::Mode p_mode, int p_id) const {
 	String code;
 
 	code += "vec2 __get_random_point_on_ring2d(inout uint seed, float radius, float inner_radius) {\n";
@@ -243,7 +265,7 @@ String VisualShaderNodeParticleRingEmitter::generate_code(Shader::Mode p_mode, V
 	String code;
 
 	if (mode_2d) {
-		code = "	" + p_output_vars[0] + " = vec3(__get_random_point_on_ring2d(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ", " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + "), 0.0);\n";
+		code = "	" + p_output_vars[0] + " = __get_random_point_on_ring2d(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ", " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ");\n";
 	} else {
 		code = "	" + p_output_vars[0] + " = __get_random_point_on_ring3d(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ", " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ", " + (p_input_vars[2].is_empty() ? (String)get_input_port_default_value(2) : p_input_vars[2]) + ");\n";
 	}
@@ -269,18 +291,24 @@ int VisualShaderNodeParticleMeshEmitter::get_output_port_count() const {
 
 VisualShaderNodeParticleBoxEmitter::PortType VisualShaderNodeParticleMeshEmitter::get_output_port_type(int p_port) const {
 	switch (p_port) {
-		case 0:
-			return PORT_TYPE_VECTOR_3D; // position
-		case 1:
-			return PORT_TYPE_VECTOR_3D; // normal
-		case 2:
-			return PORT_TYPE_VECTOR_3D; // color
-		case 3:
-			return PORT_TYPE_SCALAR; // alpha
-		case 4:
-			return PORT_TYPE_VECTOR_3D; // uv
-		case 5:
-			return PORT_TYPE_VECTOR_3D; // uv2
+		case 0: // position
+			if (mode_2d) {
+				return PORT_TYPE_VECTOR_2D;
+			}
+			return PORT_TYPE_VECTOR_3D;
+		case 1: // normal
+			if (mode_2d) {
+				return PORT_TYPE_VECTOR_2D;
+			}
+			return PORT_TYPE_VECTOR_3D;
+		case 2: // color
+			return PORT_TYPE_VECTOR_3D;
+		case 3: // alpha
+			return PORT_TYPE_SCALAR;
+		case 4: // uv
+			return PORT_TYPE_VECTOR_2D;
+		case 5: // uv2
+			return PORT_TYPE_VECTOR_2D;
 	}
 	return PORT_TYPE_SCALAR;
 }
@@ -341,18 +369,22 @@ String VisualShaderNodeParticleMeshEmitter::generate_global(Shader::Mode p_mode,
 	return code;
 }
 
-String VisualShaderNodeParticleMeshEmitter::_generate_code(VisualShader::Type p_type, int p_id, const String *p_output_vars, int p_index, const String &p_texture_name, bool p_ignore_mode2d) const {
+String VisualShaderNodeParticleMeshEmitter::_generate_code(VisualShader::Type p_type, int p_id, const String *p_output_vars, int p_index, const String &p_texture_name, PortType p_port_type) const {
 	String code;
 	if (is_output_port_connected(p_index)) {
-		if (mode_2d && !p_ignore_mode2d) {
-			code += "	" + p_output_vars[p_index] + " = vec3(";
-			code += "texelFetch(";
-			code += make_unique_id(p_type, p_id, p_texture_name) + ", ";
-			code += "ivec2(__scalar_ibuff, 0), 0).xy, 0.0);\n";
-		} else {
-			code += "	" + p_output_vars[p_index] + " = texelFetch(";
-			code += make_unique_id(p_type, p_id, p_texture_name) + ", ";
-			code += "ivec2(__scalar_ibuff, 0), 0).xyz;\n";
+		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));
+			} 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));
+				} 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));
+				}
+			} break;
+			default:
+				break;
 		}
 	}
 	return code;
@@ -362,27 +394,22 @@ String VisualShaderNodeParticleMeshEmitter::generate_code(Shader::Mode p_mode, V
 	String code;
 	code += "	__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");
-	code += _generate_code(p_type, p_id, p_output_vars, 1, "mesh_nm");
+	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 += "	__vec4_buff = texelFetch(";
-		code += make_unique_id(p_type, p_id, "mesh_col") + ", ";
-		code += "ivec2(__scalar_ibuff, 0), 0);\n";
+		code += vformat("	__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";
-		} else {
-			code += "	" + p_output_vars[2] + " = vec3(0.0);\n";
 		}
 		if (is_output_port_connected(3)) {
 			code += "	" + p_output_vars[3] + " = __vec4_buff.a;\n";
-		} else {
-			code += "	" + p_output_vars[3] + " = 0.0;\n";
 		}
 	}
 
-	code += _generate_code(p_type, p_id, p_output_vars, 4, "mesh_uv", true);
-	code += _generate_code(p_type, p_id, p_output_vars, 5, "mesh_uv2", true);
+	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);
 
 	return code;
 }
@@ -876,10 +903,11 @@ void VisualShaderNodeParticleRandomness::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_op_type", "type"), &VisualShaderNodeParticleRandomness::set_op_type);
 	ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeParticleRandomness::get_op_type);
 
-	ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector"), "set_op_type", "get_op_type");
+	ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector2,Vector3"), "set_op_type", "get_op_type");
 
 	BIND_ENUM_CONSTANT(OP_TYPE_SCALAR);
-	BIND_ENUM_CONSTANT(OP_TYPE_VECTOR);
+	BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D);
+	BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D);
 	BIND_ENUM_CONSTANT(OP_TYPE_MAX);
 }
 
@@ -898,8 +926,13 @@ int VisualShaderNodeParticleRandomness::get_output_port_count() const {
 }
 
 VisualShaderNodeParticleRandomness::PortType VisualShaderNodeParticleRandomness::get_output_port_type(int p_port) const {
-	if (op_type == OP_TYPE_VECTOR) {
-		return PORT_TYPE_VECTOR_3D;
+	switch (op_type) {
+		case OP_TYPE_VECTOR_2D:
+			return PORT_TYPE_VECTOR_2D;
+		case OP_TYPE_VECTOR_3D:
+			return PORT_TYPE_VECTOR_3D;
+		default:
+			break;
 	}
 	return PORT_TYPE_SCALAR;
 }
@@ -913,8 +946,13 @@ int VisualShaderNodeParticleRandomness::get_input_port_count() const {
 }
 
 VisualShaderNodeParticleRandomness::PortType VisualShaderNodeParticleRandomness::get_input_port_type(int p_port) const {
-	if (op_type == OP_TYPE_VECTOR) {
-		return PORT_TYPE_VECTOR_3D;
+	switch (op_type) {
+		case OP_TYPE_VECTOR_2D:
+			return PORT_TYPE_VECTOR_2D;
+		case OP_TYPE_VECTOR_3D:
+			return PORT_TYPE_VECTOR_3D;
+		default:
+			break;
 	}
 	return PORT_TYPE_SCALAR;
 }
@@ -930,10 +968,18 @@ String VisualShaderNodeParticleRandomness::get_input_port_name(int p_port) const
 
 String VisualShaderNodeParticleRandomness::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;
-	if (op_type == OP_TYPE_SCALAR) {
-		code += vformat("	%s = __randf_range(__seed, %s, %s);\n", p_output_vars[0], p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0], p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]);
-	} else if (op_type == OP_TYPE_VECTOR) {
-		code += vformat("	%s = __randv_range(__seed, %s, %s);\n", p_output_vars[0], p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0], p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]);
+	switch (op_type) {
+		case OP_TYPE_SCALAR: {
+			code += vformat("	%s = __randf_range(__seed, %s, %s);\n", p_output_vars[0], p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0], p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]);
+		} break;
+		case OP_TYPE_VECTOR_2D: {
+			code += vformat("	%s = __randv2_range(__seed, %s, %s);\n", p_output_vars[0], p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0], p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]);
+		} break;
+		case OP_TYPE_VECTOR_3D: {
+			code += vformat("	%s = __randv3_range(__seed, %s, %s);\n", p_output_vars[0], p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0], p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]);
+		} break;
+		default:
+			break;
 	}
 	return code;
 }
@@ -943,12 +989,21 @@ void VisualShaderNodeParticleRandomness::set_op_type(OpType p_op_type) {
 	if (op_type == p_op_type) {
 		return;
 	}
-	if (p_op_type == OP_TYPE_SCALAR) {
-		set_input_port_default_value(0, 0.0);
-		set_input_port_default_value(1, 1.0);
-	} else {
-		set_input_port_default_value(0, Vector3(-1.0, -1.0, -1.0));
-		set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0));
+	switch (p_op_type) {
+		case OP_TYPE_SCALAR: {
+			set_input_port_default_value(0, 0.0, get_input_port_default_value(0));
+			set_input_port_default_value(1, 0.0, get_input_port_default_value(1));
+		} break;
+		case OP_TYPE_VECTOR_2D: {
+			set_input_port_default_value(0, Vector2(), get_input_port_default_value(0));
+			set_input_port_default_value(1, Vector2(), get_input_port_default_value(1));
+		} break;
+		case OP_TYPE_VECTOR_3D: {
+			set_input_port_default_value(0, Vector3(), get_input_port_default_value(0));
+			set_input_port_default_value(1, Vector3(), get_input_port_default_value(1));
+		} break;
+		default:
+			break;
 	}
 	op_type = p_op_type;
 	emit_changed();
@@ -963,7 +1018,7 @@ bool VisualShaderNodeParticleRandomness::has_output_port_preview(int p_port) con
 }
 
 VisualShaderNodeParticleRandomness::VisualShaderNodeParticleRandomness() {
-	set_input_port_default_value(0, 0.0);
+	set_input_port_default_value(0, -1.0);
 	set_input_port_default_value(1, 1.0);
 }
 

+ 8 - 6
scene/resources/visual_shader_particle_nodes.h

@@ -48,7 +48,7 @@ public:
 	virtual String get_output_port_name(int p_port) const override;
 	virtual bool has_output_port_preview(int p_port) const override;
 
-	void set_mode_2d(bool p_enabled);
+	virtual void set_mode_2d(bool p_enabled);
 	bool is_mode_2d() const;
 
 	Vector<StringName> get_editable_properties() const override;
@@ -68,7 +68,7 @@ public:
 	virtual PortType get_input_port_type(int p_port) const override;
 	virtual String get_input_port_name(int p_port) const override;
 
-	virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
+	virtual String generate_global_per_node(Shader::Mode p_mode, int p_id) const override;
 	virtual String 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 = false) const override;
 
 	VisualShaderNodeParticleSphereEmitter();
@@ -83,8 +83,9 @@ public:
 	virtual int get_input_port_count() const override;
 	virtual PortType get_input_port_type(int p_port) const override;
 	virtual String get_input_port_name(int p_port) const override;
+	virtual void set_mode_2d(bool p_enabled) override;
 
-	virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
+	virtual String generate_global_per_node(Shader::Mode p_mode, int p_id) const override;
 	virtual String 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 = false) const override;
 
 	VisualShaderNodeParticleBoxEmitter();
@@ -100,7 +101,7 @@ public:
 	virtual PortType get_input_port_type(int p_port) const override;
 	virtual String get_input_port_name(int p_port) const override;
 
-	virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
+	virtual String generate_global_per_node(Shader::Mode p_mode, int p_id) const override;
 	virtual String 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 = false) const override;
 
 	VisualShaderNodeParticleRingEmitter();
@@ -118,7 +119,7 @@ class VisualShaderNodeParticleMeshEmitter : public VisualShaderNodeParticleEmitt
 	Ref<ImageTexture> uv_texture;
 	Ref<ImageTexture> uv2_texture;
 
-	String _generate_code(VisualShader::Type p_type, int p_id, const String *p_output_vars, int p_index, const String &p_texture_name, bool p_ignore_mode2d = false) const;
+	String _generate_code(VisualShader::Type p_type, int p_id, const String *p_output_vars, int p_index, const String &p_texture_name, PortType p_port_type) const;
 
 	void _update_texture(const Vector<Vector2> &p_array, Ref<ImageTexture> &r_texture);
 	void _update_texture(const Vector<Vector3> &p_array, Ref<ImageTexture> &r_texture);
@@ -213,7 +214,8 @@ class VisualShaderNodeParticleRandomness : public VisualShaderNode {
 public:
 	enum OpType {
 		OP_TYPE_SCALAR,
-		OP_TYPE_VECTOR,
+		OP_TYPE_VECTOR_2D,
+		OP_TYPE_VECTOR_3D,
 		OP_TYPE_MAX,
 	};
 

+ 16 - 16
scene/resources/visual_shader_sdf_nodes.cpp

@@ -41,7 +41,7 @@ int VisualShaderNodeSDFToScreenUV::get_input_port_count() const {
 }
 
 VisualShaderNodeSDFToScreenUV::PortType VisualShaderNodeSDFToScreenUV::get_input_port_type(int p_port) const {
-	return PORT_TYPE_VECTOR_3D;
+	return PORT_TYPE_VECTOR_2D;
 }
 
 String VisualShaderNodeSDFToScreenUV::get_input_port_name(int p_port) const {
@@ -53,7 +53,7 @@ int VisualShaderNodeSDFToScreenUV::get_output_port_count() const {
 }
 
 VisualShaderNodeSDFToScreenUV::PortType VisualShaderNodeSDFToScreenUV::get_output_port_type(int p_port) const {
-	return PORT_TYPE_VECTOR_3D;
+	return PORT_TYPE_VECTOR_2D;
 }
 
 String VisualShaderNodeSDFToScreenUV::get_output_port_name(int p_port) const {
@@ -61,7 +61,7 @@ String VisualShaderNodeSDFToScreenUV::get_output_port_name(int p_port) const {
 }
 
 String VisualShaderNodeSDFToScreenUV::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 {
-	return "		" + p_output_vars[0] + " = vec3(sdf_to_screen_uv(" + (p_input_vars[0].is_empty() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + "), 0.0f);\n";
+	return "		" + p_output_vars[0] + " = sdf_to_screen_uv(" + (p_input_vars[0].is_empty() ? "vec2(0.0)" : p_input_vars[0]) + ");\n";
 }
 
 VisualShaderNodeSDFToScreenUV::VisualShaderNodeSDFToScreenUV() {
@@ -78,7 +78,7 @@ int VisualShaderNodeScreenUVToSDF::get_input_port_count() const {
 }
 
 VisualShaderNodeScreenUVToSDF::PortType VisualShaderNodeScreenUVToSDF::get_input_port_type(int p_port) const {
-	return PORT_TYPE_VECTOR_3D;
+	return PORT_TYPE_VECTOR_2D;
 }
 
 String VisualShaderNodeScreenUVToSDF::get_input_port_name(int p_port) const {
@@ -90,7 +90,7 @@ int VisualShaderNodeScreenUVToSDF::get_output_port_count() const {
 }
 
 VisualShaderNodeScreenUVToSDF::PortType VisualShaderNodeScreenUVToSDF::get_output_port_type(int p_port) const {
-	return PORT_TYPE_VECTOR_3D;
+	return PORT_TYPE_VECTOR_2D;
 }
 
 String VisualShaderNodeScreenUVToSDF::get_output_port_name(int p_port) const {
@@ -105,7 +105,7 @@ bool VisualShaderNodeScreenUVToSDF::is_input_port_default(int p_port, Shader::Mo
 }
 
 String VisualShaderNodeScreenUVToSDF::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 {
-	return "		" + p_output_vars[0] + " = vec3(screen_uv_to_sdf(" + (p_input_vars[0].is_empty() ? "SCREEN_UV" : p_input_vars[0] + ".xy") + "), 0.0f);\n";
+	return "		" + p_output_vars[0] + " = screen_uv_to_sdf(" + (p_input_vars[0].is_empty() ? "SCREEN_UV" : p_input_vars[0]) + ");\n";
 }
 
 VisualShaderNodeScreenUVToSDF::VisualShaderNodeScreenUVToSDF() {
@@ -122,7 +122,7 @@ int VisualShaderNodeTextureSDF::get_input_port_count() const {
 }
 
 VisualShaderNodeTextureSDF::PortType VisualShaderNodeTextureSDF::get_input_port_type(int p_port) const {
-	return PORT_TYPE_VECTOR_3D;
+	return PORT_TYPE_VECTOR_2D;
 }
 
 String VisualShaderNodeTextureSDF::get_input_port_name(int p_port) const {
@@ -142,7 +142,7 @@ String VisualShaderNodeTextureSDF::get_output_port_name(int p_port) const {
 }
 
 String VisualShaderNodeTextureSDF::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 {
-	return "		" + p_output_vars[0] + " = texture_sdf(" + (p_input_vars[0].is_empty() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + ");\n";
+	return "		" + p_output_vars[0] + " = texture_sdf(" + (p_input_vars[0].is_empty() ? "vec2(0.0)" : p_input_vars[0]) + ");\n";
 }
 
 VisualShaderNodeTextureSDF::VisualShaderNodeTextureSDF() {
@@ -159,7 +159,7 @@ int VisualShaderNodeTextureSDFNormal::get_input_port_count() const {
 }
 
 VisualShaderNodeTextureSDFNormal::PortType VisualShaderNodeTextureSDFNormal::get_input_port_type(int p_port) const {
-	return PORT_TYPE_VECTOR_3D;
+	return PORT_TYPE_VECTOR_2D;
 }
 
 String VisualShaderNodeTextureSDFNormal::get_input_port_name(int p_port) const {
@@ -171,7 +171,7 @@ int VisualShaderNodeTextureSDFNormal::get_output_port_count() const {
 }
 
 VisualShaderNodeTextureSDFNormal::PortType VisualShaderNodeTextureSDFNormal::get_output_port_type(int p_port) const {
-	return PORT_TYPE_VECTOR_3D;
+	return PORT_TYPE_VECTOR_2D;
 }
 
 String VisualShaderNodeTextureSDFNormal::get_output_port_name(int p_port) const {
@@ -179,7 +179,7 @@ String VisualShaderNodeTextureSDFNormal::get_output_port_name(int p_port) const
 }
 
 String VisualShaderNodeTextureSDFNormal::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 {
-	return "		" + p_output_vars[0] + " = vec3(texture_sdf_normal(" + (p_input_vars[0].is_empty() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + "), 0.0f);\n";
+	return "		" + p_output_vars[0] + " = texture_sdf_normal(" + (p_input_vars[0].is_empty() ? "vec2(0.0)" : p_input_vars[0]) + ");\n";
 }
 
 VisualShaderNodeTextureSDFNormal::VisualShaderNodeTextureSDFNormal() {
@@ -197,7 +197,7 @@ int VisualShaderNodeSDFRaymarch::get_input_port_count() const {
 
 VisualShaderNodeSDFRaymarch::PortType VisualShaderNodeSDFRaymarch::get_input_port_type(int p_port) const {
 	if (p_port == 0 || p_port == 1) {
-		return PORT_TYPE_VECTOR_3D;
+		return PORT_TYPE_VECTOR_2D;
 	}
 	return PORT_TYPE_SCALAR;
 }
@@ -221,7 +221,7 @@ VisualShaderNodeSDFRaymarch::PortType VisualShaderNodeSDFRaymarch::get_output_po
 	} else if (p_port == 1) {
 		return PORT_TYPE_BOOLEAN;
 	} else if (p_port == 2) {
-		return PORT_TYPE_VECTOR_3D;
+		return PORT_TYPE_VECTOR_2D;
 	}
 	return PORT_TYPE_SCALAR;
 }
@@ -245,13 +245,13 @@ String VisualShaderNodeSDFRaymarch::generate_code(Shader::Mode p_mode, VisualSha
 	if (p_input_vars[0].is_empty()) {
 		code += "				vec2 __from_pos = vec2(0.0f);\n";
 	} else {
-		code += "				vec2 __from_pos = " + p_input_vars[0] + ".xy;\n";
+		code += "				vec2 __from_pos = " + p_input_vars[0] + ";\n";
 	}
 
 	if (p_input_vars[1].is_empty()) {
 		code += "				vec2 __to_pos = vec2(0.0f);\n";
 	} else {
-		code += "				vec2 __to_pos = " + p_input_vars[1] + ".xy;\n";
+		code += "				vec2 __to_pos = " + p_input_vars[1] + ";\n";
 	}
 
 	code += "\n				vec2 __at = __from_pos;\n";
@@ -271,7 +271,7 @@ String VisualShaderNodeSDFRaymarch::generate_code(Shader::Mode p_mode, VisualSha
 	code += "				float __dist = min(__max_dist, __accum);\n";
 	code += "				" + p_output_vars[0] + " = __dist;\n";
 	code += "				" + p_output_vars[1] + " = __accum < __max_dist;\n";
-	code += "				" + p_output_vars[2] + " = vec3(__from_pos + __dir * __dist, 0.0f);\n";
+	code += "				" + p_output_vars[2] + " = __from_pos + __dir * __dist;\n";
 
 	code += "		}\n";