Added FastNoise2 to VoxelGeneratorGraph

This commit is contained in:
Marc Gilleron 2021-12-31 18:23:42 +00:00
parent 666b9eb7e8
commit 204b64ac23
5 changed files with 117 additions and 0 deletions

View File

@ -1608,5 +1608,7 @@ void VoxelGeneratorGraph::_bind_methods() {
BIND_ENUM_CONSTANT(NODE_FAST_NOISE_GRADIENT_2D);
BIND_ENUM_CONSTANT(NODE_FAST_NOISE_GRADIENT_3D);
BIND_ENUM_CONSTANT(NODE_OUTPUT_WEIGHT);
BIND_ENUM_CONSTANT(NODE_FAST_NOISE_2_2D);
BIND_ENUM_CONSTANT(NODE_FAST_NOISE_2_3D);
BIND_ENUM_CONSTANT(NODE_TYPE_COUNT);
}

View File

@ -55,6 +55,9 @@ public:
NODE_FAST_NOISE_GRADIENT_2D,
NODE_FAST_NOISE_GRADIENT_3D,
NODE_OUTPUT_WEIGHT,
NODE_FAST_NOISE_2_2D,
NODE_FAST_NOISE_2_3D,
NODE_TYPE_COUNT
};

View File

@ -1,5 +1,6 @@
#include "voxel_graph_node_db.h"
#include "../../util/math/sdf.h"
#include "../../util/noise/fast_noise_2.h"
#include "../../util/noise/fast_noise_lite.h"
#include "../../util/profiling.h"
#include "image_range_grid.h"
@ -1595,6 +1596,103 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
ctx.set_output(2, r.z);
};
}
{
struct Params {
FastNoise2 *noise;
};
NodeType &t = types[VoxelGeneratorGraph::NODE_FAST_NOISE_2_2D];
t.name = "FastNoise2_2D";
t.category = CATEGORY_GENERATE;
t.inputs.push_back(Port("x"));
t.inputs.push_back(Port("y"));
t.outputs.push_back(Port("out"));
t.params.push_back(Param("noise", "FastNoise2"));
t.compile_func = [](CompileContext &ctx) {
Ref<FastNoise2> noise = ctx.get_param(0);
if (noise.is_null()) {
ctx.make_error("FastNoise2 instance is null");
return;
}
noise->update_generator();
if (!noise->is_valid()) {
ctx.make_error("FastNoise2 setup is invalid");
return;
}
Params p;
p.noise = *noise;
ctx.set_params(p);
};
t.process_buffer_func = [](ProcessBufferContext &ctx) {
VOXEL_PROFILE_SCOPE_NAMED("NODE_FAST_NOISE_2_2D");
const VoxelGraphRuntime::Buffer &x = ctx.get_input(0);
const VoxelGraphRuntime::Buffer &y = ctx.get_input(1);
VoxelGraphRuntime::Buffer &out = ctx.get_output(0);
const Params p = ctx.get_params<Params>();
p.noise->get_noise_2d_series(Span<const float>(x.data, x.size), Span<const float>(y.data, y.size),
Span<float>(out.data, out.size));
};
t.range_analysis_func = [](RangeAnalysisContext &ctx) {
const Interval x = ctx.get_input(0);
const Interval y = ctx.get_input(1);
const Params p = ctx.get_params<Params>();
ERR_FAIL_COND(p.noise == nullptr);
ctx.set_output(0, p.noise->get_estimated_output_range());
};
}
{
struct Params {
FastNoise2 *noise;
};
NodeType &t = types[VoxelGeneratorGraph::NODE_FAST_NOISE_2_3D];
t.name = "FastNoise2_3D";
t.category = CATEGORY_GENERATE;
t.inputs.push_back(Port("x"));
t.inputs.push_back(Port("y"));
t.inputs.push_back(Port("z"));
t.outputs.push_back(Port("out"));
t.params.push_back(Param("noise", "FastNoise2"));
t.compile_func = [](CompileContext &ctx) {
Ref<FastNoise2> noise = ctx.get_param(0);
if (noise.is_null()) {
ctx.make_error("FastNoise2 instance is null");
return;
}
noise->update_generator();
if (!noise->is_valid()) {
ctx.make_error("FastNoise2 setup is invalid");
return;
}
Params p;
p.noise = *noise;
ctx.set_params(p);
};
t.process_buffer_func = [](ProcessBufferContext &ctx) {
VOXEL_PROFILE_SCOPE_NAMED("NODE_FAST_NOISE_2_3D");
const VoxelGraphRuntime::Buffer &x = ctx.get_input(0);
const VoxelGraphRuntime::Buffer &y = ctx.get_input(1);
const VoxelGraphRuntime::Buffer &z = ctx.get_input(2);
VoxelGraphRuntime::Buffer &out = ctx.get_output(0);
const Params p = ctx.get_params<Params>();
p.noise->get_noise_3d_series(Span<const float>(x.data, x.size), Span<const float>(y.data, y.size),
Span<const float>(z.data, z.size), Span<float>(out.data, out.size));
};
t.range_analysis_func = [](RangeAnalysisContext &ctx) {
const Interval x = ctx.get_input(0);
const Interval y = ctx.get_input(1);
const Interval z = ctx.get_input(2);
const Params p = ctx.get_params<Params>();
ERR_FAIL_COND(p.noise == nullptr);
ctx.set_output(0, p.noise->get_estimated_output_range());
};
}
for (unsigned int i = 0; i < _types.size(); ++i) {
NodeType &t = _types[i];

View File

@ -465,6 +465,17 @@ void FastNoise2::update_generator() {
_generator = generator_node;
}
Interval FastNoise2::get_estimated_output_range() const {
// TODO Optimize: better range analysis on FastNoise2
// Most noises should have known bounds like FastNoiseLite, but the node-graph nature of this library
// can make it difficult to calculate. Would be nice if the library could provide that out of the box.
if (is_remap_enabled()) {
return Interval(get_remap_output_min(), get_remap_output_max());
} else {
return Interval(-1.f, 1.f);
}
}
String FastNoise2::_b_get_simd_level_name(SIMDLevel level) {
return get_simd_level_name(level);
}

View File

@ -1,6 +1,7 @@
#ifndef VOXEL_FAST_NOISE_2_H
#define VOXEL_FAST_NOISE_2_H
#include "../math/interval.h"
#include "../span.h"
#include "FastNoise/FastNoise.h"
#include <core/io/resource.h>
@ -166,6 +167,8 @@ public:
void generate_image(Ref<Image> image, bool tileable) const;
Interval get_estimated_output_range() const;
private:
// Non-static method for scripts because Godot4 does not support binding static methods (it's only implemented for
// primitive types)