diff --git a/addons/ShaderLib/Procedural/Shapes/KochFractal.gd b/addons/ShaderLib/Procedural/Shapes/KochFractal.gd new file mode 100644 index 0000000..d2bde24 --- /dev/null +++ b/addons/ShaderLib/Procedural/Shapes/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/Shapes" + +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/Shapes/KochFractal.gdshaderinc b/addons/ShaderLib/Procedural/Shapes/KochFractal.gdshaderinc new file mode 100644 index 0000000..a5ad2a7 --- /dev/null +++ b/addons/ShaderLib/Procedural/Shapes/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 = center; + return 1.0 - dist; +} \ No newline at end of file diff --git a/documentation/Documentation.md b/documentation/Documentation.md index db68049..b147533 100644 --- a/documentation/Documentation.md +++ b/documentation/Documentation.md @@ -38,6 +38,7 @@ Delete the contents of **_addons/ShaderLib_** folder from your project. Make sur