diff --git a/addons/ShaderLib/Procedural/Noise/GradientNoise.gd b/addons/ShaderLib/Procedural/Noise/GradientNoise.gd new file mode 100644 index 0000000..76dc34b --- /dev/null +++ b/addons/ShaderLib/Procedural/Noise/GradientNoise.gd @@ -0,0 +1,60 @@ +@tool +class_name VisualShaderNodeProceduralGradientNoise extends VisualShaderNodeCustom + +func _init() -> void: + set_input_port_default_value(1, 10.0) + + output_port_for_preview = 0 + +func _get_name() -> String: + return "GradientNoise" + +func _get_category() -> String: + return "Procedural/Noise" + +func _get_description() -> String: + return "Generates a gradient, or Perlin, noise based on input UV." + +func _get_return_icon_type() -> VisualShaderNode.PortType: + return PORT_TYPE_SCALAR + +func _get_input_port_count() -> int: + return 2 + +func _get_input_port_name(port: int) -> String: + match port: + 0: + return "uv" + 1: + return "scale" + return "" + +func _get_input_port_type(port: int) -> VisualShaderNode.PortType: + match port: + 0: + return PORT_TYPE_VECTOR_2D + 1: + return PORT_TYPE_SCALAR + return PORT_TYPE_SCALAR + +func _get_output_port_count() -> int: + return 1 + +func _get_output_port_name(port: int) -> String: + return "output" + +func _get_output_port_type(port: int) -> VisualShaderNode.PortType: + return PORT_TYPE_SCALAR + +func _get_global_code(mode: Shader.Mode) -> String: + var code: String = preload("GradientNoise.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 scale: String = input_vars[1] + return output_vars[0] + " = gradient_noise(%s, %s);" % [uv, scale] diff --git a/addons/ShaderLib/Procedural/Noise/GradientNoise.gdshaderinc b/addons/ShaderLib/Procedural/Noise/GradientNoise.gdshaderinc new file mode 100644 index 0000000..ab52472 --- /dev/null +++ b/addons/ShaderLib/Procedural/Noise/GradientNoise.gdshaderinc @@ -0,0 +1,19 @@ +vec2 gradient_noise_dir(vec2 p){ + p = vec2(mod(p.x,289.0), mod(p.y, 289.0)); + float x = (34.0 * p.x + 1.0) * mod(p.x, 289.0) + p.y; + x = (34.0 * x + 1.0) * mod(x, 289.0); + x = fract(x / 41.0) * 2.0 - 1.0; + return normalize(vec2(x - floor(x + 0.5), abs(x) - 0.5)); +} + +float gradient_noise(vec2 uv, float scale){ + vec2 p = uv * scale; + vec2 ip = floor(p); + vec2 fp = fract(p); + float d00 = dot(gradient_noise_dir(ip), fp); + float d01 = dot(gradient_noise_dir(ip + vec2(0, 1)), fp - vec2(0, 1)); + float d10 = dot(gradient_noise_dir(ip + vec2(1, 0)), fp - vec2(1, 0)); + float d11 = dot(gradient_noise_dir(ip + vec2(1, 1)), fp - vec2(1, 1)); + fp = fp * fp * fp * (fp * (fp * 6.0 - 15.0) + 10.0); + return mix(mix(d00, d01, fp.y), mix(d10, d11, fp.y), fp.x) + 0.5; +} \ No newline at end of file diff --git a/addons/ShaderLib/Procedural/Noise/SimpleNoise.gd b/addons/ShaderLib/Procedural/Noise/SimpleNoise.gd new file mode 100644 index 0000000..6150723 --- /dev/null +++ b/addons/ShaderLib/Procedural/Noise/SimpleNoise.gd @@ -0,0 +1,61 @@ +@tool +class_name VisualShaderNodeProceduralSimpleNoise extends VisualShaderNodeCustom + +func _init() -> void: + set_input_port_default_value(1, 10.0) + + output_port_for_preview = 0 + +func _get_name() -> String: + return "SimpleNoise" + +func _get_category() -> String: + return "Procedural/Noise" + +func _get_description() -> String: + return "Generates a simple, or Value, noise based on input UV." + +func _get_return_icon_type() -> VisualShaderNode.PortType: + return PORT_TYPE_SCALAR + +func _get_input_port_count() -> int: + return 2 + +func _get_input_port_name(port: int) -> String: + match port: + 0: + return "uv" + 1: + return "scale" + return "" + +func _get_input_port_type(port: int) -> VisualShaderNode.PortType: + match port: + 0: + return PORT_TYPE_VECTOR_2D + 1: + return PORT_TYPE_SCALAR + return PORT_TYPE_SCALAR + +func _get_output_port_count() -> int: + return 1 + +func _get_output_port_name(port: int) -> String: + return "output" + +func _get_output_port_type(port: int) -> VisualShaderNode.PortType: + return PORT_TYPE_SCALAR + +func _get_global_code(mode: Shader.Mode) -> String: + var code: String = preload("SimpleNoise.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 scale: String = input_vars[1] + + return output_vars[0] + " = simple_noise(%s, %s);" % [uv, scale] diff --git a/addons/ShaderLib/Procedural/Noise/SimpleNoise.gdshaderinc b/addons/ShaderLib/Procedural/Noise/SimpleNoise.gdshaderinc new file mode 100644 index 0000000..5bda2a7 --- /dev/null +++ b/addons/ShaderLib/Procedural/Noise/SimpleNoise.gdshaderinc @@ -0,0 +1,47 @@ +float noise_random_value(vec2 uv){ + return fract(sin(dot(uv, vec2(12.9898, 78.233))) * 43758.5453); +} + +float noise_interpolate(float a, float b, float t){ + return (1.0 - t) * a + (t * b); +} + +float value_noise(vec2 uv){ + vec2 i = floor(uv); + vec2 f = fract(uv); + f = f * f * (3.0 - 2.0 * f); + uv = abs(fract(uv) - 0.5); + + vec2 c0 = i + vec2(0.0, 0.0); + vec2 c1 = i + vec2(1.0, 0.0); + vec2 c2 = i + vec2(0.0, 1.0); + vec2 c3 = i + vec2(1.0, 1.0); + + float r0 = noise_random_value(c0); + float r1 = noise_random_value(c1); + float r2 = noise_random_value(c2); + float r3 = noise_random_value(c3); + + float bottom_of_grid = noise_interpolate(r0, r1, f.x); + float top_of_grid = noise_interpolate(r2, r3, f.x); + float t = noise_interpolate(bottom_of_grid, top_of_grid, f.y); + + return t; +} + +float simple_noise(vec2 uv, float scale){ + float t = 0.0; + float freq = pow(2.0, float(0)); + float amp = pow(0.5, float(3-0)); + + t += value_noise(vec2(uv.x * scale / freq, uv.y * scale / freq)) * amp; + freq = pow(2.0, float(1)); + amp = pow(0.5, float(3-1)); + + t += value_noise(vec2(uv.x * scale / freq, uv.y * scale / freq)) * amp; + freq = pow(2.0, float(2)); + amp = pow(0.5, float(3-2)); + + t += value_noise(vec2(uv.x * scale / freq, uv.y * scale / freq)) * amp; + return t; +} \ No newline at end of file