From b2ba78fa433d9f7b9d6b66a3395ab028e3f9373f Mon Sep 17 00:00:00 2001 From: Digvijaysinh Gohil Date: Mon, 11 Mar 2024 12:11:57 +0530 Subject: [PATCH] Koch Fractal node added --- .../Procedural/Shapes/KochFractal.gd | 86 +++++++++++++++++++ .../Procedural/Shapes/KochFractal.gdshaderinc | 36 ++++++++ documentation/Documentation.md | 1 + .../Nodes/Procedural/Shapes/KochFractal.md | 18 ++++ 4 files changed, 141 insertions(+) create mode 100644 addons/ShaderLib/Procedural/Shapes/KochFractal.gd create mode 100644 addons/ShaderLib/Procedural/Shapes/KochFractal.gdshaderinc create mode 100644 documentation/Nodes/Procedural/Shapes/KochFractal.md 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

 Shapes

  Ellipse node

+

  Koch Fractal node

  Polygon node

  Rectangle node

  Rounded Polygon node

diff --git a/documentation/Nodes/Procedural/Shapes/KochFractal.md b/documentation/Nodes/Procedural/Shapes/KochFractal.md new file mode 100644 index 0000000..c9c0f3c --- /dev/null +++ b/documentation/Nodes/Procedural/Shapes/KochFractal.md @@ -0,0 +1,18 @@ +# Ellipse node +Generates an koch curve similar to ice fractal shape based on input UV at the size specified by inputs width and height. The generated shape can be offset or tiled by connecting a [TilingAndOffset](/documentation/Nodes/UV/TilingAndOffset.md) node. Note that in order to preserve the ability to offset the shape within the UV space the shape will not automatically repeat if tiled. To achieve a repeating effect first connect your TilingAndOffset output through a Fract node. +
+ +**Inputs** +|Name|Type|Binding|Description| +|---|---|---|---| +|uv|vec2|UV|Input UV value| +|thickness|float|none|Shape outline thickness| +|iterations|int|none|Number of steps to repeat the fractal shape| +|width|float|none|Fractal width| +|height|float|none|Fractal height| + +**Outputs** +|Name|Type|Binding|Description| +|---|---|---|---| +|output|float|None|Output ellipse value| +___ \ No newline at end of file