Restructure and refine the noise module

This commit is contained in:
Hendrik Brucker 2022-04-19 19:48:25 +02:00
parent 3ca4514866
commit bde6fc9c82
15 changed files with 948 additions and 288 deletions

View file

@ -27,6 +27,7 @@ env.modules_sources += thirdparty_obj
module_obj = []
env_noise.add_source_files(module_obj, "*.cpp")
env_noise.add_source_files(module_obj, "editor/*.cpp")
env.modules_sources += module_obj
# Needed to force rebuilding the module files when the thirdparty library is updated.

View file

@ -16,12 +16,9 @@
<member name="cellular_jitter" type="float" setter="set_cellular_jitter" getter="get_cellular_jitter" default="0.45">
Maximum distance a point can move off of its grid position. Set to [code]0[/code] for an even grid.
</member>
<member name="cellular_return_type" type="int" setter="set_cellular_return_type" getter="get_cellular_return_type" enum="FastNoiseLite.CellularReturnType" default="0">
<member name="cellular_return_type" type="int" setter="set_cellular_return_type" getter="get_cellular_return_type" enum="FastNoiseLite.CellularReturnType" default="1">
Return type from cellular noise calculations. See [enum CellularReturnType].
</member>
<member name="color_ramp" type="Gradient" setter="set_color_ramp" getter="get_color_ramp">
A [Gradient] which is used to map the luminance of each pixel to a color value.
</member>
<member name="domain_warp_amplitude" type="float" setter="set_domain_warp_amplitude" getter="get_domain_warp_amplitude" default="30.0">
Sets the maximum warp distance from the origin.
</member>
@ -69,9 +66,6 @@
<member name="frequency" type="float" setter="set_frequency" getter="get_frequency" default="0.01">
The frequency for all noise types. Low frequency results in smooth noise while high frequency results in rougher, more granular noise.
</member>
<member name="in_3d_space" type="bool" setter="set_in_3d_space" getter="is_in_3d_space" default="false">
Determines whether the noise image returned by [method Noise.get_image] is calculated in 3d space. May result in reduced contrast.
</member>
<member name="noise_type" type="int" setter="set_noise_type" getter="get_noise_type" enum="FastNoiseLite.NoiseType" default="1">
The noise algorithm used. See [enum NoiseType].
</member>

View file

@ -11,23 +11,24 @@
<tutorials>
</tutorials>
<methods>
<method name="get_image">
<method name="get_image" qualifiers="const">
<return type="Image" />
<argument index="0" name="width" type="int" />
<argument index="1" name="height" type="int" />
<argument index="2" name="invert" type="bool" default="false" />
<argument index="3" name="in_3d_space" type="bool" default="false" />
<description>
Returns a 2D [Image] noise image.
</description>
</method>
<method name="get_noise_1d">
<method name="get_noise_1d" qualifiers="const">
<return type="float" />
<argument index="0" name="x" type="float" />
<description>
Returns the 1D noise value at the given (x) coordinate.
</description>
</method>
<method name="get_noise_2d">
<method name="get_noise_2d" qualifiers="const">
<return type="float" />
<argument index="0" name="x" type="float" />
<argument index="1" name="y" type="float" />
@ -35,14 +36,14 @@
Returns the 2D noise value at the given position.
</description>
</method>
<method name="get_noise_2dv">
<method name="get_noise_2dv" qualifiers="const">
<return type="float" />
<argument index="0" name="v" type="Vector2" />
<description>
Returns the 2D noise value at the given position.
</description>
</method>
<method name="get_noise_3d">
<method name="get_noise_3d" qualifiers="const">
<return type="float" />
<argument index="0" name="x" type="float" />
<argument index="1" name="y" type="float" />
@ -51,19 +52,20 @@
Returns the 3D noise value at the given position.
</description>
</method>
<method name="get_noise_3dv">
<method name="get_noise_3dv" qualifiers="const">
<return type="float" />
<argument index="0" name="v" type="Vector3" />
<description>
Returns the 3D noise value at the given position.
</description>
</method>
<method name="get_seamless_image">
<method name="get_seamless_image" qualifiers="const">
<return type="Image" />
<argument index="0" name="width" type="int" />
<argument index="1" name="height" type="int" />
<argument index="2" name="invert" type="bool" default="false" />
<argument index="3" name="skirt" type="float" default="0.1" />
<argument index="3" name="in_3d_space" type="bool" default="false" />
<argument index="4" name="skirt" type="float" default="0.1" />
<description>
Returns a seamless 2D [Image] noise image.
</description>

View file

@ -24,9 +24,20 @@
<member name="bump_strength" type="float" setter="set_bump_strength" getter="get_bump_strength" default="8.0">
Strength of the bump maps used in this texture. A higher value will make the bump maps appear larger while a lower value will make them appear softer.
</member>
<member name="color_ramp" type="Gradient" setter="set_color_ramp" getter="get_color_ramp">
A [Gradient] which is used to map the luminance of each pixel to a color value.
</member>
<member name="generate_mipmaps" type="bool" setter="set_generate_mipmaps" getter="is_generating_mipmaps" default="true">
Determines whether mipmaps are generated for this texture.
Enabling this results in less texture aliasing, but the noise texture generation may take longer.
Requires (anisotropic) mipmap filtering to be enabled for a material to have an effect.
</member>
<member name="height" type="int" setter="set_height" getter="get_height" default="512">
Height of the generated texture.
</member>
<member name="in_3d_space" type="bool" setter="set_in_3d_space" getter="is_in_3d_space" default="false">
Determines whether the noise image is calculated in 3D space. May result in reduced contrast.
</member>
<member name="invert" type="bool" setter="set_invert" getter="get_invert" default="false">
If [code]true[/code], inverts the noise texture. White becomes black, black becomes white.
</member>

View file

