FBM noise node.

This commit is contained in:
Relintai 2021-10-19 13:43:35 +02:00
parent fb502505a3
commit 8feda525db
4 changed files with 174 additions and 66 deletions

View File

@ -2,7 +2,7 @@
[ext_resource path="res://addons/mat_maker_gd/nodes/mm_material.gd" type="Script" id=1] [ext_resource path="res://addons/mat_maker_gd/nodes/mm_material.gd" type="Script" id=1]
[ext_resource path="res://addons/mat_maker_gd/nodes/noise/noise.gd" type="Script" id=2] [ext_resource path="res://addons/mat_maker_gd/nodes/noise/noise.gd" type="Script" id=2]
[ext_resource path="res://addons/mat_maker_gd/nodes/noise/value.gd" type="Script" id=3] [ext_resource path="res://addons/mat_maker_gd/nodes/noise/fbm_noise.gd" type="Script" id=3]
[ext_resource path="res://addons/mat_maker_gd/nodes/simple/shape.gd" type="Script" id=4] [ext_resource path="res://addons/mat_maker_gd/nodes/simple/shape.gd" type="Script" id=4]
[ext_resource path="res://addons/mat_maker_gd/nodes/mm_node_universal_property.gd" type="Script" id=5] [ext_resource path="res://addons/mat_maker_gd/nodes/mm_node_universal_property.gd" type="Script" id=5]
[ext_resource path="res://addons/mat_maker_gd/nodes/other/output_image.gd" type="Script" id=6] [ext_resource path="res://addons/mat_maker_gd/nodes/other/output_image.gd" type="Script" id=6]

View File

