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