@ -0,0 +1,149 @@
/*************************************************************************/
/* noise_editor_plugin.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "noise_editor_plugin.h"
#ifdef TOOLS_ENABLED
#include "editor/editor_scale.h"
#include "modules/noise/noise.h"
#include "modules/noise/noise_texture.h"
class NoisePreview : public Control {
GDCLASS(NoisePreview, Control)
static const int PREVIEW_HEIGHT = 150;
static const int PADDING_3D_SPACE_SWITCH = 2;
Ref<Noise> _noise;
Size2i _preview_texture_size;
TextureRect *_texture_rect = nullptr;
Button *_3d_space_switch = nullptr;
public:
NoisePreview() {
set_custom_minimum_size(Size2(0, EDSCALE * PREVIEW_HEIGHT));
_texture_rect = memnew(TextureRect);
_texture_rect->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
_texture_rect->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_COVERED);
add_child(_texture_rect);
_3d_space_switch = memnew(Button);
_3d_space_switch->set_text(TTR("3D"));
_3d_space_switch->set_tooltip(TTR("Toggles whether the noise preview is computed in 3D space."));
_3d_space_switch->set_toggle_mode(true);
_3d_space_switch->set_offset(SIDE_LEFT, PADDING_3D_SPACE_SWITCH);
_3d_space_switch->set_offset(SIDE_TOP, PADDING_3D_SPACE_SWITCH);
_3d_space_switch->connect("pressed", callable_mp(this, &NoisePreview::_on_3d_button_pressed));
add_child(_3d_space_switch);
}
void set_noise(Ref<Noise> noise) {
if (_noise == noise) {
return;
}
_noise = noise;
if (_noise.is_valid()) {
if (_noise->has_meta("_preview_in_3d_space_")) {
_3d_space_switch->set_pressed(true);
}
update_preview();
}
}
private:
void _on_3d_button_pressed() {
if (_3d_space_switch->is_pressed()) {
_noise->set_meta("_preview_in_3d_space_", true);
} else {
_noise->remove_meta("_preview_in_3d_space_");
}
}
void _notification(int p_what) {
switch (p_what) {
case NOTIFICATION_RESIZED: {
_preview_texture_size = get_size();
update_preview();
} break;
}
}
void update_preview() {
if (MIN(_preview_texture_size.width, _preview_texture_size.height) > 0) {
Ref<NoiseTexture> tex;
tex.instantiate();
tex->set_width(_preview_texture_size.width);
tex->set_height(_preview_texture_size.height);
tex->set_in_3d_space(_3d_space_switch->is_pressed());
tex->set_noise(_noise);
_texture_rect->set_texture(tex);
}
}
};
/////////////////////////////////////////////////////////////////////////////////
class NoiseEditorInspectorPlugin : public EditorInspectorPlugin {
GDCLASS(NoiseEditorInspectorPlugin, EditorInspectorPlugin)
public:
bool can_handle(Object *p_object) override {
return Object::cast_to<Noise>(p_object) != nullptr;
}
void parse_begin(Object *p_object) override {
Noise *noise_ptr = Object::cast_to<Noise>(p_object);
if (noise_ptr) {
Ref<Noise> noise(noise_ptr);
NoisePreview *viewer = memnew(NoisePreview);
viewer->set_noise(noise);
add_custom_control(viewer);
}
}
};
/////////////////////////////////////////////////////////////////////////////////
String NoiseEditorPlugin::get_name() const {
return Noise::get_class_static();
}
NoiseEditorPlugin::NoiseEditorPlugin() {
Ref<NoiseEditorInspectorPlugin> plugin;
plugin.instantiate();
add_inspector_plugin(plugin);
}
#endif // TOOLS_ENABLED

View file

@ -0,0 +1,49 @@
/*************************************************************************/
/* noise_editor_plugin.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef NOISE_EDITOR_PLUGIN_H
#define NOISE_EDITOR_PLUGIN_H
#ifdef TOOLS_ENABLED
#include "editor/editor_plugin.h"
class NoiseEditorPlugin : public EditorPlugin {
GDCLASS(NoiseEditorPlugin, EditorPlugin)
public:
String get_name() const override;
NoiseEditorPlugin();
};
#endif // TOOLS_ENABLED
#endif // NOISE_EDITOR_PLUGIN_H

View file

@ -31,31 +31,29 @@
#include "fastnoise_lite.h"
FastNoiseLite::FastNoiseLite() {
// Most defaults copied from the library.
set_noise_type(TYPE_SIMPLEX_SMOOTH);
set_seed(0);
set_frequency(0.01);
set_in_3d_space(false);
_noise.SetNoiseType((_FastNoiseLite::NoiseType)noise_type);
_noise.SetSeed(seed);
_noise.SetFrequency(frequency);
set_fractal_type(FRACTAL_FBM);
set_fractal_octaves(5);
set_fractal_lacunarity(2.0);
set_fractal_gain(0.5);
set_fractal_weighted_strength(0.0);
set_fractal_ping_pong_strength(2.0);
_noise.SetFractalType((_FastNoiseLite::FractalType)fractal_type);
_noise.SetFractalOctaves(fractal_octaves);
_noise.SetFractalLacunarity(fractal_lacunarity);
_noise.SetFractalGain(fractal_gain);
_noise.SetFractalWeightedStrength(fractal_weighted_strength);
_noise.SetFractalPingPongStrength(fractal_ping_pong_strength);
set_cellular_distance_function(DISTANCE_EUCLIDEAN);
set_cellular_return_type(RETURN_CELL_VALUE);
set_cellular_jitter(0.45);
_noise.SetCellularDistanceFunction((_FastNoiseLite::CellularDistanceFunction)cellular_distance_function);
_noise.SetCellularReturnType((_FastNoiseLite::CellularReturnType)cellular_return_type);
_noise.SetCellularJitter(cellular_jitter);
set_domain_warp_enabled(false);
set_domain_warp_type(DOMAIN_WARP_SIMPLEX);
set_domain_warp_amplitude(30.0);
set_domain_warp_frequency(0.05);
set_domain_warp_fractal_type(DOMAIN_WARP_FRACTAL_PROGRESSIVE);
set_domain_warp_fractal_octaves(5);
set_domain_warp_fractal_lacunarity(6);
set_domain_warp_fractal_gain(0.5);
_domain_warp_noise.SetDomainWarpType((_FastNoiseLite::DomainWarpType)domain_warp_type);
_domain_warp_noise.SetSeed(seed);
_domain_warp_noise.SetDomainWarpAmp(domain_warp_amplitude);
_domain_warp_noise.SetFrequency(domain_warp_frequency);
_domain_warp_noise.SetFractalType(_FastNoiseLite::FractalType_None);
_domain_warp_noise.SetFractalOctaves(domain_warp_fractal_octaves);
_domain_warp_noise.SetFractalLacunarity(domain_warp_fractal_lacunarity);
_domain_warp_noise.SetFractalGain(domain_warp_fractal_gain);
}
FastNoiseLite::~FastNoiseLite() {
@ -77,6 +75,7 @@ FastNoiseLite::NoiseType FastNoiseLite::get_noise_type() const {
void FastNoiseLite::set_seed(int p_seed) {
seed = p_seed;
_noise.SetSeed(p_seed);
_domain_warp_noise.SetSeed(p_seed);
emit_changed();
}
@ -94,14 +93,6 @@ real_t FastNoiseLite::get_frequency() const {
return frequency;
}
void FastNoiseLite::set_in_3d_space(bool p_enable) {
in_3d_space = p_enable;
emit_changed();
}
bool FastNoiseLite::is_in_3d_space() const {
return in_3d_space;
}
void FastNoiseLite::set_offset(Vector3 p_offset) {
offset = p_offset;
emit_changed();
@ -111,46 +102,6 @@ Vector3 FastNoiseLite::get_offset() const {
return offset;
}
void FastNoiseLite::set_color_ramp(const Ref<Gradient> &p_gradient) {
color_ramp = p_gradient;
if (color_ramp.is_valid()) {
color_ramp->connect(SNAME("changed"), callable_mp(this, &FastNoiseLite::_changed));
emit_changed();
}
}
Ref<Gradient> FastNoiseLite::get_color_ramp() const {
return color_ramp;
}
// Noise functions.
real_t FastNoiseLite::get_noise_1d(real_t p_x) {
return get_noise_2d(p_x, 0.0);
}
real_t FastNoiseLite::get_noise_2dv(Vector2 p_v) {
return get_noise_2d(p_v.x, p_v.y);
}
real_t FastNoiseLite::get_noise_2d(real_t p_x, real_t p_y) {
if (domain_warp_enabled) {
_domain_warp_noise.DomainWarp(p_x, p_y);
}
return _noise.GetNoise(p_x + offset.x, p_y + offset.y);
}
real_t FastNoiseLite::get_noise_3dv(Vector3 p_v) {
return get_noise_3d(p_v.x, p_v.y, p_v.z);
}
real_t FastNoiseLite::get_noise_3d(real_t p_x, real_t p_y, real_t p_z) {
if (domain_warp_enabled) {
_domain_warp_noise.DomainWarp(p_x, p_y, p_z);
}
return _noise.GetNoise(p_x + offset.x, p_y + offset.y, p_z + offset.z);
}
// Fractal.
void FastNoiseLite::set_fractal_type(FractalType p_type) {
@ -204,12 +155,12 @@ real_t FastNoiseLite::get_fractal_weighted_strength() const {
}
void FastNoiseLite::set_fractal_ping_pong_strength(real_t p_ping_pong_strength) {
fractal_pinp_pong_strength = p_ping_pong_strength;
fractal_ping_pong_strength = p_ping_pong_strength;
_noise.SetFractalPingPongStrength(p_ping_pong_strength);
emit_changed();
}
real_t FastNoiseLite::get_fractal_ping_pong_strength() const {
return fractal_pinp_pong_strength;
return fractal_ping_pong_strength;
}
// Cellular.
@ -237,7 +188,6 @@ real_t FastNoiseLite::get_cellular_jitter() const {
void FastNoiseLite::set_cellular_return_type(CellularReturnType p_ret) {
cellular_return_type = p_ret;
_noise.SetCellularReturnType((_FastNoiseLite::CellularReturnType)p_ret);
emit_changed();
}
@ -345,68 +295,32 @@ real_t FastNoiseLite::get_domain_warp_fractal_gain() const {
return domain_warp_fractal_gain;
}
// Textures.
// Noise interface functions.
Ref<Image> FastNoiseLite::get_image(int p_width, int p_height, bool p_invert) {
bool grayscale = color_ramp.is_null();
Vector<uint8_t> data;
data.resize(p_width * p_height * (grayscale ? 1 : 4));
uint8_t *wd8 = data.ptrw();
// Get all values and identify min/max values.
Vector<real_t> values;
values.resize(p_width * p_height);
real_t min_val = 100;
real_t max_val = -100;
for (int y = 0, i = 0; y < p_height; y++) {
for (int x = 0; x < p_width; x++, i++) {
values.set(i, is_in_3d_space() ? get_noise_3d(x, y, 0.0) : get_noise_2d(x, y));
if (values[i] > max_val) {
max_val = values[i];
}
if (values[i] < min_val) {
min_val = values[i];
}
}
}
// Normalize values and write to texture.
uint8_t value;
for (int i = 0, x = 0; i < p_height; i++) {
for (int j = 0; j < p_width; j++, x++) {
if (max_val == min_val) {
value = 0;
} else {
value = uint8_t(CLAMP((values[x] - min_val) / (max_val - min_val) * 255.f, 0, 255));
}
if (p_invert) {
value = 255 - value;
}
if (grayscale) {
wd8[x] = value;
} else {
float luminance = value / 255.0;
Color ramp_color = color_ramp->get_color_at_offset(luminance);
wd8[x * 4 + 0] = uint8_t(CLAMP(ramp_color.r * 255, 0, 255));
wd8[x * 4 + 1] = uint8_t(CLAMP(ramp_color.g * 255, 0, 255));
wd8[x * 4 + 2] = uint8_t(CLAMP(ramp_color.b * 255, 0, 255));
wd8[x * 4 + 3] = uint8_t(CLAMP(ramp_color.a * 255, 0, 255));
}
}
}
if (grayscale) {
return memnew(Image(p_width, p_height, false, Image::FORMAT_L8, data));
} else {
return memnew(Image(p_width, p_height, false, Image::FORMAT_RGBA8, data));
}
real_t FastNoiseLite::get_noise_1d(real_t p_x) const {
return get_noise_2d(p_x, 0.0);
}
Ref<Image> FastNoiseLite::get_seamless_image(int p_width, int p_height, bool p_invert, real_t p_blend_skirt) {
// Just return parent function. This is here only so Godot will properly document this function.
return Noise::get_seamless_image(p_width, p_height, p_invert, p_blend_skirt);
real_t FastNoiseLite::get_noise_2dv(Vector2 p_v) const {
return get_noise_2d(p_v.x, p_v.y);
}
real_t FastNoiseLite::get_noise_2d(real_t p_x, real_t p_y) const {
if (domain_warp_enabled) {
_domain_warp_noise.DomainWarp(p_x, p_y);
}
return _noise.GetNoise(p_x + offset.x, p_y + offset.y);
}
real_t FastNoiseLite::get_noise_3dv(Vector3 p_v) const {
return get_noise_3d(p_v.x, p_v.y, p_v.z);
}
real_t FastNoiseLite::get_noise_3d(real_t p_x, real_t p_y, real_t p_z) const {
if (domain_warp_enabled) {
_domain_warp_noise.DomainWarp(p_x, p_y, p_z);
}
return _noise.GetNoise(p_x + offset.x, p_y + offset.y, p_z + offset.z);
}
void FastNoiseLite::_changed() {
@ -418,108 +332,103 @@ void FastNoiseLite::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_noise_type", "type"), &FastNoiseLite::set_noise_type);
ClassDB::bind_method(D_METHOD("get_noise_type"), &FastNoiseLite::get_noise_type);
ADD_PROPERTY(PropertyInfo(Variant::INT, "noise_type", PROPERTY_HINT_ENUM, "Simplex,Simplex Smooth,Cellular,Perlin,Value Cubic,Value"), "set_noise_type", "get_noise_type");
ClassDB::bind_method(D_METHOD("set_seed", "seed"), &FastNoiseLite::set_seed);
ClassDB::bind_method(D_METHOD("get_seed"), &FastNoiseLite::get_seed);
ADD_PROPERTY(PropertyInfo(Variant::INT, "seed"), "set_seed", "get_seed");
ClassDB::bind_method(D_METHOD("set_frequency", "freq"), &FastNoiseLite::set_frequency);
ClassDB::bind_method(D_METHOD("get_frequency"), &FastNoiseLite::get_frequency);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "frequency", PROPERTY_HINT_RANGE, ".001,1"), "set_frequency", "get_frequency");
ClassDB::bind_method(D_METHOD("set_in_3d_space", "enable"), &FastNoiseLite::set_in_3d_space);
ClassDB::bind_method(D_METHOD("is_in_3d_space"), &FastNoiseLite::is_in_3d_space);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "in_3d_space"), "set_in_3d_space", "is_in_3d_space");
ClassDB::bind_method(D_METHOD("set_offset", "offset"), &FastNoiseLite::set_offset);
ClassDB::bind_method(D_METHOD("get_offset"), &FastNoiseLite::get_offset);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "offset", PROPERTY_HINT_RANGE, "-999999999,999999999,1"), "set_offset", "get_offset");
ClassDB::bind_method(D_METHOD("set_color_ramp", "gradient"), &FastNoiseLite::set_color_ramp);
ClassDB::bind_method(D_METHOD("get_color_ramp"), &FastNoiseLite::get_color_ramp);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_color_ramp", "get_color_ramp");
// Fractal.
ADD_GROUP("Fractal", "fractal_");
ClassDB::bind_method(D_METHOD("set_fractal_type", "type"), &FastNoiseLite::set_fractal_type);
ClassDB::bind_method(D_METHOD("get_fractal_type"), &FastNoiseLite::get_fractal_type);
ADD_PROPERTY(PropertyInfo(Variant::INT, "fractal_type", PROPERTY_HINT_ENUM, "None,FBM,Ridged,Ping-Pong"), "set_fractal_type", "get_fractal_type");
ClassDB::bind_method(D_METHOD("set_fractal_octaves", "octave_count"), &FastNoiseLite::set_fractal_octaves);
ClassDB::bind_method(D_METHOD("get_fractal_octaves"), &FastNoiseLite::get_fractal_octaves);
ADD_PROPERTY(PropertyInfo(Variant::INT, "fractal_octaves", PROPERTY_HINT_RANGE, "1,10,1"), "set_fractal_octaves", "get_fractal_octaves");
ClassDB::bind_method(D_METHOD("set_fractal_lacunarity", "lacunarity"), &FastNoiseLite::set_fractal_lacunarity);
ClassDB::bind_method(D_METHOD("get_fractal_lacunarity"), &FastNoiseLite::get_fractal_lacunarity);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fractal_lacunarity"), "set_fractal_lacunarity", "get_fractal_lacunarity");
ClassDB::bind_method(D_METHOD("set_fractal_gain", "gain"), &FastNoiseLite::set_fractal_gain);
ClassDB::bind_method(D_METHOD("get_fractal_gain"), &FastNoiseLite::get_fractal_gain);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fractal_gain"), "set_fractal_gain", "get_fractal_gain");
ClassDB::bind_method(D_METHOD("set_fractal_weighted_strength", "weighted_strength"), &FastNoiseLite::set_fractal_weighted_strength);
ClassDB::bind_method(D_METHOD("get_fractal_weighted_strength"), &FastNoiseLite::get_fractal_weighted_strength);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fractal_weighted_strength", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_fractal_weighted_strength", "get_fractal_weighted_strength");
ClassDB::bind_method(D_METHOD("set_fractal_ping_pong_strength", "ping_pong_strength"), &FastNoiseLite::set_fractal_ping_pong_strength);
ClassDB::bind_method(D_METHOD("get_fractal_ping_pong_strength"), &FastNoiseLite::get_fractal_ping_pong_strength);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fractal_ping_pong_strength"), "set_fractal_ping_pong_strength", "get_fractal_ping_pong_strength");
// Cellular.
ADD_GROUP("Cellular", "cellular_");
ClassDB::bind_method(D_METHOD("set_cellular_distance_function", "func"), &FastNoiseLite::set_cellular_distance_function);
ClassDB::bind_method(D_METHOD("get_cellular_distance_function"), &FastNoiseLite::get_cellular_distance_function);
ADD_PROPERTY(PropertyInfo(Variant::INT, "cellular_distance_function", PROPERTY_HINT_ENUM, "Euclidean,Euclidean Squared,Manhattan,Hybrid"), "set_cellular_distance_function", "get_cellular_distance_function");
ClassDB::bind_method(D_METHOD("set_cellular_jitter", "jitter"), &FastNoiseLite::set_cellular_jitter);
ClassDB::bind_method(D_METHOD("get_cellular_jitter"), &FastNoiseLite::get_cellular_jitter);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "cellular_jitter"), "set_cellular_jitter", "get_cellular_jitter");
ClassDB::bind_method(D_METHOD("set_cellular_return_type", "ret"), &FastNoiseLite::set_cellular_return_type);
ClassDB::bind_method(D_METHOD("get_cellular_return_type"), &FastNoiseLite::get_cellular_return_type);
ADD_PROPERTY(PropertyInfo(Variant::INT, "cellular_return_type", PROPERTY_HINT_ENUM, "Cell Value,Distance,Distance2,Distance2Add,Distance2Sub,Distance2Mul,Distance2Div"), "set_cellular_return_type", "get_cellular_return_type");
// Domain warp.
ADD_GROUP("Domain Warp", "domain_warp_");
ClassDB::bind_method(D_METHOD("set_domain_warp_enabled", "domain_warp_enabled"), &FastNoiseLite::set_domain_warp_enabled);
ClassDB::bind_method(D_METHOD("is_domain_warp_enabled"), &FastNoiseLite::is_domain_warp_enabled);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "domain_warp_enabled"), "set_domain_warp_enabled", "is_domain_warp_enabled");
ClassDB::bind_method(D_METHOD("set_domain_warp_type", "domain_warp_type"), &FastNoiseLite::set_domain_warp_type);
ClassDB::bind_method(D_METHOD("get_domain_warp_type"), &FastNoiseLite::get_domain_warp_type);
ADD_PROPERTY(PropertyInfo(Variant::INT, "domain_warp_type", PROPERTY_HINT_ENUM, "Simplex,Simplex Reduced,Basic Grid"), "set_domain_warp_type", "get_domain_warp_type");
ClassDB::bind_method(D_METHOD("set_domain_warp_amplitude", "domain_warp_amplitude"), &FastNoiseLite::set_domain_warp_amplitude);
ClassDB::bind_method(D_METHOD("get_domain_warp_amplitude"), &FastNoiseLite::get_domain_warp_amplitude);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "domain_warp_amplitude"), "set_domain_warp_amplitude", "get_domain_warp_amplitude");
ClassDB::bind_method(D_METHOD("set_domain_warp_frequency", "domain_warp_frequency"), &FastNoiseLite::set_domain_warp_frequency);
ClassDB::bind_method(D_METHOD("get_domain_warp_frequency"), &FastNoiseLite::get_domain_warp_frequency);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "domain_warp_frequency"), "set_domain_warp_frequency", "get_domain_warp_frequency");
ClassDB::bind_method(D_METHOD("set_domain_warp_fractal_type", "domain_warp_fractal_type"), &FastNoiseLite::set_domain_warp_fractal_type);
ClassDB::bind_method(D_METHOD("get_domain_warp_fractal_type"), &FastNoiseLite::get_domain_warp_fractal_type);
ADD_PROPERTY(PropertyInfo(Variant::INT, "domain_warp_fractal_type", PROPERTY_HINT_ENUM, "None,Progressive,Independent"), "set_domain_warp_fractal_type", "get_domain_warp_fractal_type");
ClassDB::bind_method(D_METHOD("set_domain_warp_fractal_octaves", "domain_warp_octave_count"), &FastNoiseLite::set_domain_warp_fractal_octaves);
ClassDB::bind_method(D_METHOD("get_domain_warp_fractal_octaves"), &FastNoiseLite::get_domain_warp_fractal_octaves);
ADD_PROPERTY(PropertyInfo(Variant::INT, "domain_warp_fractal_octaves", PROPERTY_HINT_RANGE, "1,10,1"), "set_domain_warp_fractal_octaves", "get_domain_warp_fractal_octaves");
ClassDB::bind_method(D_METHOD("set_domain_warp_fractal_lacunarity", "domain_warp_lacunarity"), &FastNoiseLite::set_domain_warp_fractal_lacunarity);
ClassDB::bind_method(D_METHOD("get_domain_warp_fractal_lacunarity"), &FastNoiseLite::get_domain_warp_fractal_lacunarity);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "domain_warp_fractal_lacunarity"), "set_domain_warp_fractal_lacunarity", "get_domain_warp_fractal_lacunarity");
ClassDB::bind_method(D_METHOD("set_domain_warp_fractal_gain", "domain_warp_gain"), &FastNoiseLite::set_domain_warp_fractal_gain);
ClassDB::bind_method(D_METHOD("get_domain_warp_fractal_gain"), &FastNoiseLite::get_domain_warp_fractal_gain);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "domain_warp_fractal_gain"), "set_domain_warp_fractal_gain", "get_domain_warp_fractal_gain");
ClassDB::bind_method(D_METHOD("_changed"), &FastNoiseLite::_changed);
ADD_PROPERTY(PropertyInfo(Variant::INT, "noise_type", PROPERTY_HINT_ENUM, "Simplex,Simplex Smooth,Cellular,Perlin,Value Cubic,Value"), "set_noise_type", "get_noise_type");
ADD_PROPERTY(PropertyInfo(Variant::INT, "seed"), "set_seed", "get_seed");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "frequency", PROPERTY_HINT_RANGE, ".001,1"), "set_frequency", "get_frequency");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "offset", PROPERTY_HINT_RANGE, "-999999999,999999999,0.01"), "set_offset", "get_offset");
ADD_GROUP("Fractal", "fractal_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "fractal_type", PROPERTY_HINT_ENUM, "None,FBM,Ridged,Ping-Pong"), "set_fractal_type", "get_fractal_type");
ADD_PROPERTY(PropertyInfo(Variant::INT, "fractal_octaves", PROPERTY_HINT_RANGE, "1,10,1"), "set_fractal_octaves", "get_fractal_octaves");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fractal_lacunarity"), "set_fractal_lacunarity", "get_fractal_lacunarity");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fractal_gain"), "set_fractal_gain", "get_fractal_gain");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fractal_weighted_strength", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_fractal_weighted_strength", "get_fractal_weighted_strength");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fractal_ping_pong_strength"), "set_fractal_ping_pong_strength", "get_fractal_ping_pong_strength");
ADD_GROUP("Cellular", "cellular_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "cellular_distance_function", PROPERTY_HINT_ENUM, "Euclidean,Euclidean Squared,Manhattan,Hybrid"), "set_cellular_distance_function", "get_cellular_distance_function");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "cellular_jitter"), "set_cellular_jitter", "get_cellular_jitter");
ADD_PROPERTY(PropertyInfo(Variant::INT, "cellular_return_type", PROPERTY_HINT_ENUM, "Cell Value,Distance,Distance2,Distance2Add,Distance2Sub,Distance2Mul,Distance2Div"), "set_cellular_return_type", "get_cellular_return_type");
ADD_GROUP("Domain Warp", "domain_warp_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "domain_warp_enabled"), "set_domain_warp_enabled", "is_domain_warp_enabled");
ADD_PROPERTY(PropertyInfo(Variant::INT, "domain_warp_type", PROPERTY_HINT_ENUM, "Simplex,Simplex Reduced,Basic Grid"), "set_domain_warp_type", "get_domain_warp_type");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "domain_warp_amplitude"), "set_domain_warp_amplitude", "get_domain_warp_amplitude");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "domain_warp_frequency"), "set_domain_warp_frequency", "get_domain_warp_frequency");
ADD_PROPERTY(PropertyInfo(Variant::INT, "domain_warp_fractal_type", PROPERTY_HINT_ENUM, "None,Progressive,Independent"), "set_domain_warp_fractal_type", "get_domain_warp_fractal_type");
ADD_PROPERTY(PropertyInfo(Variant::INT, "domain_warp_fractal_octaves", PROPERTY_HINT_RANGE, "1,10,1"), "set_domain_warp_fractal_octaves", "get_domain_warp_fractal_octaves");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "domain_warp_fractal_lacunarity"), "set_domain_warp_fractal_lacunarity", "get_domain_warp_fractal_lacunarity");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "domain_warp_fractal_gain"), "set_domain_warp_fractal_gain", "get_domain_warp_fractal_gain");
BIND_ENUM_CONSTANT(TYPE_VALUE);
BIND_ENUM_CONSTANT(TYPE_VALUE_CUBIC);
BIND_ENUM_CONSTANT(TYPE_PERLIN);

View file

@ -99,36 +99,33 @@ private:
_FastNoiseLite _domain_warp_noise;
Vector3 offset;
NoiseType noise_type;
Ref<Gradient> color_ramp;
NoiseType noise_type = TYPE_SIMPLEX_SMOOTH;
int seed;
real_t frequency;
bool in_3d_space;
int seed = 0;
real_t frequency = 0.01;
// Fractal specific.
FractalType fractal_type;
int fractal_octaves;
real_t fractal_lacunarity;
real_t fractal_gain;
real_t fractal_weighted_strength;
real_t fractal_pinp_pong_strength;
FractalType fractal_type = FRACTAL_FBM;
int fractal_octaves = 5;
real_t fractal_lacunarity = 2;
real_t fractal_gain = 0.5;
real_t fractal_weighted_strength = 0;
real_t fractal_ping_pong_strength = 2;
// Cellular specific.
CellularDistanceFunction cellular_distance_function;
CellularReturnType cellular_return_type;
real_t cellular_jitter;
CellularDistanceFunction cellular_distance_function = DISTANCE_EUCLIDEAN;
CellularReturnType cellular_return_type = RETURN_DISTANCE;
real_t cellular_jitter = 0.45;
// Domain warp specific.
bool domain_warp_enabled;
DomainWarpType domain_warp_type;
real_t domain_warp_frequency;
real_t domain_warp_amplitude;
DomainWarpFractalType domain_warp_fractal_type;
int domain_warp_fractal_octaves;
real_t domain_warp_fractal_lacunarity;
real_t domain_warp_fractal_gain;
bool domain_warp_enabled = false;
DomainWarpType domain_warp_type = DOMAIN_WARP_SIMPLEX;
real_t domain_warp_amplitude = 30.0;
real_t domain_warp_frequency = 0.05;
DomainWarpFractalType domain_warp_fractal_type = DOMAIN_WARP_FRACTAL_PROGRESSIVE;
int domain_warp_fractal_octaves = 5;
real_t domain_warp_fractal_lacunarity = 6;
real_t domain_warp_fractal_gain = 0.5;
public:
FastNoiseLite();
@ -145,15 +142,9 @@ public:
void set_frequency(real_t p_freq);
real_t get_frequency() const;
void set_in_3d_space(bool p_enable);
bool is_in_3d_space() const;
void set_offset(Vector3 p_offset);
Vector3 get_offset() const;
void set_color_ramp(const Ref<Gradient> &p_gradient);
Ref<Gradient> get_color_ramp() const;
// Fractal specific.
void set_fractal_type(FractalType p_type);
@ -212,17 +203,13 @@ public:
real_t get_domain_warp_fractal_gain() const;
// Interface methods.
real_t get_noise_1d(real_t p_x) const override;
Ref<Image> get_image(int p_width, int p_height, bool p_invert = false) override;
Ref<Image> get_seamless_image(int p_width, int p_height, bool p_invert = false, real_t p_blend_skirt = 0.1) override;
real_t get_noise_2dv(Vector2 p_v) const override;
real_t get_noise_2d(real_t p_x, real_t p_y) const override;
real_t get_noise_1d(real_t p_x) override;
real_t get_noise_2dv(Vector2 p_v) override;
real_t get_noise_2d(real_t p_x, real_t p_y) override;
real_t get_noise_3dv(Vector3 p_v) override;
real_t get_noise_3d(real_t p_x, real_t p_y, real_t p_z) override;
real_t get_noise_3dv(Vector3 p_v) const override;
real_t get_noise_3d(real_t p_x, real_t p_y, real_t p_z) const override;
void _changed();
};

View file

@ -30,13 +30,13 @@
#include "noise.h"
Ref<Image> Noise::get_seamless_image(int p_width, int p_height, bool p_invert, real_t p_blend_skirt) {
Ref<Image> Noise::get_seamless_image(int p_width, int p_height, bool p_invert, bool p_in_3d_space, real_t p_blend_skirt) const {
int skirt_width = p_width * p_blend_skirt;
int skirt_height = p_height * p_blend_skirt;
int src_width = p_width + skirt_width;
int src_height = p_height + skirt_height;
Ref<Image> src = get_image(src_width, src_height, p_invert);
Ref<Image> src = get_image(src_width, src_height, p_invert, p_in_3d_space);
bool grayscale = (src->get_format() == Image::FORMAT_L8);
if (grayscale) {
return _generate_seamless_image<uint8_t>(src, p_width, p_height, p_invert, p_blend_skirt);
@ -54,6 +54,50 @@ uint8_t Noise::_alpha_blend<uint8_t>(uint8_t p_bg, uint8_t p_fg, int p_alpha) co
return (uint8_t)((alpha * p_fg + inv_alpha * p_bg) >> 8);
}
Ref<Image> Noise::get_image(int p_width, int p_height, bool p_invert, bool p_in_3d_space) const {
Vector<uint8_t> data;
data.resize(p_width * p_height);
uint8_t *wd8 = data.ptrw();
// Get all values and identify min/max values.
Vector<real_t> values;
values.resize(p_width * p_height);
real_t min_val = 1000;
real_t max_val = -1000;
for (int y = 0, i = 0; y < p_height; y++) {
for (int x = 0; x < p_width; x++, i++) {
values.set(i, p_in_3d_space ? get_noise_3d(x, y, 0.0) : get_noise_2d(x, y));
if (values[i] > max_val) {
max_val = values[i];
}
if (values[i] < min_val) {
min_val = values[i];
}
}
}
// Normalize values and write to texture.
uint8_t value;
for (int i = 0, x = 0; i < p_height; i++) {
for (int j = 0; j < p_width; j++, x++) {
if (max_val == min_val) {
value = 0;
} else {
value = uint8_t(CLAMP((values[x] - min_val) / (max_val - min_val) * 255.f, 0, 255));
}
if (p_invert) {
value = 255 - value;
}
wd8[x] = value;
}
}
return memnew(Image(p_width, p_height, false, Image::FORMAT_L8, data));
}
void Noise::_bind_methods() {
// Noise functions.
ClassDB::bind_method(D_METHOD("get_noise_1d", "x"), &Noise::get_noise_1d);
@ -63,6 +107,6 @@ void Noise::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_noise_3dv", "v"), &Noise::get_noise_3dv);
// Textures.
ClassDB::bind_method(D_METHOD("get_image", "width", "height", "invert"), &Noise::get_image, DEFVAL(false));
ClassDB::bind_method(D_METHOD("get_seamless_image", "width", "height", "invert", "skirt"), &Noise::get_seamless_image, DEFVAL(false), DEFVAL(0.1));
ClassDB::bind_method(D_METHOD("get_image", "width", "height", "invert", "in_3d_space"), &Noise::get_image, DEFVAL(false), DEFVAL(false));
ClassDB::bind_method(D_METHOD("get_seamless_image", "width", "height", "invert", "in_3d_space", "skirt"), &Noise::get_seamless_image, DEFVAL(false), DEFVAL(false), DEFVAL(0.1));
}

View file

@ -81,7 +81,7 @@ class Noise : public Resource {
};
template <typename T>
Ref<Image> _generate_seamless_image(Ref<Image> p_src, int p_width, int p_height, bool p_invert, real_t p_blend_skirt) {
Ref<Image> _generate_seamless_image(Ref<Image> p_src, int p_width, int p_height, bool p_invert, real_t p_blend_skirt) const {
/*
To make a seamless image, we swap the quadrants so the edges are perfect matches.
We initially get a 10% larger image so we have an overlap we can use to blend over the seams.
@ -225,16 +225,16 @@ public:
// Virtual destructor so we can delete any Noise derived object when referenced as a Noise*.
virtual ~Noise() {}
virtual real_t get_noise_1d(real_t p_x) = 0;
virtual real_t get_noise_1d(real_t p_x) const = 0;
virtual real_t get_noise_2dv(Vector2 p_v) = 0;
virtual real_t get_noise_2d(real_t p_x, real_t p_y) = 0;
virtual real_t get_noise_2dv(Vector2 p_v) const = 0;
virtual real_t get_noise_2d(real_t p_x, real_t p_y) const = 0;
virtual real_t get_noise_3dv(Vector3 p_v) = 0;
virtual real_t get_noise_3d(real_t p_x, real_t p_y, real_t p_z) = 0;
virtual real_t get_noise_3dv(Vector3 p_v) const = 0;
virtual real_t get_noise_3d(real_t p_x, real_t p_y, real_t p_z) const = 0;
virtual Ref<Image> get_image(int p_width, int p_height, bool p_invert = false) = 0;
virtual Ref<Image> get_seamless_image(int p_width, int p_height, bool p_invert = false, real_t p_blend_skirt = 0.1);
virtual Ref<Image> get_image(int p_width, int p_height, bool p_invert = false, bool p_in_3d_space = false) const;
virtual Ref<Image> get_seamless_image(int p_width, int p_height, bool p_invert = false, bool p_in_3d_space = false, real_t p_blend_skirt = 0.1) const;
};
#endif // NOISE_H

View file

@ -47,15 +47,22 @@ NoiseTexture::~NoiseTexture() {
}
void NoiseTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("_update_texture"), &NoiseTexture::_update_texture);
ClassDB::bind_method(D_METHOD("_generate_texture"), &NoiseTexture::_generate_texture);
ClassDB::bind_method(D_METHOD("_thread_done", "image"), &NoiseTexture::_thread_done);
ClassDB::bind_method(D_METHOD("set_width", "width"), &NoiseTexture::set_width);
ClassDB::bind_method(D_METHOD("set_height", "height"), &NoiseTexture::set_height);
ClassDB::bind_method(D_METHOD("set_noise", "noise"), &NoiseTexture::set_noise);
ClassDB::bind_method(D_METHOD("get_noise"), &NoiseTexture::get_noise);
ClassDB::bind_method(D_METHOD("set_invert", "invert"), &NoiseTexture::set_invert);
ClassDB::bind_method(D_METHOD("get_invert"), &NoiseTexture::get_invert);
ClassDB::bind_method(D_METHOD("set_in_3d_space", "enable"), &NoiseTexture::set_in_3d_space);
ClassDB::bind_method(D_METHOD("is_in_3d_space"), &NoiseTexture::is_in_3d_space);
ClassDB::bind_method(D_METHOD("set_generate_mipmaps", "invert"), &NoiseTexture::set_generate_mipmaps);
ClassDB::bind_method(D_METHOD("is_generating_mipmaps"), &NoiseTexture::is_generating_mipmaps);
ClassDB::bind_method(D_METHOD("set_seamless", "seamless"), &NoiseTexture::set_seamless);
ClassDB::bind_method(D_METHOD("get_seamless"), &NoiseTexture::get_seamless);
@ -68,17 +75,22 @@ void NoiseTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_bump_strength", "bump_strength"), &NoiseTexture::set_bump_strength);
ClassDB::bind_method(D_METHOD("get_bump_strength"), &NoiseTexture::get_bump_strength);
ClassDB::bind_method(D_METHOD("_update_texture"), &NoiseTexture::_update_texture);
ClassDB::bind_method(D_METHOD("_generate_texture"), &NoiseTexture::_generate_texture);
ClassDB::bind_method(D_METHOD("_thread_done", "image"), &NoiseTexture::_thread_done);
ClassDB::bind_method(D_METHOD("set_color_ramp", "gradient"), &NoiseTexture::set_color_ramp);
ClassDB::bind_method(D_METHOD("get_color_ramp"), &NoiseTexture::get_color_ramp);
ClassDB::bind_method(D_METHOD("set_noise", "noise"), &NoiseTexture::set_noise);
ClassDB::bind_method(D_METHOD("get_noise"), &NoiseTexture::get_noise);
ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "1,2048,1,or_greater"), "set_width", "get_width");
ADD_PROPERTY(PropertyInfo(Variant::INT, "height", PROPERTY_HINT_RANGE, "1,2048,1,or_greater"), "set_height", "get_height");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "invert"), "set_invert", "get_invert");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "in_3d_space"), "set_in_3d_space", "is_in_3d_space");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "generate_mipmaps"), "set_generate_mipmaps", "is_generating_mipmaps");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "seamless"), "set_seamless", "get_seamless");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "seamless_blend_skirt", PROPERTY_HINT_RANGE, "0.05,1,0.001"), "set_seamless_blend_skirt", "get_seamless_blend_skirt");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "as_normal_map"), "set_as_normal_map", "is_normal_map");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bump_strength", PROPERTY_HINT_RANGE, "0,32,0.1,or_greater"), "set_bump_strength", "get_bump_strength");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_color_ramp", "get_color_ramp");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "noise", PROPERTY_HINT_RESOURCE_TYPE, "Noise"), "set_noise", "get_noise");
}
@ -143,18 +155,42 @@ Ref<Image> NoiseTexture::_generate_texture() {
Ref<Image> image;
if (seamless) {
image = ref_noise->get_seamless_image(size.x, size.y, invert, seamless_blend_skirt);
image = ref_noise->get_seamless_image(size.x, size.y, invert, in_3d_space, seamless_blend_skirt);
} else {
image = ref_noise->get_image(size.x, size.y, invert);
image = ref_noise->get_image(size.x, size.y, invert, in_3d_space);
}
if (color_ramp.is_valid()) {
image = _modulate_with_gradient(image, color_ramp);
}
if (as_normal_map) {
image->bump_map_to_normal_map(bump_strength);
}
if (generate_mipmaps) {
image->generate_mipmaps();
}
return image;
}
Ref<Image> NoiseTexture::_modulate_with_gradient(Ref<Image> p_image, Ref<Gradient> p_gradient) {
int width = p_image->get_width();
int height = p_image->get_height();
Ref<Image> new_image;
new_image.instantiate();
new_image->create(width, height, false, Image::FORMAT_RGBA8);
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
Color pixel_color = p_image->get_pixel(col, row);
Color ramp_color = color_ramp->get_color_at_offset(pixel_color.get_luminance());
new_image->set_pixel(col, row, ramp_color);
}
}
return new_image;
}
void NoiseTexture::_update_texture() {
bool use_thread = true;
if (first_time) {
@ -227,6 +263,29 @@ bool NoiseTexture::get_invert() const {
return invert;
}
void NoiseTexture::set_in_3d_space(bool p_enable) {
if (p_enable == in_3d_space) {
return;
}
in_3d_space = p_enable;
_queue_update();
}
bool NoiseTexture::is_in_3d_space() const {
return in_3d_space;
}
void NoiseTexture::set_generate_mipmaps(bool p_enable) {
if (p_enable == generate_mipmaps) {
return;
}
generate_mipmaps = p_enable;
_queue_update();
}
bool NoiseTexture::is_generating_mipmaps() const {
return generate_mipmaps;
}
void NoiseTexture::set_seamless(bool p_seamless) {
if (p_seamless == seamless) {
return;
@ -278,6 +337,24 @@ float NoiseTexture::get_bump_strength() {
return bump_strength;
}
void NoiseTexture::set_color_ramp(const Ref<Gradient> &p_gradient) {
if (p_gradient == color_ramp) {
return;
}
if (color_ramp.is_valid()) {
color_ramp->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &NoiseTexture::_queue_update));
}
color_ramp = p_gradient;
if (color_ramp.is_valid()) {
color_ramp->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &NoiseTexture::_queue_update));
}
_queue_update();
}
Ref<Gradient> NoiseTexture::get_color_ramp() const {
return color_ramp;
}
int NoiseTexture::get_width() const {
return size.x;
}

View file

@ -51,15 +51,18 @@ private:
mutable RID texture;
uint32_t flags = 0;
Ref<Noise> noise;
Size2i size = Size2i(512, 512);
bool invert = false;
Vector2i size = Vector2i(512, 512);
Vector2 noise_offset;
bool in_3d_space = false;
bool generate_mipmaps = true;
bool seamless = false;
real_t seamless_blend_skirt = 0.1;
bool as_normal_map = false;
float bump_strength = 8.0;
Ref<Gradient> color_ramp;
Ref<Noise> noise;
void _thread_done(const Ref<Image> &p_image);
static void _thread_function(void *p_ud);
@ -68,6 +71,8 @@ private:
void _update_texture();
void _set_texture_image(const Ref<Image> &p_image);
Ref<Image> _modulate_with_gradient(Ref<Image> p_image, Ref<Gradient> p_gradient);
protected:
static void _bind_methods();
virtual void _validate_property(PropertyInfo &property) const override;
@ -82,6 +87,12 @@ public:
void set_invert(bool p_invert);
bool get_invert() const;
void set_in_3d_space(bool p_enable);
bool is_in_3d_space() const;
void set_generate_mipmaps(bool p_enable);
bool is_generating_mipmaps() const;
void set_seamless(bool p_seamless);
bool get_seamless();
@ -94,6 +105,9 @@ public:
void set_bump_strength(float p_bump_strength);
float get_bump_strength();
void set_color_ramp(const Ref<Gradient> &p_gradient);
Ref<Gradient> get_color_ramp() const;
int get_width() const override;
int get_height() const override;

View file

@ -34,10 +34,19 @@
#include "noise.h"
#include "noise_texture.h"
#ifdef TOOLS_ENABLED
#include "editor/editor_plugin.h"
#include "editor/noise_editor_plugin.h"
#endif
void register_noise_types() {
GDREGISTER_CLASS(NoiseTexture);
GDREGISTER_ABSTRACT_CLASS(Noise);
GDREGISTER_CLASS(FastNoiseLite);
#ifdef TOOLS_ENABLED
EditorPlugins::add_by_type<NoiseEditorPlugin>();
#endif
}
void unregister_noise_types() {

View file

@ -295,7 +295,7 @@ public:
/// Noise output bounded between -1...1
/// </returns>
template <typename FNfloat>
float GetNoise(FNfloat x, FNfloat y)
float GetNoise(FNfloat x, FNfloat y) const
{
Arguments_must_be_floating_point_values<FNfloat>();
@ -321,7 +321,7 @@ public:
/// Noise output bounded between -1...1
/// </returns>
template <typename FNfloat>
float GetNoise(FNfloat x, FNfloat y, FNfloat z)
float GetNoise(FNfloat x, FNfloat y, FNfloat z) const
{
Arguments_must_be_floating_point_values<FNfloat>();
@ -350,7 +350,7 @@ public:
/// noise = GetNoise(x, y)</code>
/// </example>
template <typename FNfloat>
void DomainWarp(FNfloat& x, FNfloat& y)
void DomainWarp(FNfloat& x, FNfloat& y) const
{
Arguments_must_be_floating_point_values<FNfloat>();
@ -377,7 +377,7 @@ public:
/// noise = GetNoise(x, y, z)</code>
/// </example>
template <typename FNfloat>
void DomainWarp(FNfloat& x, FNfloat& y, FNfloat& z)
void DomainWarp(FNfloat& x, FNfloat& y, FNfloat& z) const
{
Arguments_must_be_floating_point_values<FNfloat>();
@ -528,7 +528,7 @@ private:
}
float GradCoord(int seed, int xPrimed, int yPrimed, float xd, float yd)
float GradCoord(int seed, int xPrimed, int yPrimed, float xd, float yd) const
{
int hash = Hash(seed, xPrimed, yPrimed);
hash ^= hash >> 15;
@ -541,7 +541,7 @@ private:
}
float GradCoord(int seed, int xPrimed, int yPrimed, int zPrimed, float xd, float yd, float zd)
float GradCoord(int seed, int xPrimed, int yPrimed, int zPrimed, float xd, float yd, float zd) const
{
int hash = Hash(seed, xPrimed, yPrimed, zPrimed);
hash ^= hash >> 15;
@ -555,7 +555,7 @@ private:
}
void GradCoordOut(int seed, int xPrimed, int yPrimed, float& xo, float& yo)
void GradCoordOut(int seed, int xPrimed, int yPrimed, float& xo, float& yo) const
{
int hash = Hash(seed, xPrimed, yPrimed) & (255 << 1);
@ -564,7 +564,7 @@ private:
}
void GradCoordOut(int seed, int xPrimed, int yPrimed, int zPrimed, float& xo, float& yo, float& zo)
void GradCoordOut(int seed, int xPrimed, int yPrimed, int zPrimed, float& xo, float& yo, float& zo) const
{
int hash = Hash(seed, xPrimed, yPrimed, zPrimed) & (255 << 2);
@ -574,7 +574,7 @@ private:
}
void GradCoordDual(int seed, int xPrimed, int yPrimed, float xd, float yd, float& xo, float& yo)
void GradCoordDual(int seed, int xPrimed, int yPrimed, float xd, float yd, float& xo, float& yo) const
{
int hash = Hash(seed, xPrimed, yPrimed);
int index1 = hash & (127 << 1);
@ -592,7 +592,7 @@ private:
}
void GradCoordDual(int seed, int xPrimed, int yPrimed, int zPrimed, float xd, float yd, float zd, float& xo, float& yo, float& zo)
void GradCoordDual(int seed, int xPrimed, int yPrimed, int zPrimed, float xd, float yd, float zd, float& xo, float& yo, float& zo) const
{
int hash = Hash(seed, xPrimed, yPrimed, zPrimed);
int index1 = hash & (63 << 2);
@ -616,7 +616,7 @@ private:
// Generic noise gen
template <typename FNfloat>
float GenNoiseSingle(int seed, FNfloat x, FNfloat y)
float GenNoiseSingle(int seed, FNfloat x, FNfloat y) const
{
switch (mNoiseType)
{
@ -638,7 +638,7 @@ private:
}
template <typename FNfloat>
float GenNoiseSingle(int seed, FNfloat x, FNfloat y, FNfloat z)
float GenNoiseSingle(int seed, FNfloat x, FNfloat y, FNfloat z) const
{
switch (mNoiseType)
{
@ -663,7 +663,7 @@ private:
// Noise Coordinate Transforms (frequency, and possible skew or rotation)
template <typename FNfloat>
void TransformNoiseCoordinate(FNfloat& x, FNfloat& y)
void TransformNoiseCoordinate(FNfloat& x, FNfloat& y) const
{
x *= mFrequency;
y *= mFrequency;
@ -686,7 +686,7 @@ private:
}
template <typename FNfloat>
void TransformNoiseCoordinate(FNfloat& x, FNfloat& y, FNfloat& z)
void TransformNoiseCoordinate(FNfloat& x, FNfloat& y, FNfloat& z) const
{
x *= mFrequency;
y *= mFrequency;
@ -757,7 +757,7 @@ private:
// Domain Warp Coordinate Transforms
template <typename FNfloat>
void TransformDomainWarpCoordinate(FNfloat& x, FNfloat& y)
void TransformDomainWarpCoordinate(FNfloat& x, FNfloat& y) const
{
switch (mDomainWarpType)
{
@ -777,7 +777,7 @@ private:
}
template <typename FNfloat>
void TransformDomainWarpCoordinate(FNfloat& x, FNfloat& y, FNfloat& z)
void TransformDomainWarpCoordinate(FNfloat& x, FNfloat& y, FNfloat& z) const
{
switch (mWarpTransformType3D)
{
@ -844,7 +844,7 @@ private:
// Fractal FBm
template <typename FNfloat>
float GenFractalFBm(FNfloat x, FNfloat y)
float GenFractalFBm(FNfloat x, FNfloat y) const
{
int seed = mSeed;
float sum = 0;
@ -865,7 +865,7 @@ private:
}
template <typename FNfloat>
float GenFractalFBm(FNfloat x, FNfloat y, FNfloat z)
float GenFractalFBm(FNfloat x, FNfloat y, FNfloat z) const
{
int seed = mSeed;
float sum = 0;
@ -890,7 +890,7 @@ private:
// Fractal Ridged
template <typename FNfloat>
float GenFractalRidged(FNfloat x, FNfloat y)
float GenFractalRidged(FNfloat x, FNfloat y) const
{
int seed = mSeed;
float sum = 0;
@ -911,7 +911,7 @@ private:
}
template <typename FNfloat>
float GenFractalRidged(FNfloat x, FNfloat y, FNfloat z)
float GenFractalRidged(FNfloat x, FNfloat y, FNfloat z) const
{
int seed = mSeed;
float sum = 0;
@ -936,7 +936,7 @@ private:
// Fractal PingPong
template <typename FNfloat>
float GenFractalPingPong(FNfloat x, FNfloat y)
float GenFractalPingPong(FNfloat x, FNfloat y) const
{
int seed = mSeed;
float sum = 0;
@ -957,7 +957,7 @@ private:
}
template <typename FNfloat>
float GenFractalPingPong(FNfloat x, FNfloat y, FNfloat z)
float GenFractalPingPong(FNfloat x, FNfloat y, FNfloat z) const
{
int seed = mSeed;
float sum = 0;
@ -982,7 +982,7 @@ private:
// Simplex/OpenSimplex2 Noise
template <typename FNfloat>
float SingleSimplex(int seed, FNfloat x, FNfloat y)
float SingleSimplex(int seed, FNfloat x, FNfloat y) const
{
// 2D OpenSimplex2 case uses the same algorithm as ordinary Simplex.
@ -1053,7 +1053,7 @@ private:
}
template <typename FNfloat>
float SingleOpenSimplex2(int seed, FNfloat x, FNfloat y, FNfloat z)
float SingleOpenSimplex2(int seed, FNfloat x, FNfloat y, FNfloat z) const
{
// 3D OpenSimplex2 case uses two offset rotated cube grids.
@ -1155,7 +1155,7 @@ private:
// OpenSimplex2S Noise
template <typename FNfloat>
float SingleOpenSimplex2S(int seed, FNfloat x, FNfloat y)
float SingleOpenSimplex2S(int seed, FNfloat x, FNfloat y) const
{
// 2D OpenSimplex2S case is a modified 2D simplex noise.
@ -1286,7 +1286,7 @@ private:
}
template <typename FNfloat>
float SingleOpenSimplex2S(int seed, FNfloat x, FNfloat y, FNfloat z)
float SingleOpenSimplex2S(int seed, FNfloat x, FNfloat y, FNfloat z) const
{
// 3D OpenSimplex2S case uses two offset rotated cube grids.
@ -1482,7 +1482,7 @@ private:
// Cellular Noise
template <typename FNfloat>
float SingleCellular(int seed, FNfloat x, FNfloat y)
float SingleCellular(int seed, FNfloat x, FNfloat y) const
{
int xr = FastRound(x);
int yr = FastRound(y);
@ -1612,7 +1612,7 @@ private:
}
template <typename FNfloat>
float SingleCellular(int seed, FNfloat x, FNfloat y, FNfloat z)
float SingleCellular(int seed, FNfloat x, FNfloat y, FNfloat z) const
{
int xr = FastRound(x);
int yr = FastRound(y);
@ -1769,7 +1769,7 @@ private:
// Perlin Noise
template <typename FNfloat>
float SinglePerlin(int seed, FNfloat x, FNfloat y)
float SinglePerlin(int seed, FNfloat x, FNfloat y) const
{
int x0 = FastFloor(x);
int y0 = FastFloor(y);
@ -1794,7 +1794,7 @@ private:
}
template <typename FNfloat>
float SinglePerlin(int seed, FNfloat x, FNfloat y, FNfloat z)
float SinglePerlin(int seed, FNfloat x, FNfloat y, FNfloat z) const
{
int x0 = FastFloor(x);
int y0 = FastFloor(y);
@ -1833,7 +1833,7 @@ private:
// Value Cubic Noise
template <typename FNfloat>
float SingleValueCubic(int seed, FNfloat x, FNfloat y)
float SingleValueCubic(int seed, FNfloat x, FNfloat y) const
{
int x1 = FastFloor(x);
int y1 = FastFloor(y);
@ -1863,7 +1863,7 @@ private:
}
template <typename FNfloat>
float SingleValueCubic(int seed, FNfloat x, FNfloat y, FNfloat z)
float SingleValueCubic(int seed, FNfloat x, FNfloat y, FNfloat z) const
{
int x1 = FastFloor(x);
int y1 = FastFloor(y);
@ -1920,7 +1920,7 @@ private:
// Value Noise
template <typename FNfloat>
float SingleValue(int seed, FNfloat x, FNfloat y)
float SingleValue(int seed, FNfloat x, FNfloat y) const
{
int x0 = FastFloor(x);
int y0 = FastFloor(y);
@ -1940,7 +1940,7 @@ private:
}
template <typename FNfloat>
float SingleValue(int seed, FNfloat x, FNfloat y, FNfloat z)
float SingleValue(int seed, FNfloat x, FNfloat y, FNfloat z) const
{
int x0 = FastFloor(x);
int y0 = FastFloor(y);
@ -1972,7 +1972,7 @@ private:
// Domain Warp
template <typename FNfloat>
void DoSingleDomainWarp(int seed, float amp, float freq, FNfloat x, FNfloat y, FNfloat& xr, FNfloat& yr)
void DoSingleDomainWarp(int seed, float amp, float freq, FNfloat x, FNfloat y, FNfloat& xr, FNfloat& yr) const
{
switch (mDomainWarpType)
{
@ -1989,7 +1989,7 @@ private:
}
template <typename FNfloat>
void DoSingleDomainWarp(int seed, float amp, float freq, FNfloat x, FNfloat y, FNfloat z, FNfloat& xr, FNfloat& yr, FNfloat& zr)
void DoSingleDomainWarp(int seed, float amp, float freq, FNfloat x, FNfloat y, FNfloat z, FNfloat& xr, FNfloat& yr, FNfloat& zr) const
{
switch (mDomainWarpType)
{
@ -2009,7 +2009,7 @@ private:
// Domain Warp Single Wrapper
template <typename FNfloat>
void DomainWarpSingle(FNfloat& x, FNfloat& y)
void DomainWarpSingle(FNfloat& x, FNfloat& y) const
{
int seed = mSeed;
float amp = mDomainWarpAmp * mFractalBounding;
@ -2023,7 +2023,7 @@ private:
}
template <typename FNfloat>
void DomainWarpSingle(FNfloat& x, FNfloat& y, FNfloat& z)
void DomainWarpSingle(FNfloat& x, FNfloat& y, FNfloat& z) const
{
int seed = mSeed;
float amp = mDomainWarpAmp * mFractalBounding;
@ -2041,7 +2041,7 @@ private:
// Domain Warp Fractal Progressive
template <typename FNfloat>
void DomainWarpFractalProgressive(FNfloat& x, FNfloat& y)
void DomainWarpFractalProgressive(FNfloat& x, FNfloat& y) const
{
int seed = mSeed;
float amp = mDomainWarpAmp * mFractalBounding;
@ -2062,7 +2062,7 @@ private:
}
template <typename FNfloat>
void DomainWarpFractalProgressive(FNfloat& x, FNfloat& y, FNfloat& z)
void DomainWarpFractalProgressive(FNfloat& x, FNfloat& y, FNfloat& z) const
{
int seed = mSeed;
float amp = mDomainWarpAmp * mFractalBounding;
@ -2087,7 +2087,7 @@ private:
// Domain Warp Fractal Independant
template <typename FNfloat>
void DomainWarpFractalIndependent(FNfloat& x, FNfloat& y)
void DomainWarpFractalIndependent(FNfloat& x, FNfloat& y) const
{
FNfloat xs = x;
FNfloat ys = y;
@ -2108,7 +2108,7 @@ private:
}
template <typename FNfloat>
void DomainWarpFractalIndependent(FNfloat& x, FNfloat& y, FNfloat& z)
void DomainWarpFractalIndependent(FNfloat& x, FNfloat& y, FNfloat& z) const
{
FNfloat xs = x;
FNfloat ys = y;
@ -2133,7 +2133,7 @@ private:
// Domain Warp Basic Grid
template <typename FNfloat>
void SingleDomainWarpBasicGrid(int seed, float warpAmp, float frequency, FNfloat x, FNfloat y, FNfloat& xr, FNfloat& yr)
void SingleDomainWarpBasicGrid(int seed, float warpAmp, float frequency, FNfloat x, FNfloat y, FNfloat& xr, FNfloat& yr) const
{
FNfloat xf = x * frequency;
FNfloat yf = y * frequency;
@ -2166,7 +2166,7 @@ private:
}
template <typename FNfloat>
void SingleDomainWarpBasicGrid(int seed, float warpAmp, float frequency, FNfloat x, FNfloat y, FNfloat z, FNfloat& xr, FNfloat& yr, FNfloat& zr)
void SingleDomainWarpBasicGrid(int seed, float warpAmp, float frequency, FNfloat x, FNfloat y, FNfloat z, FNfloat& xr, FNfloat& yr, FNfloat& zr) const
{
FNfloat xf = x * frequency;
FNfloat yf = y * frequency;
@ -2228,7 +2228,7 @@ private:
// Domain Warp Simplex/OpenSimplex2
template <typename FNfloat>
void SingleDomainWarpSimplexGradient(int seed, float warpAmp, float frequency, FNfloat x, FNfloat y, FNfloat& xr, FNfloat& yr, bool outGradOnly)
void SingleDomainWarpSimplexGradient(int seed, float warpAmp, float frequency, FNfloat x, FNfloat y, FNfloat& xr, FNfloat& yr, bool outGradOnly) const
{
const float SQRT3 = 1.7320508075688772935274463415059f;
const float G2 = (3 - SQRT3) / 6;
@ -2326,7 +2326,7 @@ private:
}
template <typename FNfloat>
void SingleDomainWarpOpenSimplex2Gradient(int seed, float warpAmp, float frequency, FNfloat x, FNfloat y, FNfloat z, FNfloat& xr, FNfloat& yr, FNfloat& zr, bool outGradOnly)
void SingleDomainWarpOpenSimplex2Gradient(int seed, float warpAmp, float frequency, FNfloat x, FNfloat y, FNfloat z, FNfloat& xr, FNfloat& yr, FNfloat& zr, bool outGradOnly) const
{
x *= frequency;
y *= frequency;

View file

@ -16,3 +16,417 @@
-#endif
+}
+#endif // namespace fastnoiselite
@@ -295,7 +295,7 @@ public:
/// Noise output bounded between -1...1
/// </returns>
template <typename FNfloat>
- float GetNoise(FNfloat x, FNfloat y)
+ float GetNoise(FNfloat x, FNfloat y) const
{
Arguments_must_be_floating_point_values<FNfloat>();
@@ -321,7 +321,7 @@ public:
/// Noise output bounded between -1...1
/// </returns>
template <typename FNfloat>
- float GetNoise(FNfloat x, FNfloat y, FNfloat z)
+ float GetNoise(FNfloat x, FNfloat y, FNfloat z) const
{
Arguments_must_be_floating_point_values<FNfloat>();
@@ -350,7 +350,7 @@ public:
/// noise = GetNoise(x, y)</code>
/// </example>
template <typename FNfloat>
- void DomainWarp(FNfloat& x, FNfloat& y)
+ void DomainWarp(FNfloat& x, FNfloat& y) const
{
Arguments_must_be_floating_point_values<FNfloat>();
@@ -377,7 +377,7 @@ public:
/// noise = GetNoise(x, y, z)</code>
/// </example>
template <typename FNfloat>
- void DomainWarp(FNfloat& x, FNfloat& y, FNfloat& z)
+ void DomainWarp(FNfloat& x, FNfloat& y, FNfloat& z) const
{
Arguments_must_be_floating_point_values<FNfloat>();
@@ -528,7 +528,7 @@ private:
}
- float GradCoord(int seed, int xPrimed, int yPrimed, float xd, float yd)
+ float GradCoord(int seed, int xPrimed, int yPrimed, float xd, float yd) const
{
int hash = Hash(seed, xPrimed, yPrimed);
hash ^= hash >> 15;
@@ -541,7 +541,7 @@ private:
}
- float GradCoord(int seed, int xPrimed, int yPrimed, int zPrimed, float xd, float yd, float zd)
+ float GradCoord(int seed, int xPrimed, int yPrimed, int zPrimed, float xd, float yd, float zd) const
{
int hash = Hash(seed, xPrimed, yPrimed, zPrimed);
hash ^= hash >> 15;
@@ -555,7 +555,7 @@ private:
}
- void GradCoordOut(int seed, int xPrimed, int yPrimed, float& xo, float& yo)
+ void GradCoordOut(int seed, int xPrimed, int yPrimed, float& xo, float& yo) const
{
int hash = Hash(seed, xPrimed, yPrimed) & (255 << 1);
@@ -564,7 +564,7 @@ private:
}
- void GradCoordOut(int seed, int xPrimed, int yPrimed, int zPrimed, float& xo, float& yo, float& zo)
+ void GradCoordOut(int seed, int xPrimed, int yPrimed, int zPrimed, float& xo, float& yo, float& zo) const
{
int hash = Hash(seed, xPrimed, yPrimed, zPrimed) & (255 << 2);
@@ -574,7 +574,7 @@ private:
}
- void GradCoordDual(int seed, int xPrimed, int yPrimed, float xd, float yd, float& xo, float& yo)
+ void GradCoordDual(int seed, int xPrimed, int yPrimed, float xd, float yd, float& xo, float& yo) const
{
int hash = Hash(seed, xPrimed, yPrimed);
int index1 = hash & (127 << 1);
@@ -592,7 +592,7 @@ private:
}
- void GradCoordDual(int seed, int xPrimed, int yPrimed, int zPrimed, float xd, float yd, float zd, float& xo, float& yo, float& zo)
+ void GradCoordDual(int seed, int xPrimed, int yPrimed, int zPrimed, float xd, float yd, float zd, float& xo, float& yo, float& zo) const
{
int hash = Hash(seed, xPrimed, yPrimed, zPrimed);
int index1 = hash & (63 << 2);
@@ -616,7 +616,7 @@ private:
// Generic noise gen
template <typename FNfloat>
- float GenNoiseSingle(int seed, FNfloat x, FNfloat y)
+ float GenNoiseSingle(int seed, FNfloat x, FNfloat y) const
{
switch (mNoiseType)
{
@@ -638,7 +638,7 @@ private:
}
template <typename FNfloat>
- float GenNoiseSingle(int seed, FNfloat x, FNfloat y, FNfloat z)
+ float GenNoiseSingle(int seed, FNfloat x, FNfloat y, FNfloat z) const
{
switch (mNoiseType)
{
@@ -663,7 +663,7 @@ private:
// Noise Coordinate Transforms (frequency, and possible skew or rotation)
template <typename FNfloat>
- void TransformNoiseCoordinate(FNfloat& x, FNfloat& y)
+ void TransformNoiseCoordinate(FNfloat& x, FNfloat& y) const
{
x *= mFrequency;
y *= mFrequency;
@@ -686,7 +686,7 @@ private:
}
template <typename FNfloat>
- void TransformNoiseCoordinate(FNfloat& x, FNfloat& y, FNfloat& z)
+ void TransformNoiseCoordinate(FNfloat& x, FNfloat& y, FNfloat& z) const
{
x *= mFrequency;
y *= mFrequency;
@@ -757,7 +757,7 @@ private:
// Domain Warp Coordinate Transforms
template <typename FNfloat>
- void TransformDomainWarpCoordinate(FNfloat& x, FNfloat& y)
+ void TransformDomainWarpCoordinate(FNfloat& x, FNfloat& y) const
{
switch (mDomainWarpType)
{
@@ -777,7 +777,7 @@ private:
}
template <typename FNfloat>
- void TransformDomainWarpCoordinate(FNfloat& x, FNfloat& y, FNfloat& z)
+ void TransformDomainWarpCoordinate(FNfloat& x, FNfloat& y, FNfloat& z) const
{
switch (mWarpTransformType3D)
{
@@ -844,7 +844,7 @@ private:
// Fractal FBm
template <typename FNfloat>
- float GenFractalFBm(FNfloat x, FNfloat y)
+ float GenFractalFBm(FNfloat x, FNfloat y) const
{
int seed = mSeed;
float sum = 0;
@@ -865,7 +865,7 @@ private:
}
template <typename FNfloat>
- float GenFractalFBm(FNfloat x, FNfloat y, FNfloat z)
+ float GenFractalFBm(FNfloat x, FNfloat y, FNfloat z) const
{
int seed = mSeed;
float sum = 0;
@@ -890,7 +890,7 @@ private:
// Fractal Ridged
template <typename FNfloat>
- float GenFractalRidged(FNfloat x, FNfloat y)
+ float GenFractalRidged(FNfloat x, FNfloat y) const
{
int seed = mSeed;
float sum = 0;
@@ -911,7 +911,7 @@ private:
}
template <typename FNfloat>
- float GenFractalRidged(FNfloat x, FNfloat y, FNfloat z)
+ float GenFractalRidged(FNfloat x, FNfloat y, FNfloat z) const
{
int seed = mSeed;
float sum = 0;
@@ -936,7 +936,7 @@ private:
// Fractal PingPong
template <typename FNfloat>
- float GenFractalPingPong(FNfloat x, FNfloat y)
+ float GenFractalPingPong(FNfloat x, FNfloat y) const
{
int seed = mSeed;
float sum = 0;
@@ -957,7 +957,7 @@ private:
}
template <typename FNfloat>
- float GenFractalPingPong(FNfloat x, FNfloat y, FNfloat z)
+ float GenFractalPingPong(FNfloat x, FNfloat y, FNfloat z) const
{
int seed = mSeed;
float sum = 0;
@@ -982,7 +982,7 @@ private:
// Simplex/OpenSimplex2 Noise
template <typename FNfloat>
- float SingleSimplex(int seed, FNfloat x, FNfloat y)
+ float SingleSimplex(int seed, FNfloat x, FNfloat y) const
{
// 2D OpenSimplex2 case uses the same algorithm as ordinary Simplex.
@@ -1053,7 +1053,7 @@ private:
}
template <typename FNfloat>
- float SingleOpenSimplex2(int seed, FNfloat x, FNfloat y, FNfloat z)
+ float SingleOpenSimplex2(int seed, FNfloat x, FNfloat y, FNfloat z) const
{
// 3D OpenSimplex2 case uses two offset rotated cube grids.
@@ -1155,7 +1155,7 @@ private:
// OpenSimplex2S Noise
template <typename FNfloat>
- float SingleOpenSimplex2S(int seed, FNfloat x, FNfloat y)
+ float SingleOpenSimplex2S(int seed, FNfloat x, FNfloat y) const
{
// 2D OpenSimplex2S case is a modified 2D simplex noise.
@@ -1286,7 +1286,7 @@ private:
}
template <typename FNfloat>
- float SingleOpenSimplex2S(int seed, FNfloat x, FNfloat y, FNfloat z)
+ float SingleOpenSimplex2S(int seed, FNfloat x, FNfloat y, FNfloat z) const
{
// 3D OpenSimplex2S case uses two offset rotated cube grids.
@@ -1482,7 +1482,7 @@ private:
// Cellular Noise
template <typename FNfloat>
- float SingleCellular(int seed, FNfloat x, FNfloat y)
+ float SingleCellular(int seed, FNfloat x, FNfloat y) const
{
int xr = FastRound(x);
int yr = FastRound(y);
@@ -1612,7 +1612,7 @@ private:
}
template <typename FNfloat>
- float SingleCellular(int seed, FNfloat x, FNfloat y, FNfloat z)
+ float SingleCellular(int seed, FNfloat x, FNfloat y, FNfloat z) const
{
int xr = FastRound(x);
int yr = FastRound(y);
@@ -1769,7 +1769,7 @@ private:
// Perlin Noise
template <typename FNfloat>
- float SinglePerlin(int seed, FNfloat x, FNfloat y)
+ float SinglePerlin(int seed, FNfloat x, FNfloat y) const
{
int x0 = FastFloor(x);
int y0 = FastFloor(y);
@@ -1794,7 +1794,7 @@ private:
}
template <typename FNfloat>
- float SinglePerlin(int seed, FNfloat x, FNfloat y, FNfloat z)
+ float SinglePerlin(int seed, FNfloat x, FNfloat y, FNfloat z) const
{
int x0 = FastFloor(x);
int y0 = FastFloor(y);
@@ -1833,7 +1833,7 @@ private:
// Value Cubic Noise
template <typename FNfloat>
- float SingleValueCubic(int seed, FNfloat x, FNfloat y)
+ float SingleValueCubic(int seed, FNfloat x, FNfloat y) const
{
int x1 = FastFloor(x);
int y1 = FastFloor(y);
@@ -1863,7 +1863,7 @@ private:
}
template <typename FNfloat>
- float SingleValueCubic(int seed, FNfloat x, FNfloat y, FNfloat z)
+ float SingleValueCubic(int seed, FNfloat x, FNfloat y, FNfloat z) const
{
int x1 = FastFloor(x);
int y1 = FastFloor(y);
@@ -1920,7 +1920,7 @@ private:
// Value Noise
template <typename FNfloat>
- float SingleValue(int seed, FNfloat x, FNfloat y)
+ float SingleValue(int seed, FNfloat x, FNfloat y) const
{
int x0 = FastFloor(x);
int y0 = FastFloor(y);
@@ -1940,7 +1940,7 @@ private:
}
template <typename FNfloat>
- float SingleValue(int seed, FNfloat x, FNfloat y, FNfloat z)
+ float SingleValue(int seed, FNfloat x, FNfloat y, FNfloat z) const
{
int x0 = FastFloor(x);
int y0 = FastFloor(y);
@@ -1972,7 +1972,7 @@ private:
// Domain Warp
template <typename FNfloat>
- void DoSingleDomainWarp(int seed, float amp, float freq, FNfloat x, FNfloat y, FNfloat& xr, FNfloat& yr)
+ void DoSingleDomainWarp(int seed, float amp, float freq, FNfloat x, FNfloat y, FNfloat& xr, FNfloat& yr) const
{
switch (mDomainWarpType)
{
@@ -1989,7 +1989,7 @@ private:
}
template <typename FNfloat>
- void DoSingleDomainWarp(int seed, float amp, float freq, FNfloat x, FNfloat y, FNfloat z, FNfloat& xr, FNfloat& yr, FNfloat& zr)
+ void DoSingleDomainWarp(int seed, float amp, float freq, FNfloat x, FNfloat y, FNfloat z, FNfloat& xr, FNfloat& yr, FNfloat& zr) const
{
switch (mDomainWarpType)
{
@@ -2009,7 +2009,7 @@ private:
// Domain Warp Single Wrapper
template <typename FNfloat>
- void DomainWarpSingle(FNfloat& x, FNfloat& y)
+ void DomainWarpSingle(FNfloat& x, FNfloat& y) const
{
int seed = mSeed;
float amp = mDomainWarpAmp * mFractalBounding;
@@ -2023,7 +2023,7 @@ private:
}
template <typename FNfloat>
- void DomainWarpSingle(FNfloat& x, FNfloat& y, FNfloat& z)
+ void DomainWarpSingle(FNfloat& x, FNfloat& y, FNfloat& z) const
{
int seed = mSeed;
float amp = mDomainWarpAmp * mFractalBounding;
@@ -2041,7 +2041,7 @@ private:
// Domain Warp Fractal Progressive
template <typename FNfloat>
- void DomainWarpFractalProgressive(FNfloat& x, FNfloat& y)
+ void DomainWarpFractalProgressive(FNfloat& x, FNfloat& y) const
{
int seed = mSeed;
float amp = mDomainWarpAmp * mFractalBounding;
@@ -2062,7 +2062,7 @@ private:
}
template <typename FNfloat>
- void DomainWarpFractalProgressive(FNfloat& x, FNfloat& y, FNfloat& z)
+ void DomainWarpFractalProgressive(FNfloat& x, FNfloat& y, FNfloat& z) const
{
int seed = mSeed;
float amp = mDomainWarpAmp * mFractalBounding;
@@ -2087,7 +2087,7 @@ private:
// Domain Warp Fractal Independant
template <typename FNfloat>
- void DomainWarpFractalIndependent(FNfloat& x, FNfloat& y)
+ void DomainWarpFractalIndependent(FNfloat& x, FNfloat& y) const
{
FNfloat xs = x;
FNfloat ys = y;
@@ -2108,7 +2108,7 @@ private:
}
template <typename FNfloat>
- void DomainWarpFractalIndependent(FNfloat& x, FNfloat& y, FNfloat& z)
+ void DomainWarpFractalIndependent(FNfloat& x, FNfloat& y, FNfloat& z) const
{
FNfloat xs = x;
FNfloat ys = y;
@@ -2133,7 +2133,7 @@ private:
// Domain Warp Basic Grid
template <typename FNfloat>
- void SingleDomainWarpBasicGrid(int seed, float warpAmp, float frequency, FNfloat x, FNfloat y, FNfloat& xr, FNfloat& yr)
+ void SingleDomainWarpBasicGrid(int seed, float warpAmp, float frequency, FNfloat x, FNfloat y, FNfloat& xr, FNfloat& yr) const
{
FNfloat xf = x * frequency;
FNfloat yf = y * frequency;
@@ -2166,7 +2166,7 @@ private:
}
template <typename FNfloat>
- void SingleDomainWarpBasicGrid(int seed, float warpAmp, float frequency, FNfloat x, FNfloat y, FNfloat z, FNfloat& xr, FNfloat& yr, FNfloat& zr)
+ void SingleDomainWarpBasicGrid(int seed, float warpAmp, float frequency, FNfloat x, FNfloat y, FNfloat z, FNfloat& xr, FNfloat& yr, FNfloat& zr) const
{
FNfloat xf = x * frequency;
FNfloat yf = y * frequency;
@@ -2228,7 +2228,7 @@ private:
// Domain Warp Simplex/OpenSimplex2
template <typename FNfloat>
- void SingleDomainWarpSimplexGradient(int seed, float warpAmp, float frequency, FNfloat x, FNfloat y, FNfloat& xr, FNfloat& yr, bool outGradOnly)
+ void SingleDomainWarpSimplexGradient(int seed, float warpAmp, float frequency, FNfloat x, FNfloat y, FNfloat& xr, FNfloat& yr, bool outGradOnly) const
{
const float SQRT3 = 1.7320508075688772935274463415059f;
const float G2 = (3 - SQRT3) / 6;
@@ -2326,7 +2326,7 @@ private:
}
template <typename FNfloat>
- void SingleDomainWarpOpenSimplex2Gradient(int seed, float warpAmp, float frequency, FNfloat x, FNfloat y, FNfloat z, FNfloat& xr, FNfloat& yr, FNfloat& zr, bool outGradOnly)
+ void SingleDomainWarpOpenSimplex2Gradient(int seed, float warpAmp, float frequency, FNfloat x, FNfloat y, FNfloat z, FNfloat& xr, FNfloat& yr, FNfloat& zr, bool outGradOnly) const
{
x *= frequency;
y *= frequency;