From f06a680212c84f6ebbea4e00557d53a5ce3515f6 Mon Sep 17 00:00:00 2001 From: Digvijaysinh Gohil Date: Mon, 18 Mar 2024 22:45:48 +0530 Subject: [PATCH 01/20] Update VectorTransform.gdshaderinc --- .../Maths/Vector/VectorTransform.gdshaderinc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/addons/ShaderLib/Maths/Vector/VectorTransform.gdshaderinc b/addons/ShaderLib/Maths/Vector/VectorTransform.gdshaderinc index d6f7b52..32eebf1 100644 --- a/addons/ShaderLib/Maths/Vector/VectorTransform.gdshaderinc +++ b/addons/ShaderLib/Maths/Vector/VectorTransform.gdshaderinc @@ -1,14 +1,14 @@ vec3 vector_transform_world_to_local(mat4 model_matrix, vec3 vector){ - return (transpose(model_matrix) * vec4(vector, 0.0)).xyz; + return (transpose(model_matrix) * vec4(vector, 1.0)).xyz; } vec3 vector_transform_world_to_view(mat4 view_matrix, vec3 vector){ - return (view_matrix * vec4(vector, 0.0)).xyz; + return (view_matrix * vec4(vector, 1.0)).xyz; } vec3 vector_transform_world_to_screen(mat4 view_matrix, mat4 projection_matrix, vec3 vector){ vec3 vector_view = vector_transform_world_to_view(view_matrix, vector); - return (projection_matrix * vec4(vector_view, 0.0)).xyz; + return (projection_matrix * vec4(vector_view, 1.0)).xyz; } vec3 vector_transform_world_to_tangent(mat4 model_matrix, vec3 normal, vec3 binormal, vec3 tangent, vec3 vector){ @@ -18,17 +18,17 @@ vec3 vector_transform_world_to_tangent(mat4 model_matrix, vec3 normal, vec3 bino } vec3 vector_transform_local_to_world(mat4 model_matrix, vec3 vector){ - return (model_matrix * vec4(vector, 0.0)).xyz; + return (model_matrix * vec4(vector, 1.0)).xyz; } vec3 vector_transform_local_to_view(mat4 model_matrix, mat4 view_matrix, vec3 vector){ vec3 vector_world = vector_transform_local_to_world(model_matrix, vector); - return (view_matrix * vec4(vector_world, 0.0)).xyz; + return (view_matrix * vec4(vector_world, 1.0)).xyz; } vec3 vector_transform_local_to_screen(mat4 model_matrix, mat4 view_matrix, mat4 projection_matrix, vec3 vector){ vec3 vector_view = vector_transform_local_to_view(model_matrix, view_matrix, vector); - return (projection_matrix * vec4(vector_view, 0.0)).xyz; + return (projection_matrix * vec4(vector_view, 1.0)).xyz; } vec3 vector_transform_local_to_tangent(vec3 normal, vec3 binormal, vec3 tangent, vec3 vector){ @@ -37,7 +37,7 @@ vec3 vector_transform_local_to_tangent(vec3 normal, vec3 binormal, vec3 tangent, } vec3 vector_transform_view_to_world(mat4 inv_view_matrix, vec3 vector){ - return (inv_view_matrix * vec4(vector, 0.0)).xyz;; + return (inv_view_matrix * vec4(vector, 1.0)).xyz;; } vec3 vector_transform_view_to_local(mat4 inv_view_matrix, mat4 model_matrix, vec3 vector){ @@ -46,7 +46,7 @@ vec3 vector_transform_view_to_local(mat4 inv_view_matrix, mat4 model_matrix, vec } vec3 vector_transform_view_to_screen(mat4 projection_matrix, vec3 vector){ - return (projection_matrix * vec4(vector, 0.0)).xyz; + return (projection_matrix * vec4(vector, 1.0)).xyz; } vec3 vector_transform_view_to_tangent(mat4 inv_view_matrix, mat4 model_matrix, vec3 normal, vec3 binormal, vec3 tangent, vec3 vector){ @@ -56,7 +56,7 @@ vec3 vector_transform_view_to_tangent(mat4 inv_view_matrix, mat4 model_matrix, v } vec3 vector_transform_screen_to_view(mat4 inv_projection_matrix, vec3 vector){ - return (inv_projection_matrix * vec4(vector, 0.0)).xyz;; + return (inv_projection_matrix * vec4(vector, 1.0)).xyz;; } vec3 vector_transform_screen_to_local(mat4 inv_projection_matrix, mat4 inv_view_matrix, mat4 model_matrix, vec3 vector){ From 600079e3e5b4891411de5bec85ff7a7fc405ed25 Mon Sep 17 00:00:00 2001 From: Digvijaysinh Gohil Date: Tue, 19 Mar 2024 13:03:56 +0530 Subject: [PATCH 02/20] Voronoi node revamped --- addons/ShaderLib/Procedural/Noise/Voronoi.gd | 84 +++++++++++++++---- .../Procedural/Noise/Voronoi.gdshaderinc | 70 +++++++++++----- .../Nodes/Procedural/Noise/Voronoi.md | 6 ++ 3 files changed, 122 insertions(+), 38 deletions(-) diff --git a/addons/ShaderLib/Procedural/Noise/Voronoi.gd b/addons/ShaderLib/Procedural/Noise/Voronoi.gd index 4a139da..303df43 100644 --- a/addons/ShaderLib/Procedural/Noise/Voronoi.gd +++ b/addons/ShaderLib/Procedural/Noise/Voronoi.gd @@ -17,34 +17,63 @@ func _get_return_icon_type() -> VisualShaderNode.PortType: return PORT_TYPE_SCALAR func _get_input_port_count() -> int: - return 3 + var distance_index: int = get_option_index(0) + match distance_index: + 2: + return 4 + _: + return 3 func _get_input_port_name(port: int) -> String: - match port: - 0: - return "uv" - 1: - return "cell density" + var distance_index: int = get_option_index(0) + match distance_index: 2: - return "angle offset" - return "" + match port: + 0: + return "uv" + 1: + return "cell density" + 2: + return "angle offset" + _: + return "chebyshev power" + _: + match port: + 0: + return "uv" + 1: + return "cell density" + _: + return "angle offset" func _get_input_port_type(port: int) -> VisualShaderNode.PortType: match port: 0: return PORT_TYPE_VECTOR_2D - 1, 2: + _: return PORT_TYPE_SCALAR - return PORT_TYPE_SCALAR func _get_input_port_default_value(port: int) -> Variant: - match port: - 1: - return 5.0 + var distance_index: int = get_option_index(0) + match distance_index: 2: - return 2.0 + match port: + 1: + return 5.0 + 2: + return 2.0 + 3: + return 2.0 + _: + return null _: - return null + match port: + 1: + return 5.0 + 2: + return 2.0 + _: + return null func _get_output_port_count() -> int: return 2 @@ -53,13 +82,24 @@ func _get_output_port_name(port: int) -> String: match port: 0: return "output" - 1: + _: return "cells" - return "" func _get_output_port_type(port: int) -> VisualShaderNode.PortType: return PORT_TYPE_SCALAR +func _get_property_count() -> int: + return 1 + +func _get_property_name(index: int) -> String: + return "Distance" + +func _get_property_default_index(index: int) -> int: + return 0 + +func _get_property_options(index: int) -> PackedStringArray: + return ["Euclidean", "Manhattan", "Chebyshev"] + func _get_global_code(mode: Shader.Mode) -> String: var code: String = preload("Voronoi.gdshaderinc").code return code @@ -70,9 +110,17 @@ func _get_code(input_vars: Array[String], output_vars: Array[String], mode: Shad if input_vars[0]: uv = input_vars[0] + var distance_index: int = get_option_index(0) + var cell_density: String = input_vars[1] var angle_offset: String = input_vars[2] + var chebyshev_power: String = "0." + + if distance_index == 2: + if input_vars[3]: + chebyshev_power = input_vars[3] + var output: String = output_vars[0] var cells: String = output_vars[1] - return "voronoi_noise(%s,%s, %s, %s, %s);" % [uv, cell_density, angle_offset, output, cells] + return "voronoi_noise(%s, %s, %s, %s, %s, %s, %s);" % [uv, cell_density, angle_offset, distance_index, chebyshev_power, output, cells] diff --git a/addons/ShaderLib/Procedural/Noise/Voronoi.gdshaderinc b/addons/ShaderLib/Procedural/Noise/Voronoi.gdshaderinc index 36213c8..2a2c046 100644 --- a/addons/ShaderLib/Procedural/Noise/Voronoi.gdshaderinc +++ b/addons/ShaderLib/Procedural/Noise/Voronoi.gdshaderinc @@ -1,24 +1,54 @@ -void voronoi_noise(vec2 uv, float cell_density, float angle_offset, out float output, out float cells){ - vec2 _g = floor(uv * cell_density); - vec2 _f = fract(uv * cell_density); - vec3 _res = vec3(8.0, 0.0, 0.0); - mat2 _matrix = mat2(vec2(15.27, 47.63), vec2(99.41, 89.98)); - - for(int y=-1; y<=1; y++) - { - for(int x=-1; x<=1; x++) - { - vec2 lattice = vec2(float(x), float(y)); - vec2 new_uv = lattice + _g; - new_uv = fract(sin(new_uv * _matrix) * 46839.32); - vec2 offset = vec2(sin(new_uv.y * angle_offset) * 0.5 + 0.5, cos(new_uv.x * angle_offset) * 0.5 + 0.5); - float d = distance(lattice + offset, _f); - if(d < _res.x) - { - _res = vec3(d, offset.x, offset.y); - output = _res.x; - cells = _res.y; +vec2 voronoi_random_vector(vec2 p) { + mat2 matrix = mat2(vec2(15.27, 47.63), vec2(99.41, 89.98)); + return fract(sin(p * matrix) * 46839.32); +} + +float voronoi_euclidean_distance(vec2 point1, vec2 point2){ + return distance(point1, point2); +} + +float voronoi_manhattan_distance(vec2 point1, vec2 point2) { + vec2 d = point1 - point2; + return abs(d.x) + abs(d.y); +} + +float voronoi_chebyshev_distance(vec2 point1, vec2 point2, float power) { + vec2 p = point1 - point2; + return pow(pow(p.x, power) + pow(p.y, power), 1. / power); +} + +void voronoi_noise(vec2 uv, float cell_density, float angle_offset, int distance_index, float chebyshev_power, out float output, out float cells){ + vec2 grid_uv = fract(uv * cell_density); + vec2 grid_id = floor(uv * cell_density); + vec2 cell_id = vec2(0); + float min_dist = 100.; + + for(float y = -1.; y <= 1.; y++) { + for(float x = -1.; x <= 1.; x++) { + vec2 offset = vec2(x, y); + vec2 n = voronoi_random_vector(grid_id + offset); + vec2 p = offset + sin(n + angle_offset) * .5 + .5; + float d = min_dist; + + switch(distance_index){ + case 1: + d = voronoi_manhattan_distance(grid_uv, p); + break; + case 2: + d = voronoi_chebyshev_distance(grid_uv, p, chebyshev_power); + break; + default: + d = voronoi_euclidean_distance(grid_uv, p); + break; + } + + if(d < min_dist) { + min_dist = d; + cell_id = voronoi_random_vector(grid_id + offset); } } } + + output = min_dist; + cells = cell_id.y; } \ No newline at end of file diff --git a/documentation/Nodes/Procedural/Noise/Voronoi.md b/documentation/Nodes/Procedural/Noise/Voronoi.md index 4eb6da7..19f438e 100644 --- a/documentation/Nodes/Procedural/Noise/Voronoi.md +++ b/documentation/Nodes/Procedural/Noise/Voronoi.md @@ -2,12 +2,18 @@ Generates a Voronoi or Worley noise based on input UV. Voronoi noise is generated by calculating distances between a pixel and a lattice of points. By offsetting these points by a pseudo-random number, controlled by angle offset, a cluster of cells can be generated.
+**Controls** +|Name|Options|Description| +|---|---|---| +|Distance|Euclidean, Manhattan, Chebyshev|Distance matrix used to calculate the noise| + **Inputs** |Name|Type|Binding|Description| |---|---|---|---| |uv|vec2|UV|Input UV value| |cell density|float|none|Density of generated cells| |angle offset|float|none|Offset values for points| +|chebyshev power|float|none|Power values for Chebyshev distance matrix| **Outputs** |Name|Type|Binding|Description| From de8d5e472e1dd2e0741d727925d0bc9a6fc6f68a Mon Sep 17 00:00:00 2001 From: Digvijaysinh Gohil Date: Tue, 19 Mar 2024 18:22:06 +0530 Subject: [PATCH 03/20] Simple noise node revamped --- .../ShaderLib/Procedural/Noise/SimpleNoise.gd | 15 ++++-- .../Procedural/Noise/SimpleNoise.gdshaderinc | 47 ++++++++++--------- .../Nodes/Procedural/Noise/SimpleNoise.md | 1 + 3 files changed, 36 insertions(+), 27 deletions(-) diff --git a/addons/ShaderLib/Procedural/Noise/SimpleNoise.gd b/addons/ShaderLib/Procedural/Noise/SimpleNoise.gd index 86dbaa0..d825e03 100644 --- a/addons/ShaderLib/Procedural/Noise/SimpleNoise.gd +++ b/addons/ShaderLib/Procedural/Noise/SimpleNoise.gd @@ -17,7 +17,7 @@ func _get_return_icon_type() -> VisualShaderNode.PortType: return PORT_TYPE_SCALAR func _get_input_port_count() -> int: - return 2 + return 3 func _get_input_port_name(port: int) -> String: match port: @@ -25,7 +25,8 @@ func _get_input_port_name(port: int) -> String: return "uv" 1: return "scale" - return "" + _: + return "octaves" func _get_input_port_type(port: int) -> VisualShaderNode.PortType: match port: @@ -33,15 +34,20 @@ func _get_input_port_type(port: int) -> VisualShaderNode.PortType: return PORT_TYPE_VECTOR_2D 1: return PORT_TYPE_SCALAR - return PORT_TYPE_SCALAR + _: + return PORT_TYPE_SCALAR_INT func _get_input_port_default_value(port: int) -> Variant: match port: 1: return 10.0 + 2: + return 6 _: return null +func _get_default_input_port(type: PortType) -> int: + func _get_output_port_count() -> int: return 1 @@ -62,5 +68,6 @@ func _get_code(input_vars: Array[String], output_vars: Array[String], mode: Shad uv = input_vars[0] var scale: String = input_vars[1] + var octaves: String = input_vars[2] - return output_vars[0] + " = simple_noise(%s, %s);" % [uv, scale] + return output_vars[0] + " = simple_noise(%s, %s, %s);" % [uv, scale, octaves] diff --git a/addons/ShaderLib/Procedural/Noise/SimpleNoise.gdshaderinc b/addons/ShaderLib/Procedural/Noise/SimpleNoise.gdshaderinc index 14e30db..31c1f3e 100644 --- a/addons/ShaderLib/Procedural/Noise/SimpleNoise.gdshaderinc +++ b/addons/ShaderLib/Procedural/Noise/SimpleNoise.gdshaderinc @@ -1,32 +1,33 @@ -float noise_random_value(vec2 uv){ - return fract(sin(dot(uv.xy, vec2(12.9898,78.233))) * 43758.5453123); +float simple_noise_random(vec2 point) { + return fract(sin(point.x * 100. + point.y * 654.125) * 55647.8745); } -float value_noise(vec2 uv){ - vec2 _floor = floor(uv); - vec2 _fraction = fract(uv); - _fraction = _fraction * _fraction * (3.0 - 2.0 * _fraction); - vec2 _corner = vec2(1.0, 0.0); +float value_noise(vec2 uv) { + vec2 grid_uv = fract(uv); + vec2 grid_id = floor(uv); + grid_uv = grid_uv * grid_uv * (3. - 2. * grid_uv); - float _c0 = noise_random_value(_floor + _corner.yy); - float _c1 = noise_random_value(_floor + _corner.xy); - float _c2 = noise_random_value(_floor + _corner.yx); - float _c3 = noise_random_value(_floor + _corner.xx); + float bottom_left = simple_noise_random(grid_id); + float bottom_right = simple_noise_random(grid_id + vec2(1, 0)); + float bottom = mix(bottom_left, bottom_right, grid_uv.x); - vec2 _blur = smoothstep(0.0, 1.0, _fraction); - float mix_one = mix(_c0, _c1, _blur.x) + (_c2 - _c0) * _blur.y * (1.0 - _blur.x) + (_c3 - _c1) * _blur.x * _blur.y; - return mix_one; + float top_left = simple_noise_random(grid_id + vec2(0, 1)); + float top_right = simple_noise_random(grid_id + vec2(1, 1)); + float top = mix(top_left, top_right, grid_uv.x); + + return mix(bottom, top, grid_uv.y); } -float simple_noise(vec2 uv, float scale){ - int octaves = 6; - float amplitude = 0.25; - float value = 0.0; +float simple_noise(vec2 uv, float scale, int octaves) { + octaves = clamp(octaves, 1, 6); + float noise = value_noise(uv * scale); + float amplitude = 1.; - for(int i = 0; i < octaves; i++) { - value += amplitude * value_noise(scale * uv); - amplitude *= 0.85; - scale *= 3.0; + for(int i = 1; i < octaves; i++) { + scale *= 2.; + amplitude /= 2.; + noise += value_noise(uv * scale) * amplitude; } - return value; + + return noise / 2.; } \ No newline at end of file diff --git a/documentation/Nodes/Procedural/Noise/SimpleNoise.md b/documentation/Nodes/Procedural/Noise/SimpleNoise.md index 563bed9..e1c7097 100644 --- a/documentation/Nodes/Procedural/Noise/SimpleNoise.md +++ b/documentation/Nodes/Procedural/Noise/SimpleNoise.md @@ -7,6 +7,7 @@ Generates a simplex, or value noise based on input UV. The resulting outpu |---|---|---|---| |uv|vec2|UV|Input UV value| |scale|float|none|Noise scale| +|octaves|int|none|Octaves/Layers of noise, octaves input is clamped between 1 and 6.| **Outputs** |Name|Type|Binding|Description| From 55039f4c6bd9ce184f52a8638faee9cca6d38f26 Mon Sep 17 00:00:00 2001 From: Digvijaysinh Gohil Date: Tue, 19 Mar 2024 18:40:25 +0530 Subject: [PATCH 04/20] Update Voronoi.gdshaderinc --- addons/ShaderLib/Procedural/Noise/Voronoi.gdshaderinc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/ShaderLib/Procedural/Noise/Voronoi.gdshaderinc b/addons/ShaderLib/Procedural/Noise/Voronoi.gdshaderinc index 2a2c046..818d4d2 100644 --- a/addons/ShaderLib/Procedural/Noise/Voronoi.gdshaderinc +++ b/addons/ShaderLib/Procedural/Noise/Voronoi.gdshaderinc @@ -27,7 +27,7 @@ void voronoi_noise(vec2 uv, float cell_density, float angle_offset, int distance for(float x = -1.; x <= 1.; x++) { vec2 offset = vec2(x, y); vec2 n = voronoi_random_vector(grid_id + offset); - vec2 p = offset + sin(n + angle_offset) * .5 + .5; + vec2 p = offset + vec2(sin(n.x + angle_offset) * .5 + .5, cos(n.y + angle_offset) * .5 + .5); float d = min_dist; switch(distance_index){ From 41f016fecaf2981bd7055bb19f625d439af5a22e Mon Sep 17 00:00:00 2001 From: Digvijaysinh Gohil Date: Tue, 19 Mar 2024 19:38:22 +0530 Subject: [PATCH 05/20] Update Voronoi.gdshaderinc --- .../Procedural/Noise/Voronoi.gdshaderinc | 23 +++++-------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/addons/ShaderLib/Procedural/Noise/Voronoi.gdshaderinc b/addons/ShaderLib/Procedural/Noise/Voronoi.gdshaderinc index 818d4d2..cec15bb 100644 --- a/addons/ShaderLib/Procedural/Noise/Voronoi.gdshaderinc +++ b/addons/ShaderLib/Procedural/Noise/Voronoi.gdshaderinc @@ -1,22 +1,11 @@ +#include "res://addons/ShaderLib/Maths/Vector/Distance/Manhattan2D.gdshaderinc" +#include "res://addons/ShaderLib/Maths/Vector/Distance/Chebyshev2D.gdshaderinc" + vec2 voronoi_random_vector(vec2 p) { mat2 matrix = mat2(vec2(15.27, 47.63), vec2(99.41, 89.98)); return fract(sin(p * matrix) * 46839.32); } -float voronoi_euclidean_distance(vec2 point1, vec2 point2){ - return distance(point1, point2); -} - -float voronoi_manhattan_distance(vec2 point1, vec2 point2) { - vec2 d = point1 - point2; - return abs(d.x) + abs(d.y); -} - -float voronoi_chebyshev_distance(vec2 point1, vec2 point2, float power) { - vec2 p = point1 - point2; - return pow(pow(p.x, power) + pow(p.y, power), 1. / power); -} - void voronoi_noise(vec2 uv, float cell_density, float angle_offset, int distance_index, float chebyshev_power, out float output, out float cells){ vec2 grid_uv = fract(uv * cell_density); vec2 grid_id = floor(uv * cell_density); @@ -32,13 +21,13 @@ void voronoi_noise(vec2 uv, float cell_density, float angle_offset, int distance switch(distance_index){ case 1: - d = voronoi_manhattan_distance(grid_uv, p); + d = manhattan_distance_2d(grid_uv, p); break; case 2: - d = voronoi_chebyshev_distance(grid_uv, p, chebyshev_power); + d = chebyshev_distance_2d(grid_uv, p, chebyshev_power); break; default: - d = voronoi_euclidean_distance(grid_uv, p); + d = distance(grid_uv, p); break; } From 0d5c68fb1fa7bfcd1547b4bcff33d457123eb896 Mon Sep 17 00:00:00 2001 From: Digvijaysinh Gohil Date: Tue, 19 Mar 2024 19:43:02 +0530 Subject: [PATCH 06/20] Manhattan Distance node added --- .../Vector/Distance/Manhattan2D.gdshaderinc | 4 + .../Vector/Distance/Manhattan3D.gdshaderinc | 4 + .../Vector/Distance/ManhattanDistance.gd | 88 +++++++++++++++++++ documentation/Documentation.md | 4 + .../Vector/Distance/ManhattanDistance.md | 20 +++++ 5 files changed, 120 insertions(+) create mode 100644 addons/ShaderLib/Maths/Vector/Distance/Manhattan2D.gdshaderinc create mode 100644 addons/ShaderLib/Maths/Vector/Distance/Manhattan3D.gdshaderinc create mode 100644 addons/ShaderLib/Maths/Vector/Distance/ManhattanDistance.gd create mode 100644 documentation/Nodes/Maths/Vector/Distance/ManhattanDistance.md diff --git a/addons/ShaderLib/Maths/Vector/Distance/Manhattan2D.gdshaderinc b/addons/ShaderLib/Maths/Vector/Distance/Manhattan2D.gdshaderinc new file mode 100644 index 0000000..b2d6d7e --- /dev/null +++ b/addons/ShaderLib/Maths/Vector/Distance/Manhattan2D.gdshaderinc @@ -0,0 +1,4 @@ +float manhattan_distance_2d(vec2 point1, vec2 point2) { + vec2 d = point1 - point2; + return abs(d.x) + abs(d.y); +} \ No newline at end of file diff --git a/addons/ShaderLib/Maths/Vector/Distance/Manhattan3D.gdshaderinc b/addons/ShaderLib/Maths/Vector/Distance/Manhattan3D.gdshaderinc new file mode 100644 index 0000000..78ba265 --- /dev/null +++ b/addons/ShaderLib/Maths/Vector/Distance/Manhattan3D.gdshaderinc @@ -0,0 +1,4 @@ +float manhattan_distance_3d(vec3 point1, vec3 point2) { + vec3 d = point1 - point2; + return abs(d.x) + abs(d.y) + abs(d.z); +} \ No newline at end of file diff --git a/addons/ShaderLib/Maths/Vector/Distance/ManhattanDistance.gd b/addons/ShaderLib/Maths/Vector/Distance/ManhattanDistance.gd new file mode 100644 index 0000000..ce99534 --- /dev/null +++ b/addons/ShaderLib/Maths/Vector/Distance/ManhattanDistance.gd @@ -0,0 +1,88 @@ +@tool +class_name VisualShaderNodeMathsManhattanDistance extends VisualShaderNodeCustom + +func _get_name() -> String: + return "ManhattanDistance" + +func _get_category() -> String: + return "Maths/Vector/Distance" + +func _get_description() -> String: + return "Returns the distance between two points using Manhattan distance matrix." + +func _get_return_icon_type() -> 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 "a" + _: + return "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 "distance" + +func _get_output_port_type(port: int) -> PortType: + return PORT_TYPE_SCALAR + +func _get_property_count() -> int: + return 1 + +func _get_property_name(index: int) -> String: + return "" + +func _get_property_default_index(index: int) -> int: + return 0 + +func _get_property_options(index: int) -> PackedStringArray: + return ["Vector2", "Vector3"] + +func _get_global_code(mode: Shader.Mode) -> String: + var code: String + var vector_index: int = get_option_index(0) + match vector_index: + 0: + code = preload("Manhattan2D.gdshaderinc").code + _: + code = preload("Manhattan3D.gdshaderinc").code + return code + +func _get_code(input_vars: Array[String], output_vars: Array[String], mode: Shader.Mode, type: VisualShader.Type) -> String: + var point_a: String + var point_b: String + var vector_index: int = get_option_index(0) + match vector_index: + 0: + point_a = "vec2(0)" + point_b = "vec2(0)" + _: + point_b = "vec3(0)" + point_a = "vec3(0)" + + if input_vars[0]: + point_a = input_vars[0] + + if input_vars[1]: + point_b = input_vars[1] + + match vector_index: + 0: + return output_vars[0] + " = manhattan_distance_2d(%s, %s);" % [point_a, point_b] + _: + return output_vars[0] + " = manhattan_distance_3d(%s, %s);" % [point_a, point_b] + diff --git a/documentation/Documentation.md b/documentation/Documentation.md index 90f5a2a..1d2adc4 100644 --- a/documentation/Documentation.md +++ b/documentation/Documentation.md @@ -32,6 +32,10 @@ For example if you want to rotate UV in your **_.gdshader_** file, you can use `

 Vector

+

  Distance

+ +

   Manhattan Distance node

+

  Project node

  Project On Plane node

  Vector Transform node

diff --git a/documentation/Nodes/Maths/Vector/Distance/ManhattanDistance.md b/documentation/Nodes/Maths/Vector/Distance/ManhattanDistance.md new file mode 100644 index 0000000..a1a2d4a --- /dev/null +++ b/documentation/Nodes/Maths/Vector/Distance/ManhattanDistance.md @@ -0,0 +1,20 @@ +# Manhattan Distance node +Returns the distance between two points using Manhattan distance matrix. +
+ +**Controls** +|Options|Description| +|---|---| +|Vector2, Vector3|Vector type to use for calculation| + +**Inputs** +|Name|Type|Binding|Description| +|---|---|---|---| +|a|Dynamic vector|none|Point a| +|b|Dynamic vector|none|Point b| + +**Outputs** +|Name|Type|Binding|Description| +|---|---|---|---| +|distance|float|None|Distance between 2 points| +___ \ No newline at end of file From 4686b20c512b1c5d7fa0d29e30a25e983dd4d16d Mon Sep 17 00:00:00 2001 From: Digvijaysinh Gohil Date: Tue, 19 Mar 2024 19:47:24 +0530 Subject: [PATCH 07/20] Chebyshev Distance node added --- .../Vector/Distance/Chebyshev2D.gdshaderinc | 4 + .../Vector/Distance/Chebyshev3D.gdshaderinc | 4 + .../Vector/Distance/ChebyshevDistance.gd | 102 ++++++++++++++++++ documentation/Documentation.md | 1 + .../Vector/Distance/ChebyshevDistance.md | 21 ++++ 5 files changed, 132 insertions(+) create mode 100644 addons/ShaderLib/Maths/Vector/Distance/Chebyshev2D.gdshaderinc create mode 100644 addons/ShaderLib/Maths/Vector/Distance/Chebyshev3D.gdshaderinc create mode 100644 addons/ShaderLib/Maths/Vector/Distance/ChebyshevDistance.gd create mode 100644 documentation/Nodes/Maths/Vector/Distance/ChebyshevDistance.md diff --git a/addons/ShaderLib/Maths/Vector/Distance/Chebyshev2D.gdshaderinc b/addons/ShaderLib/Maths/Vector/Distance/Chebyshev2D.gdshaderinc new file mode 100644 index 0000000..a270d5b --- /dev/null +++ b/addons/ShaderLib/Maths/Vector/Distance/Chebyshev2D.gdshaderinc @@ -0,0 +1,4 @@ +float chebyshev_distance_2d(vec2 point1, vec2 point2, float power) { + vec2 p = abs(point1 - point2); + return pow(pow(p.x, power) + pow(p.y, power), 1. / power); +} \ No newline at end of file diff --git a/addons/ShaderLib/Maths/Vector/Distance/Chebyshev3D.gdshaderinc b/addons/ShaderLib/Maths/Vector/Distance/Chebyshev3D.gdshaderinc new file mode 100644 index 0000000..d5e525b --- /dev/null +++ b/addons/ShaderLib/Maths/Vector/Distance/Chebyshev3D.gdshaderinc @@ -0,0 +1,4 @@ +float chebyshev_distance_3d(vec3 point1, vec3 point2, float power) { + vec3 p = abs(point1 - point2); + return pow(pow(p.x, power) + pow(p.y, power) + pow(p.z, power), 1. / power); +} \ No newline at end of file diff --git a/addons/ShaderLib/Maths/Vector/Distance/ChebyshevDistance.gd b/addons/ShaderLib/Maths/Vector/Distance/ChebyshevDistance.gd new file mode 100644 index 0000000..bd89d87 --- /dev/null +++ b/addons/ShaderLib/Maths/Vector/Distance/ChebyshevDistance.gd @@ -0,0 +1,102 @@ +@tool +class_name VisualShaderNodeMathsChebyshevDistance extends VisualShaderNodeCustom + +func _get_name() -> String: + return "ChebyshevDistance" + +func _get_category() -> String: + return "Maths/Vector/Distance" + +func _get_description() -> String: + return "Returns the distance between two points using Chebyshev distance matrix." + +func _get_return_icon_type() -> PortType: + return PORT_TYPE_SCALAR + +func _get_input_port_count() -> int: + return 3 + +func _get_input_port_name(port: int) -> String: + match port: + 0: + return "a" + 1: + return "b" + _: + return "power" + +func _get_input_port_type(port: int) -> PortType: + var vector_index: int = get_option_index(0) + match port: + 2: + return PORT_TYPE_SCALAR + _: + match vector_index: + 0: + return PORT_TYPE_VECTOR_2D + _: + return PORT_TYPE_VECTOR_3D + +func _get_input_port_default_value(port: int) -> Variant: + match port: + 2: + return 2.0 + _: + return null + +func _get_output_port_count() -> int: + return 1 + +func _get_output_port_name(port: int) -> String: + return "distance" + +func _get_output_port_type(port: int) -> PortType: + return PORT_TYPE_SCALAR + +func _get_property_count() -> int: + return 1 + +func _get_property_name(index: int) -> String: + return "" + +func _get_property_default_index(index: int) -> int: + return 0 + +func _get_property_options(index: int) -> PackedStringArray: + return ["Vector2", "Vector3"] + +func _get_global_code(mode: Shader.Mode) -> String: + var code: String + var vector_index: int = get_option_index(0) + match vector_index: + 0: + code = preload("Chebyshev2D.gdshaderinc").code + _: + code = preload("Chebyshev3D.gdshaderinc").code + return code + +func _get_code(input_vars: Array[String], output_vars: Array[String], mode: Shader.Mode, type: VisualShader.Type) -> String: + var point_a: String + var point_b: String + var power: String = input_vars[2] + var vector_index: int = get_option_index(0) + match vector_index: + 0: + point_a = "vec2(0)" + point_b = "vec2(0)" + _: + point_b = "vec3(0)" + point_a = "vec3(0)" + + if input_vars[0]: + point_a = input_vars[0] + + if input_vars[1]: + point_b = input_vars[1] + + match vector_index: + 0: + return output_vars[0] + " = chebyshev_distance_2d(%s, %s, %s);" % [point_a, point_b, power] + _: + return output_vars[0] + " = chebyshev_distance_3d(%s, %s, %s);" % [point_a, point_b, power] + diff --git a/documentation/Documentation.md b/documentation/Documentation.md index 1d2adc4..4ae293b 100644 --- a/documentation/Documentation.md +++ b/documentation/Documentation.md @@ -34,6 +34,7 @@ For example if you want to rotate UV in your **_.gdshader_** file, you can use `

  Distance

+

   Chebyshev Distance node

   Manhattan Distance node

  Project node

diff --git a/documentation/Nodes/Maths/Vector/Distance/ChebyshevDistance.md b/documentation/Nodes/Maths/Vector/Distance/ChebyshevDistance.md new file mode 100644 index 0000000..866d179 --- /dev/null +++ b/documentation/Nodes/Maths/Vector/Distance/ChebyshevDistance.md @@ -0,0 +1,21 @@ +# Chebyshev Distance node +Returns the distance between two points using Chebyshev distance matrix. +
+ +**Controls** +|Options|Description| +|---|---| +|Vector2, Vector3|Vector type to use for calculation| + +**Inputs** +|Name|Type|Binding|Description| +|---|---|---|---| +|a|Dynamic vector|none|Point a| +|b|Dynamic vector|none|Point b| +|power|float|none|Power to use for Chebyshev distance| + +**Outputs** +|Name|Type|Binding|Description| +|---|---|---|---| +|distance|float|None|Distance between 2 points| +___ \ No newline at end of file From a7467b8bfd3747a84e3d2c7e6231668995d1ea31 Mon Sep 17 00:00:00 2001 From: Digvijaysinh Gohil Date: Tue, 26 Mar 2024 10:20:51 +0530 Subject: [PATCH 08/20] Gyroid noise node added --- .../ShaderLib/Procedural/Noise/GyroidNoise.gd | 79 +++++++++++++++++++ .../Procedural/Noise/GyroidNoise.gdshaderinc | 7 ++ documentation/Documentation.md | 1 + .../Nodes/Procedural/Noise/GyroidNoise.md | 18 +++++ 4 files changed, 105 insertions(+) create mode 100644 addons/ShaderLib/Procedural/Noise/GyroidNoise.gd create mode 100644 addons/ShaderLib/Procedural/Noise/GyroidNoise.gdshaderinc create mode 100644 documentation/Nodes/Procedural/Noise/GyroidNoise.md diff --git a/addons/ShaderLib/Procedural/Noise/GyroidNoise.gd b/addons/ShaderLib/Procedural/Noise/GyroidNoise.gd new file mode 100644 index 0000000..711b2ba --- /dev/null +++ b/addons/ShaderLib/Procedural/Noise/GyroidNoise.gd @@ -0,0 +1,79 @@ +@tool +class_name VisualShaderNodeProceduralGyroidNoise extends VisualShaderNodeCustom + +func _init() -> void: + output_port_for_preview = 0 + +func _get_name() -> String: + return "GyroidNoise" + +func _get_category() -> String: + return "Procedural/Noise" + +func _get_description() -> String: + return "Generates a gyroid noise based on input UV." + +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 "scale" + 2: + return "ratio" + 3: + return "height" + _: + return "thickness" + +func _get_input_port_type(port: int) -> PortType: + match port: + 0, 2: + return PORT_TYPE_VECTOR_2D + _: + return PORT_TYPE_SCALAR + +func _get_input_port_default_value(port: int) -> Variant: + match port: + 1: + return 2.0 + 2: + return Vector2(1, 1) + 3: + return 0.5 + 4: + return 0.0 + _: + return null + +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) -> PortType: + return PORT_TYPE_SCALAR + +func _get_global_code(mode: Shader.Mode) -> String: + var code: String = preload("GyroidNoise.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] + var ratio: String = input_vars[2] + var height: String = input_vars[3] + var thickness: String = input_vars[4] + + return output_vars[0] + " = gyroid_noise(%s, %s, %s, %s, %s);" % [uv, scale, ratio, height, thickness] diff --git a/addons/ShaderLib/Procedural/Noise/GyroidNoise.gdshaderinc b/addons/ShaderLib/Procedural/Noise/GyroidNoise.gdshaderinc new file mode 100644 index 0000000..a7007dc --- /dev/null +++ b/addons/ShaderLib/Procedural/Noise/GyroidNoise.gdshaderinc @@ -0,0 +1,7 @@ +float gyroid_noise(vec2 uv, float scale, vec2 ratio, float height, float thickness) { + scale *= 10.; + thickness = clamp(thickness, 0., 1.); + vec3 vector = vec3(uv, height); + vector *= scale; + return abs(dot(sin(vector * ratio.x), cos(vector.zxy * ratio.y))) - thickness; +} \ No newline at end of file diff --git a/documentation/Documentation.md b/documentation/Documentation.md index 4ae293b..bcb8b18 100644 --- a/documentation/Documentation.md +++ b/documentation/Documentation.md @@ -59,6 +59,7 @@ For example if you want to rotate UV in your **_.gdshader_** file, you can use `

 Noise

  Gradient Noise node

+

  Gyroid Noise node

  Pseudo Random Noise node

  Simple Noise node

  Voronoi node

diff --git a/documentation/Nodes/Procedural/Noise/GyroidNoise.md b/documentation/Nodes/Procedural/Noise/GyroidNoise.md new file mode 100644 index 0000000..992dddf --- /dev/null +++ b/documentation/Nodes/Procedural/Noise/GyroidNoise.md @@ -0,0 +1,18 @@ +# Gyroid Noise node +Generates a gyroid noise based on input UV. The resulting output values will be between 0 and 1. +
+ +**Inputs** +|Name|Type|Binding|Description| +|---|---|---|---| +|uv|vec2|UV|Input UV value| +|scale|float|none|Noise scale| +|ratio|vec2|none|Noise ratio for X and Y Axes| +|height|vec2|none|Noise height| +|thickness|vec2|none|Noise thickness| + +**Outputs** +|Name|Type|Binding|Description| +|---|---|---|---| +|output|float|None|Output noise value| +___ \ No newline at end of file From beeee0e5563b1f58381aa9abf98c71b638a1b27a Mon Sep 17 00:00:00 2001 From: Digvijaysinh Gohil Date: Tue, 26 Mar 2024 10:34:22 +0530 Subject: [PATCH 09/20] Update GyroidNoise.md --- documentation/Nodes/Procedural/Noise/GyroidNoise.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/Nodes/Procedural/Noise/GyroidNoise.md b/documentation/Nodes/Procedural/Noise/GyroidNoise.md index 992dddf..e951a5d 100644 --- a/documentation/Nodes/Procedural/Noise/GyroidNoise.md +++ b/documentation/Nodes/Procedural/Noise/GyroidNoise.md @@ -9,7 +9,7 @@ Generates a gyroid noise based on input UV. The resulting output v |scale|float|none|Noise scale| |ratio|vec2|none|Noise ratio for X and Y Axes| |height|vec2|none|Noise height| -|thickness|vec2|none|Noise thickness| +|thickness|vec2|none|Noise thickness, clamped between 0 and 1| **Outputs** |Name|Type|Binding|Description| From 6cfeaaec5e9153268998dada5532807678add11a Mon Sep 17 00:00:00 2001 From: Digvijaysinh Gohil Date: Tue, 26 Mar 2024 10:52:51 +0530 Subject: [PATCH 10/20] Update GyroidNoise.md --- documentation/Nodes/Procedural/Noise/GyroidNoise.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/Nodes/Procedural/Noise/GyroidNoise.md b/documentation/Nodes/Procedural/Noise/GyroidNoise.md index e951a5d..0015456 100644 --- a/documentation/Nodes/Procedural/Noise/GyroidNoise.md +++ b/documentation/Nodes/Procedural/Noise/GyroidNoise.md @@ -8,8 +8,8 @@ Generates a gyroid noise based on input UV. The resulting output v |uv|vec2|UV|Input UV value| |scale|float|none|Noise scale| |ratio|vec2|none|Noise ratio for X and Y Axes| -|height|vec2|none|Noise height| -|thickness|vec2|none|Noise thickness, clamped between 0 and 1| +|height|float|none|Noise height| +|thickness|float|none|Noise thickness, clamped between 0 and 1| **Outputs** |Name|Type|Binding|Description| From 1d1521456527343d7cf12964b486cc724514cdb5 Mon Sep 17 00:00:00 2001 From: Digvijaysinh Gohil Date: Tue, 26 Mar 2024 10:59:07 +0530 Subject: [PATCH 11/20] Ray march node added --- addons/ShaderLib/RayMarching/RayMarch.gd | 83 +++++++++++++++++++ .../RayMarching/RayMarch.gdshaderinc | 14 ++++ documentation/Documentation.md | 4 + documentation/Nodes/RayMarching/RayMarch.md | 19 +++++ 4 files changed, 120 insertions(+) create mode 100644 addons/ShaderLib/RayMarching/RayMarch.gd create mode 100644 addons/ShaderLib/RayMarching/RayMarch.gdshaderinc create mode 100644 documentation/Nodes/RayMarching/RayMarch.md diff --git a/addons/ShaderLib/RayMarching/RayMarch.gd b/addons/ShaderLib/RayMarching/RayMarch.gd new file mode 100644 index 0000000..7fea588 --- /dev/null +++ b/addons/ShaderLib/RayMarching/RayMarch.gd @@ -0,0 +1,83 @@ +@tool +class_name VisualShaderNodeRayMarch extends VisualShaderNodeCustom + +func _get_name() -> String: + return "RayMarch" + +func _get_category() -> String: + return "RayMarching" + +func _get_description() -> String: + return "A simple ray marcher." + +func _get_return_icon_type() -> PortType: + return PORT_TYPE_SCALAR + +func _get_input_port_count() -> int: + return 6 + +func _get_input_port_name(port: int) -> String: + match port: + 0: + return "signed distance" + 1: + return "ray origin" + 2: + return "ray direction" + 3: + return "max steps" + 4: + return "max distance" + _: + return "distance threshold" + +func _get_input_port_type(port: int) -> PortType: + match port: + 1, 2: + return PORT_TYPE_VECTOR_3D + 3: + return PORT_TYPE_SCALAR_INT + _: + return PORT_TYPE_SCALAR + +func _get_input_port_default_value(port: int) -> Variant: + match port: + 1: + return Vector3(0, 0, -1) + 2: + return Vector3(0 ,0 ,0) + 3: + return 15 + 4: + return 15.0 + 5: + return 1e-2 + _: + return null + +func _get_output_port_count() -> int: + return 1 + +func _get_output_port_name(port: int) -> String: + return "distance" + +func _get_output_port_type(port: int) -> PortType: + return PORT_TYPE_SCALAR + +func _get_global_code(mode: Shader.Mode) -> String: + var code: String = preload("RayMarch.gdshaderinc").code + return code + +func _get_code(input_vars: Array[String], output_vars: Array[String], mode: Shader.Mode, type: VisualShader.Type) -> String: + var signed_distance: String = "0.0" + + if input_vars[0]: + signed_distance = input_vars[0] + + var ray_origin: String = input_vars[1] + var ray_direction: String = input_vars[2] + var max_steps: String = input_vars[3] + var max_dist: String = input_vars[4] + var dist_threshold: String = input_vars[5] + + return output_vars[0] + " = ray_march(%s, %s, %s, %s, %s, %s);" % [ray_origin, ray_direction, max_steps, max_dist, dist_threshold, signed_distance] diff --git a/addons/ShaderLib/RayMarching/RayMarch.gdshaderinc b/addons/ShaderLib/RayMarching/RayMarch.gdshaderinc new file mode 100644 index 0000000..c24a18f --- /dev/null +++ b/addons/ShaderLib/RayMarching/RayMarch.gdshaderinc @@ -0,0 +1,14 @@ +float ray_march(vec3 ray_origin, vec3 ray_dir, int max_steps, float max_dist, float dist_threshold, float signed_dist) { + ray_dir = normalize(ray_dir); + dist_threshold = abs(dist_threshold); + float dist_from_origin = 0.; + float dist_to_surface; + for(int i = 0; i < max_steps; i++) { + vec3 point = ray_origin + dist_from_origin * ray_dir; + dist_to_surface = signed_dist; + dist_from_origin += dist_to_surface; + if(dist_to_surface < dist_threshold || dist_to_surface > max_dist) + break; + } + return dist_from_origin; +} \ No newline at end of file diff --git a/documentation/Documentation.md b/documentation/Documentation.md index bcb8b18..2731592 100644 --- a/documentation/Documentation.md +++ b/documentation/Documentation.md @@ -72,6 +72,10 @@ For example if you want to rotate UV in your **_.gdshader_** file, you can use `

  Rounded Polygon node

  Rounded Rectangle node

+

Ray marching nodes

+ +

 Ray March node

+

UV nodes

 Flipbook node

diff --git a/documentation/Nodes/RayMarching/RayMarch.md b/documentation/Nodes/RayMarching/RayMarch.md new file mode 100644 index 0000000..9c713dc --- /dev/null +++ b/documentation/Nodes/RayMarching/RayMarch.md @@ -0,0 +1,19 @@ +# Ray March node +A simple ray marcher. +
+ +**Inputs** +|Name|Type|Binding|Description| +|---|---|---|---| +|signed distance|float|none|Signed distance calculated from Signed Distance Functions (SDFs)| +|ray origin|vec3|none|Ray origin| +|ray direction|vec3|none|Normalized ray direction| +|max steps|int|none|Maximum number steps for ray marching| +|max distance|float|none|Maximum distance to march along the ray direction| +|distance threshold|float|none|Threshold to check against signed distance to determine the ray intersection point.| + +**Outputs** +|Name|Type|Binding|Description| +|---|---|---|---| +|distance|float|None|Output ray intersection distance| +___ \ No newline at end of file From c4e47d37ebf0e9fd2c7c9bf4daa4bb0b0722305e Mon Sep 17 00:00:00 2001 From: Digvijaysinh Gohil Date: Tue, 26 Mar 2024 11:00:59 +0530 Subject: [PATCH 12/20] Update RayMarch.md --- documentation/Nodes/RayMarching/RayMarch.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/Nodes/RayMarching/RayMarch.md b/documentation/Nodes/RayMarching/RayMarch.md index 9c713dc..fe78d0f 100644 --- a/documentation/Nodes/RayMarching/RayMarch.md +++ b/documentation/Nodes/RayMarching/RayMarch.md @@ -8,12 +8,12 @@ A simple ray marcher. |signed distance|float|none|Signed distance calculated from Signed Distance Functions (SDFs)| |ray origin|vec3|none|Ray origin| |ray direction|vec3|none|Normalized ray direction| -|max steps|int|none|Maximum number steps for ray marching| +|max steps|int|none|Maximum number of steps for ray marching| |max distance|float|none|Maximum distance to march along the ray direction| |distance threshold|float|none|Threshold to check against signed distance to determine the ray intersection point.| **Outputs** |Name|Type|Binding|Description| |---|---|---|---| -|distance|float|None|Output ray intersection distance| +|distance|float|None|Ray intersection distance| ___ \ No newline at end of file From 0b9c1235fa75c775e49c3160babf8de9f51597dd Mon Sep 17 00:00:00 2001 From: Digvijaysinh Gohil Date: Tue, 26 Mar 2024 21:16:07 +0530 Subject: [PATCH 13/20] Update VectorTransform.gdshaderinc --- .../ShaderLib/Maths/Vector/VectorTransform.gdshaderinc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/addons/ShaderLib/Maths/Vector/VectorTransform.gdshaderinc b/addons/ShaderLib/Maths/Vector/VectorTransform.gdshaderinc index 32eebf1..91ceb44 100644 --- a/addons/ShaderLib/Maths/Vector/VectorTransform.gdshaderinc +++ b/addons/ShaderLib/Maths/Vector/VectorTransform.gdshaderinc @@ -1,5 +1,5 @@ vec3 vector_transform_world_to_local(mat4 model_matrix, vec3 vector){ - return (transpose(model_matrix) * vec4(vector, 1.0)).xyz; + return (inverse(model_matrix) * vec4(vector, 1.0)).xyz; } vec3 vector_transform_world_to_view(mat4 view_matrix, vec3 vector){ @@ -76,24 +76,24 @@ vec3 vector_transform_screen_to_tangent(mat4 inv_projection_matrix, mat4 inv_vie } vec3 vector_transform_tangent_to_local(vec3 normal, vec3 binormal, vec3 tangent, vec3 vector){ - mat3 tangent_to_local_matrix = transpose(mat3(tangent, binormal, normal)); + mat3 tangent_to_local_matrix = inverse(mat3(tangent, binormal, normal)); return tangent_to_local_matrix * vector; } vec3 vector_transform_tangent_to_world(mat4 model_matrix, vec3 normal, vec3 binormal, vec3 tangent, vec3 vector){ - mat3 tangent_to_local_matrix = transpose(mat3(tangent, binormal, normal)); + mat3 tangent_to_local_matrix = inverse(mat3(tangent, binormal, normal)); vec3 vector_local = tangent_to_local_matrix * vector; return vector_transform_local_to_world(model_matrix, vector_local); } vec3 vector_transform_tangent_to_view(mat4 model_matrix, mat4 view_matrix, vec3 normal, vec3 binormal, vec3 tangent, vec3 vector){ - mat3 tangent_to_local_matrix = transpose(mat3(tangent, binormal, normal)); + mat3 tangent_to_local_matrix = inverse(mat3(tangent, binormal, normal)); vec3 vector_local = tangent_to_local_matrix * vector; return vector_transform_local_to_view(model_matrix, view_matrix, vector_local); } vec3 vector_transform_tangent_to_screen(mat4 model_matrix, mat4 view_matrix, mat4 projection_matrix, vec3 normal, vec3 binormal, vec3 tangent, vec3 vector){ - mat3 tangent_to_local_matrix = transpose(mat3(tangent, binormal, normal)); + mat3 tangent_to_local_matrix = inverse(mat3(tangent, binormal, normal)); vec3 vector_local = tangent_to_local_matrix * vector; return vector_transform_local_to_screen(model_matrix, view_matrix, projection_matrix, vector_local); } From e921ecebaddaa63d80be977e127ed65bbf2ca536 Mon Sep 17 00:00:00 2001 From: Digvijaysinh Gohil Date: Wed, 27 Mar 2024 08:40:59 +0530 Subject: [PATCH 14/20] Update SimpleNoise.gd - Compilation error fixed. --- addons/ShaderLib/Procedural/Noise/SimpleNoise.gd | 2 -- 1 file changed, 2 deletions(-) diff --git a/addons/ShaderLib/Procedural/Noise/SimpleNoise.gd b/addons/ShaderLib/Procedural/Noise/SimpleNoise.gd index d825e03..fdffb25 100644 --- a/addons/ShaderLib/Procedural/Noise/SimpleNoise.gd +++ b/addons/ShaderLib/Procedural/Noise/SimpleNoise.gd @@ -46,8 +46,6 @@ func _get_input_port_default_value(port: int) -> Variant: _: return null -func _get_default_input_port(type: PortType) -> int: - func _get_output_port_count() -> int: return 1 From f8c0bc1e4e2209ee6d4ae69077e8f1c43f1e1a69 Mon Sep 17 00:00:00 2001 From: Digvijaysinh Gohil Date: Wed, 27 Mar 2024 10:48:02 +0530 Subject: [PATCH 15/20] Update RayMarch.md --- documentation/Nodes/RayMarching/RayMarch.md | 31 +++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/documentation/Nodes/RayMarching/RayMarch.md b/documentation/Nodes/RayMarching/RayMarch.md index fe78d0f..3b7d7c5 100644 --- a/documentation/Nodes/RayMarching/RayMarch.md +++ b/documentation/Nodes/RayMarching/RayMarch.md @@ -2,6 +2,11 @@ A simple ray marcher.
+**Controls** +|Name|Options|Description| +|---|---|---| +|SDF (Signed Distance Function)|SDBox, SDSphere, SDCapsule, SDCylinder, SDTorus|Signed Distance Functions for the space to draw.| + **Inputs** |Name|Type|Binding|Description| |---|---|---|---| @@ -11,6 +16,32 @@ A simple ray marcher. |max steps|int|none|Maximum number of steps for ray marching| |max distance|float|none|Maximum distance to march along the ray direction| |distance threshold|float|none|Threshold to check against signed distance to determine the ray intersection point.| + +**SDFs Inputs** +|Name|Type|Availability|Description| +|---|---|---|---| +|cube pos|vec3|SDBox|Position offset of the box shape| +|cube eulers|vec3|SDBox|Rotation of the box shape in Degrees| +|cube scale|vec3|SDBox|Scale of the box shape| +|---|---|---|---| +|sphere pos|vec3|SDSphere|Position offset of the sphere shape| +|sphere eulers|vec3|SDSphere|Rotation of the box sphere in Degrees| +|sphere scale|vec3|SDSphere|Scale of the sphere shape| +|---|---|---|---| +|capsule pos|vec3|SDCapsule|Position offset of the capsule shape| +|capsule eulers|vec3|SDCapsule|Rotation of the capsule shape in Degrees| +|capsule height|float|SDCapsule|Height of the capsule shape| +|capsule radius|float|SDCapsule|Radius of the capsule shape| +|---|---|---|---| +|cylinder pos|vec3|SDCylinder|Position offset of the cylinder shape| +|cylinder eulers|vec3|SDCylinder|Rotation of the cylinder shape in Degrees| +|cylinder height|float|SDCylinder|Height of the cylinder shape| +|cylinder radius|float|SDCylinder|Radius of the cylinder shape| +|---|---|---|---| +|torus pos|vec3|SDTorus|Position offset of the torus shape| +|torus eulers|vec3|SDTorus|Rotation of the torus shape in Degrees| +|torus small radius|float|SDTorus|Small radius of the torus shape| +|torus big radius|float|SDTorus|Big radius of the torus shape| **Outputs** |Name|Type|Binding|Description| From 6b57a43325520075f7fe12b5808d216f11433004 Mon Sep 17 00:00:00 2001 From: Digvijaysinh Gohil Date: Wed, 27 Mar 2024 11:21:19 +0530 Subject: [PATCH 16/20] Update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index eb4c9dc..7e178cf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ # Godot 4+ specific ignores .godot/ tests/ +*.import From 033b54ea939cf51a66224e0df3494d216e69e291 Mon Sep 17 00:00:00 2001 From: Digvijaysinh Gohil Date: Wed, 27 Mar 2024 11:21:47 +0530 Subject: [PATCH 17/20] Ray march node documentation added. --- .../Nodes/RayMarching/Expression.jpg | Bin 0 -> 75803 bytes .../Nodes/RayMarching/GlobalExpression.jpg | Bin 0 -> 123111 bytes documentation/Nodes/RayMarching/RayMarch.md | 21 +++++++++++++----- 3 files changed, 15 insertions(+), 6 deletions(-) create mode 100644 documentation/Nodes/RayMarching/Expression.jpg create mode 100644 documentation/Nodes/RayMarching/GlobalExpression.jpg diff --git a/documentation/Nodes/RayMarching/Expression.jpg b/documentation/Nodes/RayMarching/Expression.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4ff096c5e53b170f9c61fe0dde9cb815cbd9a67c GIT binary patch literal 75803 zcmeFZ1z1&0*D$;R5d%R)Kw3ov>F!VvkZz8&ba%G}NOz|od4NNADBVaLIwYl$4mt2` zz&oDzx$pPCo=3m;y58@9mgCuL&#bj(X3bt}*36#G>G0_n;HH?cs4##80u2%k0Gyrx z*n-x2TDE$+cO8su4eyGGO3IwhAm@t;3Tn#8Nehcg2!Yf9fShcqV`g)S0RYU*ZLQ@* z1nxdpR=JC|2%rFj04i`Fz}M2Tv6Pe-RsjAM_67k^5&-nmp2_-KvcE34p{r-30{}>O z!Q#g{me#f){sP3=9BeJm@MsXftz)RA3*tE-PGb!=5X6Vi^0hDU)id1S97hIG;I_4b zoFLe@+aP||;7_>rpKu*RYcr6B1*CbPYi170M}B^R>z?7RXSkWE9oV*WIO`$0p1Gnt zczpo=CjvwOQ9u%q0qz3YfE{22m;$x{EqFBtb8G-Puw3A8_zBMWWk4=%kjn_r0Xd!m z7JwO`bG$`ir-&2)Kp6*s zkLG{yTOz48QB`zoq%1ztb^5 z5I{jjK1(260u$;LRMbnCP_Ln(UA}^T4ITaZwd>b!VBETS0|N`=`t_T*H?gp9jA7Q$WoWHQIN0zWGo~UETq#$ zuro*iG74yPXR5e>OQ^^wm(h@}fTaXy=6D9bm4S~f@+B11%cr9NIts{n6XhnDb$pop z2f?qw6x-hY8bQBFp`~rbx#h}*G9Zn|N{Z;=__1AskY^XucEmGvinaO1?pCjTzoTzf8^tBn(C z=3~I7E5g8n_b@Cm+yC)T)C002g_u=Y;d$Qc3nxERQxj6R-W?RekGa&k6nG!X%=$Ra z{KYGZ20azyqdX;1snRxKlj1P4>0RA4+M2hC1{SP}cV7Nn{V4ax9N^mzBReMif#N8vb0xwF&ykD_6#b(hw}^i49@rfk`~Sm@W%-6 zBtV1Dbcv!O(0X?L32>t@o;znpnMPy2dHw)>VTL7NNW3G`p!fH(>-h*N0Y-m`l|`VL zk(uwuL;e@^TBPVb#TWUP89^_6@tDS#RQ{lS6GK8<_V_OtFS4F=4k{bJy!6cPj00=t zvR>)N-`7RlH(Zc@uy z-QM}D1|Xp^Bey^b0++?ew{xjxSR!L}3S4LDX?l4CvNeqVofLDFeAC zW0`2=UzUFPY*`FoV+wa}-%wcvwOuvY6ds4W#G|8h#Fh0he!g@|nu_)<2JXwhXvr1M zXk4zE6ODuiHrsovR|3e>VOAtQF{bXW@XWjVs_Xj&W)D-XvdluUe9WE9io^dx1USa$ zgRsQdl^93CWOw;>nrrG~FmlVt(05ADH4U~#JR-5sC?Snn5uMsQcAtVS9Q3pyo?rN} z1ve(vIP@-kiUy-(Q26;%>YjAfY9L~v@b$}@z;|CLF<*iO{}nEtnf$;RvHtcFtwtkS zR_A9soGc_FP>i#72W2!Y?JTE;!IDY;E9b@i`2b8br!tdaFXj86<$({*BZCy8drCi^ zWxc$`3sPhZUB{vy6Tn5zKl~zLG9z~=0QaA&b*O&^f^IU?vOoR@fv+YhpOKGGk>f9Csvqf8gRM7h)0UHcMU2m43!{(=l}{oPaCX}QuaB4j^h%;)tg)J1q0Qj-06-WZ+y`UgQ8k}z{w6ng z@J78_MYKir(yPZm(*z`WpNF}*2&|a?mbj(qqmuIgfO(u>Xy3YQdt>3`GB^?KIL1&& ziSSHLRx*g|%~L)4Hj@c(m#^qVats5$xT{3??{x=%my?OjoHG!+Vv%0DR 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
  • Nr$Y(#g`ZF3;iM}Mk|PSJ7lXt+K2KBb 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 literal 0 HcmV?d00001 diff --git a/documentation/Nodes/RayMarching/GlobalExpression.jpg b/documentation/Nodes/RayMarching/GlobalExpression.jpg new file mode 100644 index 0000000000000000000000000000000000000000..66323697277274b7607a61bd19820e1d02ad9ac1 GIT binary patch literal 123111 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�`ehipO@rggCUod! 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 O>3y`+>OK3j`u_k~lMxO8 literal 0 HcmV?d00001 diff --git a/documentation/Nodes/RayMarching/RayMarch.md b/documentation/Nodes/RayMarching/RayMarch.md index 3b7d7c5..e7ce218 100644 --- a/documentation/Nodes/RayMarching/RayMarch.md +++ b/documentation/Nodes/RayMarching/RayMarch.md @@ -1,5 +1,5 @@ # Ray March node -A simple ray marcher. +A simple ray marcher for primitive shapes.
    **Controls** @@ -23,21 +23,17 @@ A simple ray marcher. |cube pos|vec3|SDBox|Position offset of the box shape| |cube eulers|vec3|SDBox|Rotation of the box shape in Degrees| |cube scale|vec3|SDBox|Scale of the box shape| -|---|---|---|---| |sphere pos|vec3|SDSphere|Position offset of the sphere shape| |sphere eulers|vec3|SDSphere|Rotation of the box sphere in Degrees| |sphere scale|vec3|SDSphere|Scale of the sphere shape| -|---|---|---|---| |capsule pos|vec3|SDCapsule|Position offset of the capsule shape| |capsule eulers|vec3|SDCapsule|Rotation of the capsule shape in Degrees| |capsule height|float|SDCapsule|Height of the capsule shape| |capsule radius|float|SDCapsule|Radius of the capsule shape| -|---|---|---|---| |cylinder pos|vec3|SDCylinder|Position offset of the cylinder shape| |cylinder eulers|vec3|SDCylinder|Rotation of the cylinder shape in Degrees| |cylinder height|float|SDCylinder|Height of the cylinder shape| |cylinder radius|float|SDCylinder|Radius of the cylinder shape| -|---|---|---|---| |torus pos|vec3|SDTorus|Position offset of the torus shape| |torus eulers|vec3|SDTorus|Rotation of the torus shape in Degrees| |torus small radius|float|SDTorus|Small radius of the torus shape| @@ -47,4 +43,17 @@ A simple ray marcher. |Name|Type|Binding|Description| |---|---|---|---| |distance|float|None|Ray intersection distance| -___ \ No newline at end of file +___ + + +**Extras** +This node is only simple ray marching example, the true power of raymarching can only be achieved by custom SDFs. At the moment I am unable to inject the custom code via visual shaders, so I have provided the custom template at the following location.

    + +The default location can be found at
    +`res://addons/ShaderLib/RayMarching/RayMarchCustom.gdshaderinc` + +You can copy the code from `RayMarchCustom.gdshaderinc` and then create a Global Expression/i> node and paste it in your visual shader.
    +![Global Expression Node](GlobalExpression.jpg)
    +Lastly you also need to create an Expression/i> node, define required input and output parameters and call the custom ray marching function as below.
    +![Expression Node](Expression.jpg) +___ From b9bd4c3a3df0762532170296a15a453c8a9f5d09 Mon Sep 17 00:00:00 2001 From: Digvijaysinh Gohil Date: Wed, 27 Mar 2024 11:23:17 +0530 Subject: [PATCH 18/20] Ray marching node finalized --- addons/ShaderLib/RayMarching/RayMarch.gd | 242 ++++++++++++++---- ...gdshaderinc => RayMarchCustom.gdshaderinc} | 11 +- .../RayMarching/RayMarchRotation.gdshaderinc | 7 + .../ShaderLib/RayMarching/SDBox.gdshaderinc | 21 ++ .../RayMarching/SDCapsule.gdshaderinc | 33 +++ .../RayMarching/SDCylinder.gdshaderinc | 37 +++ .../RayMarching/SDSphere.gdshaderinc | 23 ++ .../ShaderLib/RayMarching/SDTorus.gdshaderinc | 21 ++ documentation/Nodes/RayMarching/RayMarch.md | 8 +- 9 files changed, 354 insertions(+), 49 deletions(-) rename addons/ShaderLib/RayMarching/{RayMarch.gdshaderinc => RayMarchCustom.gdshaderinc} (54%) create mode 100644 addons/ShaderLib/RayMarching/RayMarchRotation.gdshaderinc create mode 100644 addons/ShaderLib/RayMarching/SDBox.gdshaderinc create mode 100644 addons/ShaderLib/RayMarching/SDCapsule.gdshaderinc create mode 100644 addons/ShaderLib/RayMarching/SDCylinder.gdshaderinc create mode 100644 addons/ShaderLib/RayMarching/SDSphere.gdshaderinc create mode 100644 addons/ShaderLib/RayMarching/SDTorus.gdshaderinc diff --git a/addons/ShaderLib/RayMarching/RayMarch.gd b/addons/ShaderLib/RayMarching/RayMarch.gd index 7fea588..acab6b9 100644 --- a/addons/ShaderLib/RayMarching/RayMarch.gd +++ b/addons/ShaderLib/RayMarching/RayMarch.gd @@ -8,52 +8,170 @@ func _get_category() -> String: return "RayMarching" func _get_description() -> String: - return "A simple ray marcher." + return "A simple ray marcher for primitive shapes." func _get_return_icon_type() -> PortType: return PORT_TYPE_SCALAR func _get_input_port_count() -> int: - return 6 + var sdf_index: int = get_option_index(0) + match sdf_index: + 2, 3, 4: + return 9 + _: + return 8 func _get_input_port_name(port: int) -> String: - match port: - 0: - return "signed distance" - 1: - return "ray origin" - 2: - return "ray direction" - 3: - return "max steps" - 4: - return "max distance" + var sdf_index: int = get_option_index(0) + match sdf_index: + 0, 1: + match port: + 0: + return "ray origin" + 1: + return "ray direction" + 2: + return "max steps" + 3: + return "max distance" + 4: + return "distance threshold" + 5: + return "cube pos" if sdf_index == 0 else "sphere pos" + 6: + return "cube eulers" if sdf_index == 0 else "sphere eulers" + _: + return "cube scale" if sdf_index == 0 else "sphere scale" + 2, 3: + match port: + 0: + return "ray origin" + 1: + return "ray direction" + 2: + return "max steps" + 3: + return "max distance" + 4: + return "distance threshold" + 5: + return "capsule pos" if sdf_index == 2 else "cylinder pos" + 6: + return "capsule eulers" if sdf_index == 2 else "cylinder eulers" + 7: + return "capsule height" if sdf_index == 2 else "cylinder height" + _: + return "capsule radius" if sdf_index == 2 else "cylinder radius" _: - return "distance threshold" + match port: + 0: + return "ray origin" + 1: + return "ray direction" + 2: + return "max steps" + 3: + return "max distance" + 4: + return "distance threshold" + 5: + return "torus pos" + 6: + return "torus eulers" + 7: + return "torus small radius" + _: + return "torus big radius" func _get_input_port_type(port: int) -> PortType: - match port: - 1, 2: - return PORT_TYPE_VECTOR_3D - 3: - return PORT_TYPE_SCALAR_INT + var sdf_index: int = get_option_index(0) + match sdf_index: + 0, 1: + match port: + 0, 1, 5, 6, 7: + return PORT_TYPE_VECTOR_3D + 2: + return PORT_TYPE_SCALAR_INT + _: + return PORT_TYPE_SCALAR + 2, 3: + match port: + 0, 1, 5, 6: + return PORT_TYPE_VECTOR_3D + 2: + return PORT_TYPE_SCALAR_INT + _: + return PORT_TYPE_SCALAR _: - return PORT_TYPE_SCALAR + match port: + 0, 1, 5, 6: + return PORT_TYPE_VECTOR_3D + 2: + return PORT_TYPE_SCALAR_INT + _: + return PORT_TYPE_SCALAR func _get_input_port_default_value(port: int) -> Variant: - match port: - 1: - return Vector3(0, 0, -1) - 2: - return Vector3(0 ,0 ,0) - 3: - return 15 - 4: - return 15.0 - 5: - return 1e-2 + var sdf_index: int = get_option_index(0) + match sdf_index: + 0, 1: + match port: + 0, 5, 6: + return Vector3(0, 0, 0) + 1: + return Vector3(0 ,0 ,-1) + 2: + return 15 + 3: + return 15.0 + 7: + return Vector3(0.3, 0.3, 0.3) + _: + return 1e-2 + 2, 3: + match port: + 0, 5, 6: + return Vector3(0, 0, 0) + 1: + return Vector3(0 ,0 ,-1) + 2: + return 15 + 3: + return 15.0 + 4: + return 1e-2 + 7: + return .5 if sdf_index == 2 else 1.0 + _: + return .3 _: - return null + match port: + 0, 5, 6: + return Vector3(0, 0, 0) + 1: + return Vector3(0 ,0 ,-1) + 2: + return 15 + 3: + return 15.0 + 4: + return 1e-2 + 7: + return 0.1 + _: + return 0.4 + +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 "SDF" + +func _get_property_options(index: int) -> PackedStringArray: + return ["SDBox", "SDSphere", "SDCapsule", "SDCylinder", "SDTorus"] func _get_output_port_count() -> int: return 1 @@ -65,19 +183,57 @@ func _get_output_port_type(port: int) -> PortType: return PORT_TYPE_SCALAR func _get_global_code(mode: Shader.Mode) -> String: - var code: String = preload("RayMarch.gdshaderinc").code + var code: String + var sdf_index: int = get_option_index(0) + code = preload("RayMarchRotation.gdshaderinc").code + match sdf_index: + 0: + code += preload("SDBox.gdshaderinc").code + 1: + code += preload("SDSphere.gdshaderinc").code + 2: + code += preload("SDCapsule.gdshaderinc").code + 3: + code += preload("SDCylinder.gdshaderinc").code + _: + code += preload("SDTorus.gdshaderinc").code return code func _get_code(input_vars: Array[String], output_vars: Array[String], mode: Shader.Mode, type: VisualShader.Type) -> String: - var signed_distance: String = "0.0" + var sdf_index: int = get_option_index(0) + var ray_origin: String = input_vars[0] + var ray_direction: String = input_vars[1] + var max_steps: String = input_vars[2] + var max_dist: String = input_vars[3] + var dist_threshold: String = input_vars[4] - if input_vars[0]: - signed_distance = input_vars[0] + match sdf_index: + 0: + var cube_pos: String = input_vars[5] + var eulers: String = input_vars[6] + var size: String = input_vars[7] + return output_vars[0] + " = ray_march_sd_box(%s, %s, %s, %s, %s, %s, %s, %s);" % [ray_origin, ray_direction, max_steps, max_dist, dist_threshold, cube_pos, eulers, size] + 1: + var sphere_pos: String = input_vars[5] + var eulers: String = input_vars[6] + var scale: String = input_vars[7] + return output_vars[0] + " = ray_march_sd_sphere(%s, %s, %s, %s, %s, %s, %s, %s);" % [ray_origin, ray_direction, max_steps, max_dist, dist_threshold, sphere_pos, eulers, scale] + 2: + var capsule_pos: String = input_vars[5] + var capsule_eulers: String = input_vars[6] + var capsule_height: String = input_vars[7] + var capsule_radius: String = input_vars[8] + return output_vars[0] + " = ray_march_sd_capsule(%s, %s, %s, %s, %s, %s, %s, %s, %s);" % [ray_origin, ray_direction, max_steps, max_dist, dist_threshold, capsule_pos, capsule_height, capsule_radius, capsule_eulers] + 3: + var cylinder_pos: String = input_vars[5] + var cylinder_eulers: String = input_vars[6] + var cylinder_height: String = input_vars[7] + var cylinder_radius: String = input_vars[8] + return output_vars[0] + " = ray_march_sd_cylinder(%s, %s, %s, %s, %s, %s, %s, %s, %s);" % [ray_origin, ray_direction, max_steps, max_dist, dist_threshold, cylinder_pos, cylinder_height, cylinder_radius, cylinder_eulers] + _: + var torus_pos: String = input_vars[5] + var eulers: String = input_vars[6] + var small_radius: String = input_vars[7] + var big_radius: String = input_vars[8] + return output_vars[0] + " = ray_march_sd_torus(%s, %s, %s, %s, %s, %s, %s, %s, %s);" % [ray_origin, ray_direction, max_steps, max_dist, dist_threshold, torus_pos, eulers, small_radius, big_radius] - var ray_origin: String = input_vars[1] - var ray_direction: String = input_vars[2] - var max_steps: String = input_vars[3] - var max_dist: String = input_vars[4] - var dist_threshold: String = input_vars[5] - - return output_vars[0] + " = ray_march(%s, %s, %s, %s, %s, %s);" % [ray_origin, ray_direction, max_steps, max_dist, dist_threshold, signed_distance] diff --git a/addons/ShaderLib/RayMarching/RayMarch.gdshaderinc b/addons/ShaderLib/RayMarching/RayMarchCustom.gdshaderinc similarity index 54% rename from addons/ShaderLib/RayMarching/RayMarch.gdshaderinc rename to addons/ShaderLib/RayMarching/RayMarchCustom.gdshaderinc index c24a18f..1a46c9e 100644 --- a/addons/ShaderLib/RayMarching/RayMarch.gdshaderinc +++ b/addons/ShaderLib/RayMarching/RayMarchCustom.gdshaderinc @@ -1,11 +1,18 @@ -float ray_march(vec3 ray_origin, vec3 ray_dir, int max_steps, float max_dist, float dist_threshold, float signed_dist) { +float sdf_custom(vec3 p) { + // Basic example of Sphere SDF with radius of .3 + // Put your custom logic here + float radius = .3; + return length(p) - radius; +} + +float ray_march_custom(vec3 ray_origin, vec3 ray_dir, int max_steps, float max_dist, float dist_threshold) { ray_dir = normalize(ray_dir); dist_threshold = abs(dist_threshold); float dist_from_origin = 0.; float dist_to_surface; for(int i = 0; i < max_steps; i++) { vec3 point = ray_origin + dist_from_origin * ray_dir; - dist_to_surface = signed_dist; + dist_to_surface = sdf_custom(point); dist_from_origin += dist_to_surface; if(dist_to_surface < dist_threshold || dist_to_surface > max_dist) break; diff --git a/addons/ShaderLib/RayMarching/RayMarchRotation.gdshaderinc b/addons/ShaderLib/RayMarching/RayMarchRotation.gdshaderinc new file mode 100644 index 0000000..6f88c7e --- /dev/null +++ b/addons/ShaderLib/RayMarching/RayMarchRotation.gdshaderinc @@ -0,0 +1,7 @@ +mat2 rm_rotation(float angle) { + angle = -angle * (3.1415926 / 180.); + return mat2( + vec2(cos(angle), -sin(angle)), + vec2(sin(angle), cos(angle)) + ); +} diff --git a/addons/ShaderLib/RayMarching/SDBox.gdshaderinc b/addons/ShaderLib/RayMarching/SDBox.gdshaderinc new file mode 100644 index 0000000..3da6be7 --- /dev/null +++ b/addons/ShaderLib/RayMarching/SDBox.gdshaderinc @@ -0,0 +1,21 @@ +float sd_box(vec3 point, vec3 size, vec3 eulers) { + point.yz *= rm_rotation(eulers.x); + point.xy *= rm_rotation(eulers.z); + point.xz *= rm_rotation(-eulers.y); + return length(max(abs(point) - size, vec3(0))); +} + +float ray_march_sd_box(vec3 ray_origin, vec3 ray_dir, int max_steps, float max_dist, float dist_threshold, vec3 cube_pos, vec3 eulers, vec3 size) { + ray_dir = normalize(ray_dir); + dist_threshold = abs(dist_threshold); + float dist_from_origin = 0.; + float dist_to_surface; + for(int i = 0; i < max_steps; i++) { + vec3 point = ray_origin + dist_from_origin * ray_dir; + dist_to_surface = sd_box(point - cube_pos, size, eulers); + dist_from_origin += dist_to_surface; + if(dist_to_surface < dist_threshold || dist_to_surface > max_dist) + break; + } + return dist_from_origin; +} \ No newline at end of file diff --git a/addons/ShaderLib/RayMarching/SDCapsule.gdshaderinc b/addons/ShaderLib/RayMarching/SDCapsule.gdshaderinc new file mode 100644 index 0000000..75d56d9 --- /dev/null +++ b/addons/ShaderLib/RayMarching/SDCapsule.gdshaderinc @@ -0,0 +1,33 @@ +float sd_capsule(vec3 point, vec3 capsule_pos, float height, float radius, vec3 eulers) { + vec3 orientation = vec3(0, 1, 0); + orientation.yz *= rm_rotation(eulers.x); + orientation.xy *= rm_rotation(eulers.z); + orientation.xz *= rm_rotation(-eulers.y); + + vec3 top_point = point + orientation * (height * .5); + vec3 bottom_point = point - orientation * (height * .5); + + vec3 height_vector = bottom_point - top_point; + vec3 top_distance = capsule_pos - top_point; + + float t = dot(height_vector, top_distance) / dot(height_vector, height_vector); + t = clamp(t, 0., 1.); + vec3 hit_point = top_point + t * height_vector; + + return length(capsule_pos - hit_point) - radius; +} + +float ray_march_sd_capsule(vec3 ray_origin, vec3 ray_dir, int max_steps, float max_dist, float dist_threshold, vec3 capsule_pos, float capsule_height, float capsule_radius, vec3 eulers) { + ray_dir = normalize(ray_dir); + dist_threshold = abs(dist_threshold); + float dist_from_origin = 0.; + float dist_to_surface; + for(int i = 0; i < max_steps; i++) { + vec3 point = ray_origin + dist_from_origin * ray_dir; + dist_to_surface = sd_capsule(point, capsule_pos, capsule_height, capsule_radius, eulers); + dist_from_origin += dist_to_surface; + if(dist_to_surface < dist_threshold || dist_to_surface > max_dist) + break; + } + return dist_from_origin; +} \ No newline at end of file diff --git a/addons/ShaderLib/RayMarching/SDCylinder.gdshaderinc b/addons/ShaderLib/RayMarching/SDCylinder.gdshaderinc new file mode 100644 index 0000000..0b5316e --- /dev/null +++ b/addons/ShaderLib/RayMarching/SDCylinder.gdshaderinc @@ -0,0 +1,37 @@ +float sd_cylinder(vec3 point, vec3 cylinder_pos, float height, float radius, vec3 eulers) { + vec3 orientation = vec3(0, 1, 0); + orientation.yz *= rm_rotation(eulers.x); + orientation.xy *= rm_rotation(eulers.z); + orientation.xz *= rm_rotation(-eulers.y); + + vec3 top_point = point + orientation * (height * .5); + vec3 bottom_point = point - orientation * (height * .5); + + vec3 height_vector = bottom_point - top_point; + vec3 top_distance = cylinder_pos - top_point; + + float t = dot(height_vector, top_distance) / dot(height_vector, height_vector); + vec3 hit_point = top_point + t * height_vector; + + float x = length(cylinder_pos - hit_point) - radius; + float y = (abs(t - .5) - .5) * length(height_vector); + float e = length(max(vec2(x, y), 0)); + float i = min(max(x, y), 0.); + + return e + i; +} + +float ray_march_sd_cylinder(vec3 ray_origin, vec3 ray_dir, int max_steps, float max_dist, float dist_threshold, vec3 cylinder_pos, float cylinder_height, float cylinder_radius, vec3 eulers) { + ray_dir = normalize(ray_dir); + dist_threshold = abs(dist_threshold); + float dist_from_origin = 0.; + float dist_to_surface; + for(int i = 0; i < max_steps; i++) { + vec3 point = ray_origin + dist_from_origin * ray_dir; + dist_to_surface = sd_cylinder(point, cylinder_pos, cylinder_height, cylinder_radius, eulers); + dist_from_origin += dist_to_surface; + if(dist_to_surface < dist_threshold || dist_to_surface > max_dist) + break; + } + return dist_from_origin; +} \ No newline at end of file diff --git a/addons/ShaderLib/RayMarching/SDSphere.gdshaderinc b/addons/ShaderLib/RayMarching/SDSphere.gdshaderinc new file mode 100644 index 0000000..7319423 --- /dev/null +++ b/addons/ShaderLib/RayMarching/SDSphere.gdshaderinc @@ -0,0 +1,23 @@ +float sd_sphere(vec3 point, vec3 eulers, vec3 scale) { + float radius = 1.; + point.yz *= rm_rotation(eulers.x); + point.xy *= rm_rotation(eulers.z); + point.xz *= rm_rotation(-eulers.y); + point /= scale; + return (length(point) - radius) * min(scale.x, min(scale.y, scale.z)); +} + +float ray_march_sd_sphere(vec3 ray_origin, vec3 ray_dir, int max_steps, float max_dist, float dist_threshold, vec3 sphere_pos, vec3 eulers, vec3 scale) { + ray_dir = normalize(ray_dir); + dist_threshold = abs(dist_threshold); + float dist_from_origin = 0.; + float dist_to_surface; + for(int i = 0; i < max_steps; i++) { + vec3 point = ray_origin + dist_from_origin * ray_dir; + dist_to_surface = sd_sphere(point - sphere_pos, eulers, scale); + dist_from_origin += dist_to_surface; + if(dist_to_surface < dist_threshold || dist_to_surface > max_dist) + break; + } + return dist_from_origin; +} \ No newline at end of file diff --git a/addons/ShaderLib/RayMarching/SDTorus.gdshaderinc b/addons/ShaderLib/RayMarching/SDTorus.gdshaderinc new file mode 100644 index 0000000..37c9746 --- /dev/null +++ b/addons/ShaderLib/RayMarching/SDTorus.gdshaderinc @@ -0,0 +1,21 @@ +float sd_torus(vec3 point, float small_radius, float big_radius, vec3 eulers) { + point.yz *= rm_rotation(eulers.x); + point.xy *= rm_rotation(eulers.z); + point.xz *= rm_rotation(-eulers.y); + return length(vec2(length(point.xz) - big_radius, point.y)) - small_radius; +} + +float ray_march_sd_torus(vec3 ray_origin, vec3 ray_dir, int max_steps, float max_dist, float dist_threshold, vec3 torus_pos, vec3 eulers, float small_radius, float big_radius) { + ray_dir = normalize(ray_dir); + dist_threshold = abs(dist_threshold); + float dist_from_origin = 0.; + float dist_to_surface; + for(int i = 0; i < max_steps; i++) { + vec3 point = ray_origin + dist_from_origin * ray_dir; + dist_to_surface = sd_torus(point - torus_pos, small_radius, big_radius, eulers); + dist_from_origin += dist_to_surface; + if(dist_to_surface < dist_threshold || dist_to_surface > max_dist) + break; + } + return dist_from_origin; +} \ No newline at end of file diff --git a/documentation/Nodes/RayMarching/RayMarch.md b/documentation/Nodes/RayMarching/RayMarch.md index e7ce218..b95dc44 100644 --- a/documentation/Nodes/RayMarching/RayMarch.md +++ b/documentation/Nodes/RayMarching/RayMarch.md @@ -52,8 +52,8 @@ This node is only simple ray marching example, the true power of raymarching can The default location can be found at
    `res://addons/ShaderLib/RayMarching/RayMarchCustom.gdshaderinc` -You can copy the code from `RayMarchCustom.gdshaderinc` and then create a Global Expression/i> node and paste it in your visual shader.
    -![Global Expression Node](GlobalExpression.jpg)
    -Lastly you also need to create an Expression/i> node, define required input and output parameters and call the custom ray marching function as below.
    -![Expression Node](Expression.jpg) +You can copy the code from `RayMarchCustom.gdshaderinc` and then create a Global Expression node and paste it in your visual shader.

    +![Global Expression Node](GlobalExpression.jpg)

    +Lastly you also need to create an Expression node, define required input and output parameters and call the custom ray marching function as below.

    +![Expression Node](Expression.jpg)
    ___ From 6f447b39aff7e79d3c633c666dabfe24bc8bbca0 Mon Sep 17 00:00:00 2001 From: Digvijaysinh Gohil Date: Wed, 27 Mar 2024 11:25:12 +0530 Subject: [PATCH 19/20] Update RayMarch.md --- documentation/Nodes/RayMarching/RayMarch.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/documentation/Nodes/RayMarching/RayMarch.md b/documentation/Nodes/RayMarching/RayMarch.md index b95dc44..95246fc 100644 --- a/documentation/Nodes/RayMarching/RayMarch.md +++ b/documentation/Nodes/RayMarching/RayMarch.md @@ -43,11 +43,9 @@ A simple ray marcher for primitive shapes. |Name|Type|Binding|Description| |---|---|---|---| |distance|float|None|Ray intersection distance| -___ - **Extras** -This node is only simple ray marching example, the true power of raymarching can only be achieved by custom SDFs. At the moment I am unable to inject the custom code via visual shaders, so I have provided the custom template at the following location.

    +This node is only simple ray marching example, the true power of raymarching can only be achieved by custom SDFs. At the moment I am unable to inject the custom code via visual shaders, so I have provided the custom template at the following location.
    The default location can be found at
    `res://addons/ShaderLib/RayMarching/RayMarchCustom.gdshaderinc` From 57d3027b6c4eb8b7edaf0271b6ed801f667b0484 Mon Sep 17 00:00:00 2001 From: Digvijaysinh Gohil Date: Wed, 27 Mar 2024 11:44:59 +0530 Subject: [PATCH 20/20] Update RayMarch.md --- documentation/Nodes/RayMarching/RayMarch.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/documentation/Nodes/RayMarching/RayMarch.md b/documentation/Nodes/RayMarching/RayMarch.md index 95246fc..0e5ba62 100644 --- a/documentation/Nodes/RayMarching/RayMarch.md +++ b/documentation/Nodes/RayMarching/RayMarch.md @@ -44,8 +44,9 @@ A simple ray marcher for primitive shapes. |---|---|---|---| |distance|float|None|Ray intersection distance| -**Extras** -This node is only simple ray marching example, the true power of raymarching can only be achieved by custom SDFs. At the moment I am unable to inject the custom code via visual shaders, so I have provided the custom template at the following location.
    +
    +

    Extras

    +This node is only simple ray marching example, the true power of raymarching can only be achieved by custom SDFs. At the moment I am unable to inject the custom code via visual shaders, so I have provided the custom template at the following location.

    The default location can be found at
    `res://addons/ShaderLib/RayMarching/RayMarchCustom.gdshaderinc`