mirror of
https://github.com/DigvijaysinhGohil/Godot-Shader-Lib.git
synced 2025-09-19 20:05:57 +08:00
Voronoi node revamped
This commit is contained in:
@ -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]
|
||||
|
@ -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;
|
||||
}
|
Reference in New Issue
Block a user