@ -52,6 +52,11 @@ static func perlinabs(uv : Vector2, size : Vector2, folds : int, octaves : int,
return Color(f, f, f, 1) return Color(f, f, f, 1)
static func simplex(uv : Vector2, size : Vector2, folds : int, octaves : int, persistence : float, pseed : float) -> Color:
var f : float = fbm_simplexf(uv, size, folds, octaves, persistence, pseed)
return Color(f, f, f, 1)
static func cellular(uv : Vector2, size : Vector2, folds : int, octaves : int, persistence : float, pseed : float) -> Color: static func cellular(uv : Vector2, size : Vector2, folds : int, octaves : int, persistence : float, pseed : float) -> Color:
var f : float = cellularf(uv, size, folds, octaves, persistence, pseed) var f : float = cellularf(uv, size, folds, octaves, persistence, pseed)
@ -137,6 +142,24 @@ static func perlinabsf(coord : Vector2, size : Vector2, folds : int, octaves : i
return value / normalize_factor; return value / normalize_factor;
static func fbm_simplexf(coord : Vector2, size : Vector2, folds : int, octaves : int, persistence : float, pseed : float) -> float:
var normalize_factor : float = 0.0;
var value : float = 0.0;
var scale : float = 1.0;
for i in range(octaves):# (int i = 0; i < octaves; i++) {
var noise : float = fbm_simplex(coord*size, size, pseed)
for j in range(folds):# (int f = 0; f < folds; ++f) {
noise = abs(2.0*noise-1.0);
value += noise * scale
normalize_factor += scale;
size *= 2.0;
scale *= persistence;
return value / normalize_factor;
static func cellularf(coord : Vector2, size : Vector2, folds : int, octaves : int, persistence : float, pseed : float) -> float: static func cellularf(coord : Vector2, size : Vector2, folds : int, octaves : int, persistence : float, pseed : float) -> float:
var normalize_factor : float = 0.0; var normalize_factor : float = 0.0;
var value : float = 0.0; var value : float = 0.0;
@ -328,7 +351,12 @@ static func fbm_perlinabs(coord : Vector2, size : Vector2, pseed : float) -> flo
# u = fract(u) * 6.28318530718; // 2*pi # u = fract(u) * 6.28318530718; // 2*pi
# return vec2(cos(u), sin(u)); # return vec2(cos(u), sin(u));
#} #}
#
static func rgrad2(p : Vector2, rot : float, pseed : float) -> Vector2:
var u : float = Commons.rand(p + Vector2(pseed, 1.0-pseed));
u = Commons.fract(u) * 6.28318530718; # 2*pi
return Vector2(cos(u), sin(u))
#float fbm_simplex(vec2 coord, vec2 size, float seed) { #float fbm_simplex(vec2 coord, vec2 size, float seed) {
# coord *= 2.0; // needed for it to tile # coord *= 2.0; // needed for it to tile
# coord += rand2(vec2(seed, 1.0-seed)) + size; # coord += rand2(vec2(seed, 1.0-seed)) + size;
@ -371,8 +399,51 @@ static func fbm_perlinabs(coord : Vector2, size : Vector2, pseed : float) -> flo
#} #}
static func fbm_simplex(coord : Vector2, size : Vector2, pseed : float) -> float: static func fbm_simplex(coord : Vector2, size : Vector2, pseed : float) -> float:
#TODO coord *= 2.0; # needed for it to tile
return 0.0 coord += Commons.rand2(Vector2(pseed, 1.0-pseed)) + size;
size *= 2.0; # needed for it to tile
coord.y += 0.001;
var uv : Vector2 = Vector2(coord.x + coord.y*0.5, coord.y);
var i0 : Vector2 = Commons.floorv2(uv);
var f0 : Vector2 = Commons.fractv2(uv);
var i1 : Vector2
if (f0.x > f0.y):
i1 = Vector2(1.0, 0.0)
else:
i1 = Vector2(0.0, 1.0);
var p0 : Vector2 = Vector2(i0.x - i0.y * 0.5, i0.y);
var p1 : Vector2 = Vector2(p0.x + i1.x - i1.y * 0.5, p0.y + i1.y);
var p2 : Vector2 = Vector2(p0.x + 0.5, p0.y + 1.0);
i1 = i0 + i1;
var i2 : Vector2 = i0 + Vector2(1.0, 1.0);
var d0 : Vector2 = coord - p0;
var d1 : Vector2 = coord - p1;
var d2 : Vector2 = coord - p2;
var xw : Vector3 = Commons.modv3(Vector3(p0.x, p1.x, p2.x), Vector3(size.x, size.x, size.x));
var yw : Vector3 = Commons.modv3(Vector3(p0.y, p1.y, p2.y), Vector3(size.y, size.y, size.y));
var iuw : Vector3 = xw + 0.5 * yw;
var ivw : Vector3 = yw;
var g0 : Vector2 = rgrad2(Vector2(iuw.x, ivw.x), 0.0, pseed);
var g1 : Vector2 = rgrad2(Vector2(iuw.y, ivw.y), 0.0, pseed);
var g2 : Vector2 = rgrad2(Vector2(iuw.z, ivw.z), 0.0, pseed);
var w : Vector3 = Vector3(g0.dot(d0), g1.dot(d1), g2.dot(d2));
var t : Vector3 = Vector3(0.8, 0.8, 0.8) - Vector3(d0.dot(d0), d1.dot(d1), d2.dot(d2));
t = Commons.maxv3(t, Vector3());
var t2 : Vector3 = t * t;
var t4 : Vector3 = t2 * t2;
var n : float = t4.dot(w);
return 0.5 + 5.5 * n;
#float fbm_cellular(vec2 coord, vec2 size, float seed) { #float fbm_cellular(vec2 coord, vec2 size, float seed) {
# vec2 o = floor(coord)+rand2(vec2(seed, 1.0-seed))+size; # vec2 o = floor(coord)+rand2(vec2(seed, 1.0-seed))+size;

View File

@ -0,0 +1,99 @@
tool
extends MMNode
var NoiseFBM = preload("res://addons/mat_maker_gd/nodes/common/noise_fbm.gd")
export(Resource) var image : Resource
export(int, "Value,Perlin,Simplex,Cellular1,Cellular2,Cellular3,Cellular4,Cellular5,Cellular6") var type : int = 0
export(Vector2) var scale : Vector2 = Vector2(2, 2)
export(int) var folds : int = 0
export(int) var iterations : int = 5
export(float) var persistence : float = 0.5
func _init_properties():
if !image:
image = MMNodeUniversalProperty.new()
image.default_type = MMNodeUniversalProperty.MMNodeUniversalPropertyDefaultType.DEFAULT_TYPE_IMAGE
image.output_slot_type = MMNodeUniversalProperty.SlotTypes.SLOT_TYPE_IMAGE
register_output_property(image)
func _register_methods(mm_graph_node) -> void:
mm_graph_node.add_slot_texture_universal(image)
mm_graph_node.add_slot_enum("get_type", "set_type", "Type", [ "Value", "Perlin", "Simplex", "Cellular1", "Cellular2", "Cellular3", "Cellular4", "Cellular5", "Cellular6" ])#, Vector2(0, 1))
mm_graph_node.add_slot_vector2("get_scale", "set_scale", "Scale")#, Vector2(1, 10))
mm_graph_node.add_slot_int("get_folds", "set_folds", "folds")#, Vector2(0, 1))
mm_graph_node.add_slot_int("get_iterations", "set_iterations", "Iterations")#, Vector2(0, 1))
mm_graph_node.add_slot_float("get_persistence", "set_persistence", "Persistence", 0.01)#, Vector2(0, 1))
func get_value_for(uv : Vector2, pseed : int) -> Color:
var ps : float = 1.0 / float(pseed)
#"Value,Perlin,Simplex,Cellular1,Cellular2,Cellular3,Cellular4,Cellular5,Cellular6"
if type == 0:
return NoiseFBM.fbmval(uv, scale, folds, iterations, persistence, ps)
elif type == 1:
return NoiseFBM.perlin(uv, scale, folds, iterations, persistence, ps)
elif type == 2:
return NoiseFBM.simplex(uv, scale, folds, iterations, persistence, ps)
elif type == 3:
return NoiseFBM.cellular(uv, scale, folds, iterations, persistence, ps)
elif type == 4:
return NoiseFBM.cellular2(uv, scale, folds, iterations, persistence, ps)
elif type == 5:
return NoiseFBM.cellular3(uv, scale, folds, iterations, persistence, ps)
elif type == 6:
return NoiseFBM.cellular4(uv, scale, folds, iterations, persistence, ps)
elif type == 7:
return NoiseFBM.cellular5(uv, scale, folds, iterations, persistence, ps)
elif type == 8:
return NoiseFBM.cellular6(uv, scale, folds, iterations, persistence, ps)
return Color()
func _render(material) -> void:
var img : Image = render_image(material)
image.set_value(img)
func get_type() -> int:
return type
func set_type(val : int) -> void:
type = val
set_dirty(true)
func get_scale() -> Vector2:
return scale
func set_scale(val : Vector2) -> void:
scale = val
set_dirty(true)
func get_folds() -> int:
return folds
func set_folds(val : int) -> void:
folds = val
set_dirty(true)
func get_iterations() -> int:
return iterations
func set_iterations(val : int) -> void:
iterations = val
set_dirty(true)
func get_persistence() -> float:
return persistence
func set_persistence(val : float) -> void:
persistence = val
set_dirty(true)

View File

@ -1,62 +0,0 @@
tool
extends MMNode
var NoisePerlin = preload("res://addons/mat_maker_gd/nodes/common/noise_perlin.gd")
export(Resource) var image : Resource
export(Vector2) var scale : Vector2 = Vector2(4, 4)
export(int) var iterations : int = 3
export(float) var persistence : float = 0.5
func _init_properties():
if !image:
image = MMNodeUniversalProperty.new()
image.default_type = MMNodeUniversalProperty.MMNodeUniversalPropertyDefaultType.DEFAULT_TYPE_IMAGE
image.output_slot_type = MMNodeUniversalProperty.SlotTypes.SLOT_TYPE_IMAGE
register_output_property(image)
func _register_methods(mm_graph_node) -> void:
mm_graph_node.add_slot_texture_universal(image)
mm_graph_node.add_slot_vector2("get_scale", "set_scale", "Scale")#, Vector2(1, 10))
mm_graph_node.add_slot_int("get_iterations", "set_iterations", "Iterations")#, Vector2(0, 1))
mm_graph_node.add_slot_float("get_persistence", "set_persistence", "Persistence", 0.01)#, Vector2(0, 1))
func get_value_for(uv : Vector2, pseed : int) -> Color:
var ps : float = 1.0 / float(pseed)
#perlin($(uv), vec2($(scale_x), $(scale_y)), int($(iterations)), $(persistence), $(seed))
var f : float = NoisePerlin.perlin(uv, scale, iterations, persistence, ps)
return Color(f, f, f, 1)
func _render(material) -> void:
var img : Image = render_image(material)
image.set_value(img)
func get_scale() -> Vector2:
return scale
func set_scale(val : Vector2) -> void:
scale = val
set_dirty(true)
func get_iterations() -> int:
return iterations
func set_iterations(val : int) -> void:
iterations = val
set_dirty(true)
func get_persistence() -> float:
return persistence
func set_persistence(val : float) -> void:
persistence = val
set_dirty(true)