Add some more fixes to visual shader
This commit is contained in:
parent
481b05fef1
commit
a6e280c5de
11 changed files with 160 additions and 101 deletions
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;"
|
||||
|
|
|
@ -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 "";
|
||||
|
|
|
@ -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";
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
||||
|
|
Loading…
Reference in a new issue