diff --git a/addons/ShaderLib/Artistic/Adjustment/Contrast.gd b/addons/ShaderLib/Artistic/Adjustment/Contrast.gd
new file mode 100644
index 0000000..3cbdd34
--- /dev/null
+++ b/addons/ShaderLib/Artistic/Adjustment/Contrast.gd
@@ -0,0 +1,60 @@
+@tool
+class_name VisualShaderNodeAdjustmentContrast extends VisualShaderNodeCustom
+
+func _get_name() -> String:
+ return "Contrast"
+
+func _get_category() -> String:
+ return "Artistic/Adjustment"
+
+func _get_description() -> String:
+ return "Adjusts the contrast of input in by the amount of input contrast."
+
+func _get_return_icon_type() -> PortType:
+ return PORT_TYPE_VECTOR_3D
+
+func _get_input_port_count() -> int:
+ return 2
+
+func _get_input_port_name(port: int) -> String:
+ match port:
+ 0:
+ return "in"
+ _:
+ return "contrast"
+
+func _get_input_port_type(port: int) -> PortType:
+ match port:
+ 0:
+ return PORT_TYPE_VECTOR_3D
+ _:
+ return PORT_TYPE_SCALAR
+
+func _get_input_port_default_value(port: int) -> Variant:
+ match port:
+ 1:
+ return 1.0
+ _:
+ return Vector3(1.0, 1.0, 1.0)
+
+func _get_output_port_count() -> int:
+ return 1
+
+func _get_output_port_name(port: int) -> String:
+ return "out"
+
+func _get_output_port_type(port: int) -> PortType:
+ return PORT_TYPE_VECTOR_3D
+
+func _get_global_code(mode: Shader.Mode) -> String:
+ var code: String = preload("Contrast.gdshaderinc").code
+ return code
+
+func _get_code(input_vars: Array[String], output_vars: Array[String], mode: Shader.Mode, type: VisualShader.Type) -> String:
+ var input: String = "vec3(1.0)"
+
+ if input_vars[0]:
+ input = input_vars[0]
+
+ var contrast: String = input_vars[1]
+ return output_vars[0] + " = contrast(%s, %s);" % [input, contrast]
diff --git a/addons/ShaderLib/Artistic/Adjustment/Contrast.gdshaderinc b/addons/ShaderLib/Artistic/Adjustment/Contrast.gdshaderinc
new file mode 100644
index 0000000..9559991
--- /dev/null
+++ b/addons/ShaderLib/Artistic/Adjustment/Contrast.gdshaderinc
@@ -0,0 +1,4 @@
+vec3 contrast(vec3 input, float contrast){
+ float midpoint = pow(0.5, 2.2);
+ return (input - midpoint) * contrast + midpoint;
+}
\ No newline at end of file
diff --git a/addons/ShaderLib/Artistic/Adjustment/Hue.gd b/addons/ShaderLib/Artistic/Adjustment/Hue.gd
new file mode 100644
index 0000000..9f29fd5
--- /dev/null
+++ b/addons/ShaderLib/Artistic/Adjustment/Hue.gd
@@ -0,0 +1,73 @@
+@tool
+class_name VisualShaderNodeAdjustmentHue extends VisualShaderNodeCustom
+
+func _get_name() -> String:
+ return "Hue"
+
+func _get_category() -> String:
+ return "Artistic/Adjustment"
+
+func _get_description() -> String:
+ return "Offsets the hue of input in by the amount of input offset."
+
+func _get_return_icon_type() -> PortType:
+ return PORT_TYPE_VECTOR_3D
+
+func _get_input_port_count() -> int:
+ return 2
+
+func _get_input_port_name(port: int) -> String:
+ match port:
+ 0:
+ return "in"
+ _:
+ return "offset"
+
+func _get_input_port_type(port: int) -> PortType:
+ match port:
+ 0:
+ return PORT_TYPE_VECTOR_3D
+ _:
+ return PORT_TYPE_SCALAR
+
+func _get_input_port_default_value(port: int) -> Variant:
+ match port:
+ 1:
+ return 0.0
+ _:
+ return Vector3(1.0, 1.0, 1.0)
+
+func _get_output_port_count() -> int:
+ return 1
+
+func _get_output_port_name(port: int) -> String:
+ return "out"
+
+func _get_output_port_type(port: int) -> PortType:
+ return PORT_TYPE_VECTOR_3D
+
+func _get_property_count() -> int:
+ return 1
+
+func _get_property_default_index(index: int) -> int:
+ return 0
+
+func _get_property_name(index: int) -> String:
+ return "Range"
+
+func _get_property_options(index: int) -> PackedStringArray:
+ return ["Degrees", "Normalize"]
+
+func _get_global_code(mode: Shader.Mode) -> String:
+ var code: String = preload("Hue.gdshaderinc").code
+ return code
+
+func _get_code(input_vars: Array[String], output_vars: Array[String], mode: Shader.Mode, type: VisualShader.Type) -> String:
+ var range_index: int = get_option_index(0)
+ var input: String = "vec3(1.0)"
+ var offset: String = input_vars[1]
+
+ if input_vars[0]:
+ input = input_vars[0]
+
+ return output_vars[0] + " = hue(%s, %s, %s);" % [input, offset, range_index]
diff --git a/addons/ShaderLib/Artistic/Adjustment/Hue.gdshaderinc b/addons/ShaderLib/Artistic/Adjustment/Hue.gdshaderinc
new file mode 100644
index 0000000..9919c9b
--- /dev/null
+++ b/addons/ShaderLib/Artistic/Adjustment/Hue.gdshaderinc
@@ -0,0 +1,27 @@
+vec3 hue(vec3 input, float offset, int range_index){
+ // RGB to HSV
+ vec4 k = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
+ vec4 p = mix(vec4(input.bg, k.wz), vec4(input.gb, k.xy), step(input.b, input.g));
+ vec4 q = mix(vec4(p.xyw, input.r), vec4(input.r, p.yzx), step(p.x, input.r));
+ float d = q.x - min(q.w, q.y);
+ float e = 1.0e-10;
+ vec3 hsv = vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
+
+ offset = (range_index == 0) ? offset / 360.0 : offset;
+ float hue = hsv.x + offset;
+ if(hue < 0.0){
+ hsv.x = hue + 1.;
+ }
+ else if(hue > 1.){
+ hsv.x = hue - 1.;
+ }
+ else{
+ hsv.x = hue;
+ }
+
+ // HSV to RGB
+ vec4 k2 = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
+ vec3 p2 = abs(fract(hsv.xxx + k2.xyz) * 6.0 - k2.www);
+ vec3 rgb = hsv.z * mix(k2.xxx, clamp(p2 - k2.xxx, 0.0, 1.0), hsv.y);
+ return rgb;
+}
\ No newline at end of file
diff --git a/addons/ShaderLib/Artistic/Adjustment/ReplaceColor.gd b/addons/ShaderLib/Artistic/Adjustment/ReplaceColor.gd
new file mode 100644
index 0000000..8a64cd8
--- /dev/null
+++ b/addons/ShaderLib/Artistic/Adjustment/ReplaceColor.gd
@@ -0,0 +1,78 @@
+@tool
+class_name VisualShaderNodeAdjustmentReplaceColor extends VisualShaderNodeCustom
+
+func _get_name() -> String:
+ return "ReplaceColor"
+
+func _get_category() -> String:
+ return "Artistic/Adjustment"
+
+func _get_description() -> String:
+ return "Replaces values in input \"in\" equal to input \"from\" to the value of input \"to\"."
+
+func _get_return_icon_type() -> PortType:
+ return PORT_TYPE_VECTOR_3D
+
+func _get_input_port_count() -> int:
+ return 5
+
+func _get_input_port_name(port: int) -> String:
+ match port:
+ 0:
+ return "in"
+ 1:
+ return "from"
+ 2:
+ return "to"
+ 3:
+ return "range"
+ _:
+ return "fuzziness"
+
+func _get_input_port_type(port: int) -> PortType:
+ match port:
+ 0, 1, 2:
+ return PORT_TYPE_VECTOR_3D
+ _:
+ return PORT_TYPE_SCALAR
+
+func _get_input_port_default_value(port: int) -> Variant:
+ match port:
+ 1, 2:
+ return Vector3(0.0, 0.0, 0.0)
+ 3, 4:
+ return 0.0
+ _:
+ return Vector3(1.0, 1.0, 1.0)
+
+func _get_output_port_count() -> int:
+ return 1
+
+func _get_output_port_name(port: int) -> String:
+ return "out"
+
+func _get_output_port_type(port: int) -> PortType:
+ return PORT_TYPE_VECTOR_3D
+
+func _get_global_code(mode: Shader.Mode) -> String:
+ var code: String = preload("ReplaceColor.gdshaderinc").code
+ return code
+
+func _get_code(input_vars: Array[String], output_vars: Array[String], mode: Shader.Mode, type: VisualShader.Type) -> String:
+ var input: String = "vec3(1.0)"
+ var from: String = "vec3(1.0)"
+ var to: String = "vec3(1.0)"
+
+ if input_vars[0]:
+ input = input_vars[0]
+
+ if input_vars[1]:
+ from = input_vars[1]
+
+ if input_vars[2]:
+ to = input_vars[2]
+
+ var range: String = input_vars[3]
+ var fuzziness: String = input_vars[4]
+
+ return output_vars[0] + " = replace_color(%s, %s, %s, %s, %s);" % [input, from, to, range, fuzziness]
diff --git a/addons/ShaderLib/Artistic/Adjustment/ReplaceColor.gdshaderinc b/addons/ShaderLib/Artistic/Adjustment/ReplaceColor.gdshaderinc
new file mode 100644
index 0000000..2797299
--- /dev/null
+++ b/addons/ShaderLib/Artistic/Adjustment/ReplaceColor.gdshaderinc
@@ -0,0 +1,4 @@
+vec3 replace_color(vec3 input, vec3 from, vec3 to, float range, float fuzziness){
+ float dist = distance(from, input);
+ return mix(to, input, clamp((dist - range) / max(fuzziness, 1.0e-5), 0.0, 1.0));
+}
\ No newline at end of file
diff --git a/addons/ShaderLib/Artistic/Adjustment/Saturation.gd b/addons/ShaderLib/Artistic/Adjustment/Saturation.gd
new file mode 100644
index 0000000..d295558
--- /dev/null
+++ b/addons/ShaderLib/Artistic/Adjustment/Saturation.gd
@@ -0,0 +1,61 @@
+@tool
+class_name VisualShaderNodeAdjustmentSaturation extends VisualShaderNodeCustom
+
+
+func _get_name() -> String:
+ return "Saturation"
+
+func _get_category() -> String:
+ return "Artistic/Adjustment"
+
+func _get_description() -> String:
+ return "Adjusts the saturation of input \"in\" by the amount of input \"saturation\"."
+
+func _get_return_icon_type() -> PortType:
+ return PORT_TYPE_VECTOR_3D
+
+func _get_input_port_count() -> int:
+ return 2
+
+func _get_input_port_name(port: int) -> String:
+ match port:
+ 0:
+ return "in"
+ _:
+ return "saturation"
+
+func _get_input_port_type(port: int) -> PortType:
+ match port:
+ 0:
+ return PORT_TYPE_VECTOR_3D
+ _:
+ return PORT_TYPE_SCALAR
+
+func _get_input_port_default_value(port: int) -> Variant:
+ match port:
+ 0:
+ return Vector3(1.0, 1.0, 1.0)
+ _:
+ return 1.0
+
+func _get_output_port_count() -> int:
+ return 1
+
+func _get_output_port_name(port: int) -> String:
+ return "out"
+
+func _get_output_port_type(port: int) -> PortType:
+ return PORT_TYPE_VECTOR_3D
+
+func _get_global_code(mode: Shader.Mode) -> String:
+ var code: String = preload("Saturation.gdshaderinc").code
+ return code
+
+func _get_code(input_vars: Array[String], output_vars: Array[String], mode: Shader.Mode, type: VisualShader.Type) -> String:
+ var input: String = "vec3(1.0)"
+
+ if input_vars[0]:
+ input = input_vars[0]
+
+ var saturation = input_vars[1]
+ return output_vars[0] + " = saturation(%s, %s);" % [input, saturation]
diff --git a/addons/ShaderLib/Artistic/Adjustment/Saturation.gdshaderinc b/addons/ShaderLib/Artistic/Adjustment/Saturation.gdshaderinc
new file mode 100644
index 0000000..f3f958b
--- /dev/null
+++ b/addons/ShaderLib/Artistic/Adjustment/Saturation.gdshaderinc
@@ -0,0 +1,4 @@
+vec3 saturation(vec3 input, float saturation){
+ float luma = dot(input, vec3(0.2126729, 0.7151522, 0.0721750));
+ return luma + saturation * (input - vec3(luma));
+}
\ No newline at end of file
diff --git a/addons/ShaderLib/Artistic/Adjustment/WhiteBalance.gd b/addons/ShaderLib/Artistic/Adjustment/WhiteBalance.gd
new file mode 100644
index 0000000..f5a31e7
--- /dev/null
+++ b/addons/ShaderLib/Artistic/Adjustment/WhiteBalance.gd
@@ -0,0 +1,64 @@
+@tool
+class_name VisualShaderNodeWhiteBalance extends VisualShaderNodeCustom
+
+func _get_name() -> String:
+ return "WhiteBalance"
+
+func _get_category() -> String:
+ return "Artistic/Adjustment"
+
+func _get_description() -> String:
+ return "Adjusts the temperature and tint of input \"in\" by the amount of inputs \"temperature\" and \"tint\" respectively."
+
+func _get_return_icon_type() -> PortType:
+ return PORT_TYPE_VECTOR_3D
+
+func _get_input_port_count() -> int:
+ return 3
+
+func _get_input_port_name(port: int) -> String:
+ match port:
+ 0:
+ return "in"
+ 1:
+ return "temperature"
+ _:
+ return "tint"
+
+func _get_input_port_type(port: int) -> PortType:
+ match port:
+ 0:
+ return PORT_TYPE_VECTOR_3D
+ _:
+ return PORT_TYPE_SCALAR
+
+func _get_input_port_default_value(port: int) -> Variant:
+ match port:
+ 1, 2:
+ return 0.0
+ _:
+ return Vector3(1.0, 1.0, 1.0)
+
+func _get_output_port_count() -> int:
+ return 1
+
+func _get_output_port_name(port: int) -> String:
+ return "out"
+
+func _get_output_port_type(port: int) -> PortType:
+ return PORT_TYPE_VECTOR_3D
+
+func _get_global_code(mode: Shader.Mode) -> String:
+ var code: String = preload("WhiteBalance.gdshaderinc").code
+ return code
+
+func _get_code(input_vars: Array[String], output_vars: Array[String], mode: Shader.Mode, type: VisualShader.Type) -> String:
+ var input: String = "vec3(1.0)"
+
+ if input_vars[0]:
+ input = input_vars[0]
+
+ var temperature: String = input_vars[1]
+ var tint: String = input_vars[2]
+
+ return output_vars[0] + " = white_balance(%s, %s, %s);" % [input, temperature, tint]
diff --git a/addons/ShaderLib/Artistic/Adjustment/WhiteBalance.gdshaderinc b/addons/ShaderLib/Artistic/Adjustment/WhiteBalance.gdshaderinc
new file mode 100644
index 0000000..727e73a
--- /dev/null
+++ b/addons/ShaderLib/Artistic/Adjustment/WhiteBalance.gdshaderinc
@@ -0,0 +1,36 @@
+vec3 white_balance(vec3 input, float temperature, float tint){
+ float t1 = temperature * 10.0 / 6.0;
+ float t2 = tint * 10.0 / 6.0;
+
+ float x = 0.31271 - t1 * (t1 < 0.0 ? 0.1 : 0.05);
+ float standard_illuminant_y = 2.87 * x - 3.0 * x * x - 0.27509507;
+ float y = standard_illuminant_y + t2 * 0.05;
+
+ vec3 w1 = vec3(0.949237, 1.03542, 1.08728);
+
+ float Y = 1.;
+ float X = Y * x / y;
+ float Z = Y * (1. - x - y) / y;
+ float L = 0.7328 * X + 0.4296 * Y - 0.1624 * Z;
+ float M = -0.7036 * X + 1.6975 * Y + 0.0061 * Z;
+ float S = 0.0030 * X + 0.0136 * Y + 0.9834 * Z;
+ vec3 w2 = vec3(L, M, S);
+
+ vec3 balance = vec3(w1.x / w2.x, w1.y / w2.y, w1.z / w2.z);
+
+ mat3 LIN_2_LMS_MAT = mat3(
+ vec3(3.90405e-1, 5.49941e-1, 8.92632e-3),
+ vec3(7.08416e-2, 9.63172e-1, 1.35775e-3),
+ vec3(2.31082e-2, 1.28021e-1, 9.36245e-1)
+ );
+
+ mat3 LMS_2_LIN_MAT = mat3(
+ vec3(2.85847, -1.62879, -2.48910),
+ vec3(-2.10182e-1, 1.15820e+0, 3.24281e-4),
+ vec3(-4.18120e-2, -1.18169e-1, 1.06867e+0)
+ );
+
+ vec3 lms = LIN_2_LMS_MAT * input;
+ lms *= balance;
+ return LMS_2_LIN_MAT * lms;
+}
\ No newline at end of file
diff --git a/addons/ShaderLib/Artistic/Mask/ColorMask.gd b/addons/ShaderLib/Artistic/Mask/ColorMask.gd
new file mode 100644
index 0000000..fbd0b5a
--- /dev/null
+++ b/addons/ShaderLib/Artistic/Mask/ColorMask.gd
@@ -0,0 +1,69 @@
+@tool
+class_name VisualShaderNodeMaskColorMask extends VisualShaderNodeCustom
+
+func _get_name() -> String:
+ return "ColorMask"
+
+func _get_category() -> String:
+ return "Artistic/Mask"
+
+func _get_description() -> String:
+ return "Creates a mask from values in input \"in\" equal to input \"mask color\"."
+
+func _get_return_icon_type() -> PortType:
+ return PORT_TYPE_VECTOR_4D
+
+func _get_input_port_count() -> int:
+ return 4
+
+func _get_input_port_name(port: int) -> String:
+ match port:
+ 0:
+ return "in"
+ 1:
+ return "color mask"
+ 2:
+ return "range"
+ _:
+ return "fuzziness"
+
+func _get_input_port_type(port: int) -> PortType:
+ match port:
+ 0, 1:
+ return PORT_TYPE_VECTOR_3D
+ _:
+ return PORT_TYPE_SCALAR
+
+func _get_input_port_default_value(port: int) -> Variant:
+ match port:
+ 0:
+ return Vector3(1.0, 1.0, 1.0)
+ 1:
+ return Vector3(0.0, 0.0, 0.0)
+ _:
+ return 0.0
+
+func _get_output_port_count() -> int:
+ return 1
+
+func _get_output_port_name(port: int) -> String:
+ return "out"
+
+func _get_output_port_type(port: int) -> PortType:
+ return PORT_TYPE_VECTOR_4D
+
+func _get_global_code(mode: Shader.Mode) -> String:
+ var code: String = preload("ColorMask.gdshaderinc").code
+ return code
+
+func _get_code(input_vars: Array[String], output_vars: Array[String], mode: Shader.Mode, type: VisualShader.Type) -> String:
+ var input: String = "vec3(0.0)"
+
+ if input_vars[0]:
+ input = input_vars[0]
+
+ var color_mask: String = input_vars[1]
+ var range: String = input_vars[2]
+ var fuzziness: String = input_vars[3]
+
+ return output_vars[0] + " = color_mask(%s, %s, %s, %s);" % [input, color_mask, range, fuzziness]
diff --git a/addons/ShaderLib/Artistic/Mask/ColorMask.gdshaderinc b/addons/ShaderLib/Artistic/Mask/ColorMask.gdshaderinc
new file mode 100644
index 0000000..f304e05
--- /dev/null
+++ b/addons/ShaderLib/Artistic/Mask/ColorMask.gdshaderinc
@@ -0,0 +1,4 @@
+vec4 color_mask(vec3 input, vec3 mask_color, float range, float fuzziness){
+ float dist = distance(mask_color, input);
+ return vec4(clamp(1. - (dist - range) / max(fuzziness, 1e-5), 0., 1.));
+}
\ No newline at end of file
diff --git a/addons/ShaderLib/Maths/Vector/Project.gd b/addons/ShaderLib/Maths/Vector/Project.gd
new file mode 100644
index 0000000..6333216
--- /dev/null
+++ b/addons/ShaderLib/Maths/Vector/Project.gd
@@ -0,0 +1,74 @@
+@tool
+class_name VisualShaderNodeVectorProject extends VisualShaderNodeCustom
+
+func _get_name() -> String:
+ return "Project"
+
+func _get_category() -> String:
+ return "Maths/Vector"
+
+func _get_description() -> String:
+ return "Projects vector A onto vector B."
+
+func _get_return_icon_type() -> PortType:
+ var vector_index: int = get_option_index(0)
+ match vector_index:
+ 0:
+ return PORT_TYPE_VECTOR_2D
+ _:
+ return PORT_TYPE_VECTOR_3D
+
+func _get_input_port_count() -> int:
+ return 2
+
+func _get_input_port_name(port: int) -> String:
+ match port:
+ 0:
+ return "vector A"
+ _:
+ return "vector B"
+
+func _get_input_port_type(port: int) -> PortType:
+ var vector_index: int = get_option_index(0)
+ match vector_index:
+ 0:
+ return PORT_TYPE_VECTOR_2D
+ _:
+ return PORT_TYPE_VECTOR_3D
+
+func _get_output_port_count() -> int:
+ return 1
+
+func _get_output_port_name(port: int) -> String:
+ return "vector"
+
+func _get_output_port_type(port: int) -> PortType:
+ var vector_index: int = get_option_index(0)
+ match vector_index:
+ 0:
+ return PORT_TYPE_VECTOR_2D
+ _:
+ return PORT_TYPE_VECTOR_3D
+
+func _get_property_count() -> int:
+ return 1
+
+func _get_property_default_index(index: int) -> int:
+ return 0
+
+func _get_property_name(index: int) -> String:
+ return ""
+
+func _get_property_options(index: int) -> PackedStringArray:
+ return ["Vector2", "Vector3"]
+
+func _get_code(input_vars: Array[String], output_vars: Array[String], mode: Shader.Mode, type: VisualShader.Type) -> String:
+ var vector_a: String = input_vars[0]
+ var vector_b: String = input_vars[1]
+ var vector_index: int = get_option_index(0)
+
+ match vector_index:
+ 0:
+ return output_vars[0] + " = vec2(%s.xy) * (dot(%s.xy, %s.xy) / dot(%s.xy, %s.xy));" % [vector_b, vector_a, vector_b, vector_b, vector_b]
+ _:
+ return output_vars[0] + " = %s * (dot(%s, %s) / dot(%s, %s));" % [vector_b, vector_a, vector_b, vector_b, vector_b]
diff --git a/addons/ShaderLib/Maths/Vector/ProjectOnPlane.gd b/addons/ShaderLib/Maths/Vector/ProjectOnPlane.gd
new file mode 100644
index 0000000..4abdfa0
--- /dev/null
+++ b/addons/ShaderLib/Maths/Vector/ProjectOnPlane.gd
@@ -0,0 +1,73 @@
+@tool
+class_name VisualShaderNodeVectorProjectOnPlane extends VisualShaderNodeCustom
+
+func _get_name() -> String:
+ return "ProjectOnPlane"
+
+func _get_category() -> String:
+ return "Maths/Vector"
+
+func _get_description() -> String:
+ return "Projects a vector onto a plane defined by a normal orthogonal to the plane."
+
+func _get_return_icon_type() -> PortType:
+ var vector_index: int = get_option_index(0)
+ match vector_index:
+ 0:
+ return PORT_TYPE_VECTOR_2D
+ _:
+ return PORT_TYPE_VECTOR_3D
+
+func _get_input_port_count() -> int:
+ return 2
+
+func _get_input_port_name(port: int) -> String:
+ match port:
+ 0:
+ return "vector"
+ _:
+ return "plane normal"
+
+func _get_input_port_type(port: int) -> PortType:
+ var vector_index: int = get_option_index(0)
+ match vector_index:
+ 0:
+ return PORT_TYPE_VECTOR_2D
+ _:
+ return PORT_TYPE_VECTOR_3D
+
+func _get_output_port_count() -> int:
+ return 1
+
+func _get_output_port_name(port: int) -> String:
+ return "vector"
+
+func _get_output_port_type(port: int) -> PortType:
+ var vector_index: int = get_option_index(0)
+ match vector_index:
+ 0:
+ return PORT_TYPE_VECTOR_2D
+ _:
+ return PORT_TYPE_VECTOR_3D
+
+func _get_property_count() -> int:
+ return 1
+
+func _get_property_default_index(index: int) -> int:
+ return 0
+
+func _get_property_name(index: int) -> String:
+ return ""
+
+func _get_property_options(index: int) -> PackedStringArray:
+ return ["Vector2", "Vector3"]
+
+func _get_code(input_vars: Array[String], output_vars: Array[String], mode: Shader.Mode, type: VisualShader.Type) -> String:
+ var vector_a: String = input_vars[0]
+ var plane_normal: String = input_vars[1]
+ var vector_index: int = get_option_index(0)
+ match vector_index:
+ 0:
+ return output_vars[0] + " = %s.xy - (%s.xy * (dot(%s.xy, %s.xy) / dot(%s.xy, %s.xy)));" % [vector_a, plane_normal, vector_a, plane_normal, plane_normal, plane_normal]
+ _:
+ return output_vars[0] + " = %s - (%s * (dot(%s, %s) / dot(%s, %s)));" % [vector_a, plane_normal, vector_a, plane_normal, plane_normal, plane_normal]
diff --git a/addons/ShaderLib/Maths/Wave/NoiseSineWave.gd b/addons/ShaderLib/Maths/Wave/NoiseSineWave.gd
index 2c9c4c5..c5d9f74 100644
--- a/addons/ShaderLib/Maths/Wave/NoiseSineWave.gd
+++ b/addons/ShaderLib/Maths/Wave/NoiseSineWave.gd
@@ -11,7 +11,16 @@ func _get_description() -> String:
return "Returns the sine of the value of input in. For variance, psuedo-random noise is added to the amplitude of the sine wave, within a range determined by input min max."
func _get_return_icon_type() -> VisualShaderNode.PortType:
- return PORT_TYPE_VECTOR_4D
+ var vector_index: int = get_option_index(0)
+ match vector_index:
+ 0:
+ return PORT_TYPE_SCALAR
+ 1:
+ return PORT_TYPE_VECTOR_2D
+ 2:
+ return PORT_TYPE_VECTOR_3D
+ _:
+ return PORT_TYPE_VECTOR_4D
func _get_input_port_count() -> int:
return 2
@@ -26,7 +35,16 @@ func _get_input_port_name(port: int) -> String:
func _get_input_port_type(port: int) -> VisualShaderNode.PortType:
match port:
0:
- return PORT_TYPE_VECTOR_4D
+ var vector_index: int = get_option_index(0)
+ match vector_index:
+ 0:
+ return PORT_TYPE_SCALAR
+ 1:
+ return PORT_TYPE_VECTOR_2D
+ 2:
+ return PORT_TYPE_VECTOR_3D
+ _:
+ return PORT_TYPE_VECTOR_4D
1:
return PORT_TYPE_VECTOR_2D
return PORT_TYPE_SCALAR
@@ -45,16 +63,57 @@ func _get_output_port_name(port: int) -> String:
return "out"
func _get_output_port_type(port: int) -> VisualShaderNode.PortType:
- return PORT_TYPE_VECTOR_4D
+ var vector_index: int = get_option_index(0)
+ match vector_index:
+ 0:
+ return PORT_TYPE_SCALAR
+ 1:
+ return PORT_TYPE_VECTOR_2D
+ 2:
+ return PORT_TYPE_VECTOR_3D
+ _:
+ return PORT_TYPE_VECTOR_4D
+
+func _get_property_count() -> int:
+ return 1
+
+func _get_property_default_index(index: int) -> int:
+ return 0
+
+func _get_property_name(index: int) -> String:
+ return ""
+
+func _get_property_options(index: int) -> PackedStringArray:
+ return ["Vector1", "Vector2", "Vector3", "Vector4"]
func _get_global_code(mode: Shader.Mode) -> String:
var code: String = preload("NoiseSineWave.gdshaderinc").code
return code
func _get_code(input_vars: Array[String], output_vars: Array[String], mode: Shader.Mode, type: VisualShader.Type) -> String:
- var input: String = "vec4(0.0)"
+ var input: String
+ var vector_index: int = get_option_index(0)
+ match vector_index:
+ 0:
+ input = "0.0"
+ 1:
+ input = "vec2(0.0)"
+ 2:
+ input = "vec3(0.0)"
+ _:
+ input = "vec4(0.0)"
+
if input_vars[0]:
input = input_vars[0]
var min_max: String = input_vars[1]
- return output_vars[0] + " = noise_sine_wave(%s, %s);" % [input, min_max]
+
+ match vector_index:
+ 0:
+ return output_vars[0] + " = noise_sine_wave(vec4(%s), %s).x;" % [input, min_max]
+ 1:
+ return output_vars[0] + " = noise_sine_wave(vec4(%s, 0.0, 0.0), %s).xy;" % [input, min_max]
+ 2:
+ return output_vars[0] + " = noise_sine_wave(vec4(%s, 0.0), %s).xyz;" % [input, min_max]
+ _:
+ return output_vars[0] + " = noise_sine_wave(%s, %s);" % [input, min_max]
diff --git a/addons/ShaderLib/Maths/Wave/SawtoothWave.gd b/addons/ShaderLib/Maths/Wave/SawtoothWave.gd
index 93fcd4b..2b82b9f 100644
--- a/addons/ShaderLib/Maths/Wave/SawtoothWave.gd
+++ b/addons/ShaderLib/Maths/Wave/SawtoothWave.gd
@@ -11,7 +11,16 @@ func _get_description() -> String:
return "Returns a sawtooth wave from the value of input in. Resulting output values will be between -1 and 1."
func _get_return_icon_type() -> VisualShaderNode.PortType:
- return PORT_TYPE_VECTOR_4D
+ var vector_index: int = get_option_index(0)
+ match vector_index:
+ 0:
+ return PORT_TYPE_SCALAR
+ 1:
+ return PORT_TYPE_VECTOR_2D
+ 2:
+ return PORT_TYPE_VECTOR_3D
+ _:
+ return PORT_TYPE_VECTOR_4D
func _get_input_port_count() -> int:
return 1
@@ -20,7 +29,16 @@ func _get_input_port_name(port: int) -> String:
return "in"
func _get_input_port_type(port: int) -> VisualShaderNode.PortType:
- return PORT_TYPE_VECTOR_4D
+ var vector_index: int = get_option_index(0)
+ match vector_index:
+ 0:
+ return PORT_TYPE_SCALAR
+ 1:
+ return PORT_TYPE_VECTOR_2D
+ 2:
+ return PORT_TYPE_VECTOR_3D
+ _:
+ return PORT_TYPE_VECTOR_4D
func _get_output_port_count() -> int:
return 1
@@ -29,10 +47,43 @@ func _get_output_port_name(port: int) -> String:
return "out"
func _get_output_port_type(port: int) -> VisualShaderNode.PortType:
- return PORT_TYPE_VECTOR_4D
+ var vector_index: int = get_option_index(0)
+ match vector_index:
+ 0:
+ return PORT_TYPE_SCALAR
+ 1:
+ return PORT_TYPE_VECTOR_2D
+ 2:
+ return PORT_TYPE_VECTOR_3D
+ _:
+ return PORT_TYPE_VECTOR_4D
+
+func _get_property_count() -> int:
+ return 1
+
+func _get_property_default_index(index: int) -> int:
+ return 0
+
+func _get_property_name(index: int) -> String:
+ return ""
+
+func _get_property_options(index: int) -> PackedStringArray:
+ return ["Vector1", "Vector2", "Vector3", "Vector4"]
func _get_code(input_vars: Array[String], output_vars: Array[String], mode: Shader.Mode, type: VisualShader.Type) -> String:
- var input: String = "vec4(0.0)"
+ var input: String
+ var vector_index: int = get_option_index(0)
+ match vector_index:
+ 0:
+ input = "0.0"
+ 1:
+ input = "vec2(0.0)"
+ 2:
+ input = "vec3(0.0)"
+ _:
+ input = "vec4(0.0)"
+
if input_vars[0]:
input = input_vars[0]
+
return output_vars[0] + " = 2.0 * (%s - floor(0.5 + %s));" % [input, input]
diff --git a/addons/ShaderLib/Maths/Wave/SquareWave.gd b/addons/ShaderLib/Maths/Wave/SquareWave.gd
index b359f1f..3d6e2f4 100644
--- a/addons/ShaderLib/Maths/Wave/SquareWave.gd
+++ b/addons/ShaderLib/Maths/Wave/SquareWave.gd
@@ -12,7 +12,16 @@ func _get_description() -> String:
return "Returns a square wave from the value of input in. Resulting output values will be between -1 and 1."
func _get_return_icon_type() -> VisualShaderNode.PortType:
- return PORT_TYPE_VECTOR_4D
+ var vector_index: int = get_option_index(0)
+ match vector_index:
+ 0:
+ return PORT_TYPE_SCALAR
+ 1:
+ return PORT_TYPE_VECTOR_2D
+ 2:
+ return PORT_TYPE_VECTOR_3D
+ _:
+ return PORT_TYPE_VECTOR_4D
func _get_input_port_count() -> int:
return 1
@@ -21,7 +30,16 @@ func _get_input_port_name(port: int) -> String:
return "input"
func _get_input_port_type(port: int) -> VisualShaderNode.PortType:
- return PORT_TYPE_VECTOR_4D
+ var vector_index: int = get_option_index(0)
+ match vector_index:
+ 0:
+ return PORT_TYPE_SCALAR
+ 1:
+ return PORT_TYPE_VECTOR_2D
+ 2:
+ return PORT_TYPE_VECTOR_3D
+ _:
+ return PORT_TYPE_VECTOR_4D
func _get_output_port_count() -> int:
return 1
@@ -30,10 +48,43 @@ func _get_output_port_name(port: int) -> String:
return "out"
func _get_output_port_type(port: int) -> VisualShaderNode.PortType:
- return PORT_TYPE_VECTOR_4D
+ var vector_index: int = get_option_index(0)
+ match vector_index:
+ 0:
+ return PORT_TYPE_SCALAR
+ 1:
+ return PORT_TYPE_VECTOR_2D
+ 2:
+ return PORT_TYPE_VECTOR_3D
+ _:
+ return PORT_TYPE_VECTOR_4D
+
+func _get_property_count() -> int:
+ return 1
+
+func _get_property_default_index(index: int) -> int:
+ return 0
+
+func _get_property_name(index: int) -> String:
+ return ""
+
+func _get_property_options(index: int) -> PackedStringArray:
+ return ["Vector1", "Vector2", "Vector3", "Vector4"]
func _get_code(input_vars: Array[String], output_vars: Array[String], mode: Shader.Mode, type: VisualShader.Type) -> String:
- var input: String = "vec4(0.0)"
+ var input: String
+ var vector_index: int = get_option_index(0)
+ match vector_index:
+ 0:
+ input = "0.0"
+ 1:
+ input = "vec2(0.0)"
+ 2:
+ input = "vec3(0.0)"
+ _:
+ input = "vec4(0.0)"
+
if input_vars[0]:
input = input_vars[0]
+
return output_vars[0] + " = 1.0 - 2.0 * round(fract(%s));" % [input]
diff --git a/addons/ShaderLib/Maths/Wave/TriangleWave.gd b/addons/ShaderLib/Maths/Wave/TriangleWave.gd
index edec1b7..07d3d3e 100644
--- a/addons/ShaderLib/Maths/Wave/TriangleWave.gd
+++ b/addons/ShaderLib/Maths/Wave/TriangleWave.gd
@@ -11,7 +11,16 @@ func _get_description() -> String:
return "Returns a triangle wave from the value of input in. Resulting output values will be between -1 and 1."
func _get_return_icon_type() -> VisualShaderNode.PortType:
- return PORT_TYPE_VECTOR_4D
+ var vector_index: int = get_option_index(0)
+ match vector_index:
+ 0:
+ return PORT_TYPE_SCALAR
+ 1:
+ return PORT_TYPE_VECTOR_2D
+ 2:
+ return PORT_TYPE_VECTOR_3D
+ _:
+ return PORT_TYPE_VECTOR_4D
func _get_input_port_count() -> int:
return 1
@@ -19,7 +28,16 @@ func _get_input_port_count() -> int:
func _get_input_port_name(port: int) -> String:
return "in"
func _get_input_port_type(port: int) -> VisualShaderNode.PortType:
- return PORT_TYPE_VECTOR_4D
+ var vector_index: int = get_option_index(0)
+ match vector_index:
+ 0:
+ return PORT_TYPE_SCALAR
+ 1:
+ return PORT_TYPE_VECTOR_2D
+ 2:
+ return PORT_TYPE_VECTOR_3D
+ _:
+ return PORT_TYPE_VECTOR_4D
func _get_output_port_count() -> int:
return 1
@@ -28,10 +46,43 @@ func _get_output_port_name(port: int) -> String:
return "out"
func _get_output_port_type(port: int) -> VisualShaderNode.PortType:
- return PORT_TYPE_VECTOR_4D
+ var vector_index: int = get_option_index(0)
+ match vector_index:
+ 0:
+ return PORT_TYPE_SCALAR
+ 1:
+ return PORT_TYPE_VECTOR_2D
+ 2:
+ return PORT_TYPE_VECTOR_3D
+ _:
+ return PORT_TYPE_VECTOR_4D
+
+func _get_property_count() -> int:
+ return 1
+
+func _get_property_default_index(index: int) -> int:
+ return 0
+
+func _get_property_name(index: int) -> String:
+ return ""
+
+func _get_property_options(index: int) -> PackedStringArray:
+ return ["Vector1", "Vector2", "Vector3", "Vector4"]
func _get_code(input_vars: Array[String], output_vars: Array[String], mode: Shader.Mode, type: VisualShader.Type) -> String:
- var input: String = "vec4(0.0)"
+ var input: String
+ var vector_index: int = get_option_index(0)
+ match vector_index:
+ 0:
+ input = "0.0"
+ 1:
+ input = "vec2(0.0)"
+ 2:
+ input = "vec3(0.0)"
+ _:
+ input = "vec4(0.0)"
+
if input_vars[0]:
input = input_vars[0]
+
return output_vars[0] + " = 2.0 * abs(2.0 * (%s - floor(0.5 + %s))) - 1.0;" % [input, input]
diff --git a/addons/ShaderLib/Procedural/Fractals/KochFractal.gd b/addons/ShaderLib/Procedural/Fractals/KochFractal.gd
new file mode 100644
index 0000000..cf60fd6
--- /dev/null
+++ b/addons/ShaderLib/Procedural/Fractals/KochFractal.gd
@@ -0,0 +1,86 @@
+@tool
+class_name VisualShaderNodeProceduralKochFractal extends VisualShaderNodeCustom
+
+func _init() -> void:
+ output_port_for_preview = 0
+
+func _get_name() -> String:
+ return "KochFractal"
+
+func _get_category() -> String:
+ return "Procedural/Fractals"
+
+func _get_description() -> String:
+ return "Generates an koch curve similar to ice fractal shape based on input UV at the size specified by inputs width and height."
+
+func _get_return_icon_type() -> PortType:
+ return PORT_TYPE_SCALAR
+
+func _get_input_port_count() -> int:
+ return 5
+
+func _get_input_port_name(port: int) -> String:
+ match port:
+ 0:
+ return "uv"
+ 1:
+ return "thickness"
+ 2:
+ return "iterations"
+ 3:
+ return "widht"
+ _:
+ return "height"
+
+func _get_input_port_type(port: int) -> PortType:
+ match port:
+ 0:
+ return PORT_TYPE_VECTOR_2D
+ 2:
+ return PORT_TYPE_SCALAR_INT
+ _:
+ return PORT_TYPE_SCALAR
+
+func _get_input_port_default_value(port: int) -> Variant:
+ match port:
+ 1, 3, 4:
+ return 1.0
+ 2:
+ return 3
+ _:
+ return null
+
+func _get_output_port_count() -> int:
+ return 2
+
+func _get_output_port_name(port: int) -> String:
+ match port:
+ 0:
+ return "out"
+ _:
+ return "uv"
+
+func _get_output_port_type(port: int) -> PortType:
+ match port:
+ 1:
+ return PORT_TYPE_VECTOR_2D
+ _:
+ return PORT_TYPE_SCALAR
+
+func _get_global_code(mode: Shader.Mode) -> String:
+ var code: String = preload("KochFractal.gdshaderinc").code
+ return code
+
+func _get_code(input_vars: Array[String], output_vars: Array[String], mode: Shader.Mode, type: VisualShader.Type) -> String:
+ var uv: String = "UV"
+
+ if input_vars[0]:
+ uv = input_vars[0]
+
+ var thickness: String = input_vars[1]
+ var iterations: String = input_vars[2]
+ var width: String = input_vars[3]
+ var height: String = input_vars[4]
+
+ return output_vars[0] + " = koch_fractal(%s, %s, %s, %s, %s, %s);" % [uv, thickness, iterations, width, height, output_vars[1]]
+
diff --git a/addons/ShaderLib/Procedural/Fractals/KochFractal.gdshaderinc b/addons/ShaderLib/Procedural/Fractals/KochFractal.gdshaderinc
new file mode 100644
index 0000000..b04485f
--- /dev/null
+++ b/addons/ShaderLib/Procedural/Fractals/KochFractal.gdshaderinc
@@ -0,0 +1,36 @@
+vec2 koch_fractal_direction(float angle){
+ return vec2(sin(angle), cos(angle));
+}
+
+float koch_fractal(vec2 uv, float outline, int iteration, float shape_width, float shape_height, out vec2 koch_uv) {
+ float tiling = 3.0;
+ vec2 center = uv - vec2(.5);
+ shape_width = .85 * (shape_width / 1.);
+ shape_height = .85 * (shape_height / 1.);
+ center.x /= shape_width;
+ center.y /= shape_height;
+
+ center.x = abs(center.x);
+ center.y += tan(.833 * PI) * .5;
+ vec2 dir = koch_fractal_direction(.833 * PI);
+ float dist = dot(center - vec2(tiling / (2. * tiling), 0), dir);
+ center -= dir * max(0, dist) * 2.0;
+
+ dir = koch_fractal_direction(.6667 * PI);
+ float scale = 1.0;
+ center.x += .5;
+ for(int i = 0; i < iteration; i++){
+ center *= tiling;
+ scale *= tiling;
+ center.x -= .5 * tiling;
+
+ center.x = abs(center.x);
+ center.x -= .5;
+ center -= dir * min(0.0, dot(center, dir)) * 2.0;
+ }
+
+ dist = length(center - vec2(clamp(center.x, -1.0, 1.0), 0));
+ dist += step(outline / 100.0, dist / scale);
+ koch_uv = abs(center);
+ return 1.0 - dist;
+}
\ No newline at end of file
diff --git a/documentation/Documentation.md b/documentation/Documentation.md
index 0288f1c..79cdab8 100644
--- a/documentation/Documentation.md
+++ b/documentation/Documentation.md
@@ -5,59 +5,69 @@ If you don't immediatly see new nodes under **_Addons_** category, simply reload
# Uninstallation
Delete the contents of **_addons/ShaderLib_** folder from your project. Make sure to delete it using the Godot editor instead of your default file system program.
# Available Nodes
-
-
-
-
-UV nodes
-Flipbook node
-Parallax Mapping node
-Radial Shear node
-Rotate node
-Spherize node
-Swirl node
-Tiling and Offset node
-Twirl node
-
-