Merge pull request #56718 from Geometror/noise-overhaul
This commit is contained in:
commit
8c12dfe099
26 changed files with 4084 additions and 2991 deletions
|
@ -310,11 +310,10 @@ Comment: Tangent Space Normal Maps implementation
|
|||
Copyright: 2011, Morten S. Mikkelsen
|
||||
License: Zlib
|
||||
|
||||
Files: ./thirdparty/misc/open-simplex-noise.c
|
||||
./thirdparty/misc/open-simplex-noise.h
|
||||
Comment: OpenSimplex Noise
|
||||
Copyright: 2014, Stephen M. Cameron
|
||||
License: public-domain or Unlicense
|
||||
Files: ./thirdparty/noise/FastNoiseLite.h
|
||||
Comment: FastNoise Lite
|
||||
Copyright: 2020, Jordan Peck and contributors
|
||||
License: MIT
|
||||
|
||||
Files: ./thirdparty/misc/pcg.cpp
|
||||
./thirdparty/misc/pcg.h
|
||||
|
|
|
@ -3,21 +3,21 @@
|
|||
Import("env")
|
||||
Import("env_modules")
|
||||
|
||||
env_opensimplex = env_modules.Clone()
|
||||
env_noise = env_modules.Clone()
|
||||
|
||||
# Thirdparty source files
|
||||
|
||||
thirdparty_obj = []
|
||||
|
||||
thirdparty_dir = "#thirdparty/misc/"
|
||||
thirdparty_dir = "#thirdparty/noise/"
|
||||
thirdparty_sources = [
|
||||
"open-simplex-noise.c",
|
||||
# Add C++ source files for noise modules here
|
||||
]
|
||||
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
|
||||
|
||||
env_opensimplex.Prepend(CPPPATH=[thirdparty_dir])
|
||||
env_noise.Prepend(CPPPATH=[thirdparty_dir])
|
||||
|
||||
env_thirdparty = env_opensimplex.Clone()
|
||||
env_thirdparty = env_noise.Clone()
|
||||
env_thirdparty.disable_warnings()
|
||||
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources)
|
||||
env.modules_sources += thirdparty_obj
|
||||
|
@ -26,7 +26,7 @@ env.modules_sources += thirdparty_obj
|
|||
|
||||
module_obj = []
|
||||
|
||||
env_opensimplex.add_source_files(module_obj, "*.cpp")
|
||||
env_noise.add_source_files(module_obj, "*.cpp")
|
||||
env.modules_sources += module_obj
|
||||
|
||||
# Needed to force rebuilding the module files when the thirdparty library is updated.
|
|
@ -8,8 +8,9 @@ def configure(env):
|
|||
|
||||
def get_doc_classes():
|
||||
return [
|
||||
"FastNoiseLite",
|
||||
"Noise",
|
||||
"NoiseTexture",
|
||||
"OpenSimplexNoise",
|
||||
]
|
||||
|
||||
|
169
modules/noise/doc_classes/FastNoiseLite.xml
Normal file
169
modules/noise/doc_classes/FastNoiseLite.xml
Normal file
|
@ -0,0 +1,169 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<class name="FastNoiseLite" inherits="Noise" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
|
||||
<brief_description>
|
||||
Generates noise using the FastNoiseLite library.
|
||||
</brief_description>
|
||||
<description>
|
||||
This class generates noise using the FastNoiseLite library, which is a collection of several noise algorithms including Cellular, Perlin, Value, and more.
|
||||
Most generated noise values are in the range of [code][-1,1][/code], however not always. Some of the cellular noise algorithms return results above [code]1[/code].
|
||||
</description>
|
||||
<tutorials>
|
||||
</tutorials>
|
||||
<members>
|
||||
<member name="cellular_distance_function" type="int" setter="set_cellular_distance_function" getter="get_cellular_distance_function" enum="FastNoiseLite.CellularDistanceFunction" default="0">
|
||||
Determines how the distance to the nearest/second-nearest point is computed. See [enum CellularDistanceFunction] for options.
|
||||
</member>
|
||||
<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">
|
||||
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>
|
||||
<member name="domain_warp_enabled" type="bool" setter="set_domain_warp_enabled" getter="is_domain_warp_enabled" default="false">
|
||||
If enabled, another FastNoiseLite instance is used to warp the space, resulting in a distortion of the noise.
|
||||
</member>
|
||||
<member name="domain_warp_fractal_gain" type="float" setter="set_domain_warp_fractal_gain" getter="get_domain_warp_fractal_gain" default="0.5">
|
||||
Determines the strength of each subsequent layer of the noise which is used to warp the space.
|
||||
A low value places more emphasis on the lower frequency base layers, while a high value puts more emphasis on the higher frequency layers.
|
||||
</member>
|
||||
<member name="domain_warp_fractal_lacunarity" type="float" setter="set_domain_warp_fractal_lacunarity" getter="get_domain_warp_fractal_lacunarity" default="6.0">
|
||||
Octave lacunarity of the fractal noise which warps the space. Increasing this value results in higher octaves producing noise with finer details and a rougher appearance.
|
||||
</member>
|
||||
<member name="domain_warp_fractal_octaves" type="int" setter="set_domain_warp_fractal_octaves" getter="get_domain_warp_fractal_octaves" default="5">
|
||||
The number of noise layers that are sampled to get the final value for the fractal noise which warps the space.
|
||||
</member>
|
||||
<member name="domain_warp_fractal_type" type="int" setter="set_domain_warp_fractal_type" getter="get_domain_warp_fractal_type" enum="FastNoiseLite.DomainWarpFractalType" default="1">
|
||||
The method for combining octaves into a fractal which is used to warp the space. See [enum DomainWarpFractalType].
|
||||
</member>
|
||||
<member name="domain_warp_frequency" type="float" setter="set_domain_warp_frequency" getter="get_domain_warp_frequency" default="0.05">
|
||||
Frequency of the noise which warps the space. Low frequency results in smooth noise while high frequency results in rougher, more granular noise.
|
||||
</member>
|
||||
<member name="domain_warp_type" type="int" setter="set_domain_warp_type" getter="get_domain_warp_type" enum="FastNoiseLite.DomainWarpType" default="0">
|
||||
Sets the warp algorithm. See [enum DomainWarpType].
|
||||
</member>
|
||||
<member name="fractal_gain" type="float" setter="set_fractal_gain" getter="get_fractal_gain" default="0.5">
|
||||
Determines the strength of each subsequent layer of noise in fractal noise.
|
||||
A low value places more emphasis on the lower frequency base layers, while a high value puts more emphasis on the higher frequency layers.
|
||||
</member>
|
||||
<member name="fractal_lacunarity" type="float" setter="set_fractal_lacunarity" getter="get_fractal_lacunarity" default="2.0">
|
||||
Frequency multiplier between subsequent octaves. Increasing this value results in higher octaves producing noise with finer details and a rougher appearance.
|
||||
</member>
|
||||
<member name="fractal_octaves" type="int" setter="set_fractal_octaves" getter="get_fractal_octaves" default="5">
|
||||
The number of noise layers that are sampled to get the final value for fractal noise types.
|
||||
</member>
|
||||
<member name="fractal_ping_pong_strength" type="float" setter="set_fractal_ping_pong_strength" getter="get_fractal_ping_pong_strength" default="2.0">
|
||||
Sets the strength of the fractal ping pong type.
|
||||
</member>
|
||||
<member name="fractal_type" type="int" setter="set_fractal_type" getter="get_fractal_type" enum="FastNoiseLite.FractalType" default="1">
|
||||
The method for combining octaves into a fractal. See [enum FractalType].
|
||||
</member>
|
||||
<member name="fractal_weighted_strength" type="float" setter="set_fractal_weighted_strength" getter="get_fractal_weighted_strength" default="0.0">
|
||||
Higher weighting means higher octaves have less impact if lower octaves have a large impact.
|
||||
</member>
|
||||
<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>
|
||||
<member name="offset" type="Vector3" setter="set_offset" getter="get_offset" default="Vector3(0, 0, 0)">
|
||||
Translate the noise input coordinates by the given [Vector3].
|
||||
</member>
|
||||
<member name="seed" type="int" setter="set_seed" getter="get_seed" default="0">
|
||||
The random number seed for all noise types.
|
||||
</member>
|
||||
</members>
|
||||
<constants>
|
||||
<constant name="TYPE_VALUE" value="5" enum="NoiseType">
|
||||
A lattice of points are assigned random values then interpolated based on neighboring values.
|
||||
</constant>
|
||||
<constant name="TYPE_VALUE_CUBIC" value="4" enum="NoiseType">
|
||||
Similar to Value noise, but slower. Has more variance in peaks and valleys.
|
||||
Cubic noise can be used to avoid certain artifacts when using value noise to create a bumpmap. In general, you should always use this mode if the value noise is being used for a heightmap or bumpmap.
|
||||
</constant>
|
||||
<constant name="TYPE_PERLIN" value="3" enum="NoiseType">
|
||||
A lattice of random gradients. Their dot products are interpolated to obtain values in between the lattices.
|
||||
</constant>
|
||||
<constant name="TYPE_CELLULAR" value="2" enum="NoiseType">
|
||||
Cellular includes both Worley noise and Voronoi diagrams which creates various regions of the same value.
|
||||
</constant>
|
||||
<constant name="TYPE_SIMPLEX" value="0" enum="NoiseType">
|
||||
As opposed to [constant TYPE_PERLIN], gradients exist in a simplex lattice rather than a grid lattice, avoiding directional artifacts.
|
||||
</constant>
|
||||
<constant name="TYPE_SIMPLEX_SMOOTH" value="1" enum="NoiseType">
|
||||
Modified, higher quality version of [constant TYPE_SIMPLEX], but slower.
|
||||
</constant>
|
||||
<constant name="FRACTAL_NONE" value="0" enum="FractalType">
|
||||
No fractal noise.
|
||||
</constant>
|
||||
<constant name="FRACTAL_FBM" value="1" enum="FractalType">
|
||||
Method using Fractional Brownian Motion to combine octaves into a fractal.
|
||||
</constant>
|
||||
<constant name="FRACTAL_RIDGED" value="2" enum="FractalType">
|
||||
Method of combining octaves into a fractal resulting in a "ridged" look.
|
||||
</constant>
|
||||
<constant name="FRACTAL_PING_PONG" value="3" enum="FractalType">
|
||||
Method of combining octaves into a fractal with a ping pong effect.
|
||||
</constant>
|
||||
<constant name="DISTANCE_EUCLIDEAN" value="0" enum="CellularDistanceFunction">
|
||||
Euclidean distance to the nearest point.
|
||||
</constant>
|
||||
<constant name="DISTANCE_EUCLIDEAN_SQUARED" value="1" enum="CellularDistanceFunction">
|
||||
Squared Euclidean distance to the nearest point.
|
||||
</constant>
|
||||
<constant name="DISTANCE_MANHATTAN" value="2" enum="CellularDistanceFunction">
|
||||
Manhattan distance (taxicab metric) to the nearest point.
|
||||
</constant>
|
||||
<constant name="DISTANCE_HYBRID" value="3" enum="CellularDistanceFunction">
|
||||
Blend of [constant DISTANCE_EUCLIDEAN] and [constant DISTANCE_MANHATTAN] to give curved cell boundaries
|
||||
</constant>
|
||||
<constant name="RETURN_CELL_VALUE" value="0" enum="CellularReturnType">
|
||||
The cellular distance function will return the same value for all points within a cell.
|
||||
</constant>
|
||||
<constant name="RETURN_DISTANCE" value="1" enum="CellularReturnType">
|
||||
The cellular distance function will return a value determined by the distance to the nearest point.
|
||||
</constant>
|
||||
<constant name="RETURN_DISTANCE2" value="2" enum="CellularReturnType">
|
||||
The cellular distance function returns the distance to the second-nearest point.
|
||||
</constant>
|
||||
<constant name="RETURN_DISTANCE2_ADD" value="3" enum="CellularReturnType">
|
||||
The distance to the nearest point is added to the distance to the second-nearest point.
|
||||
</constant>
|
||||
<constant name="RETURN_DISTANCE2_SUB" value="4" enum="CellularReturnType">
|
||||
The distance to the nearest point is subtracted from the distance to the second-nearest point.
|
||||
</constant>
|
||||
<constant name="RETURN_DISTANCE2_MUL" value="5" enum="CellularReturnType">
|
||||
The distance to the nearest point is multiplied with the distance to the second-nearest point.
|
||||
</constant>
|
||||
<constant name="RETURN_DISTANCE2_DIV" value="6" enum="CellularReturnType">
|
||||
The distance to the nearest point is divided by the distance to the second-nearest point.
|
||||
</constant>
|
||||
<constant name="DOMAIN_WARP_SIMPLEX" value="0" enum="DomainWarpType">
|
||||
The domain is warped using the simplex noise algorithm.
|
||||
</constant>
|
||||
<constant name="DOMAIN_WARP_SIMPLEX_REDUCED" value="1" enum="DomainWarpType">
|
||||
The domain is warped using a simplified version of the simplex noise algorithm.
|
||||
</constant>
|
||||
<constant name="DOMAIN_WARP_BASIC_GRID" value="2" enum="DomainWarpType">
|
||||
The domain is warped using a simple noise grid (not as smooth as the other methods, but more performant).
|
||||
</constant>
|
||||
<constant name="DOMAIN_WARP_FRACTAL_NONE" value="0" enum="DomainWarpFractalType">
|
||||
No fractal noise for warping the space.
|
||||
</constant>
|
||||
<constant name="DOMAIN_WARP_FRACTAL_PROGRESSIVE" value="1" enum="DomainWarpFractalType">
|
||||
Warping the space progressively, octave for octave, resulting in a more "liquified" distortion.
|
||||
</constant>
|
||||
<constant name="DOMAIN_WARP_FRACTAL_INDEPENDENT" value="2" enum="DomainWarpFractalType">
|
||||
Warping the space independently for each octave, resulting in a more chaotic distortion.
|
||||
</constant>
|
||||
</constants>
|
||||
</class>
|
72
modules/noise/doc_classes/Noise.xml
Normal file
72
modules/noise/doc_classes/Noise.xml
Normal file
|
@ -0,0 +1,72 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<class name="Noise" inherits="Resource" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
|
||||
<brief_description>
|
||||
Abstract base class for noise generators.
|
||||
</brief_description>
|
||||
<description>
|
||||
This class defines the interface for noise generation libraries to inherit from.
|
||||
A default get_seamless_noise() implementation is provided for libraries that do not provide seamless noise. This function requests a larger image from get_image(), reverses the quadrants of the image, then uses the strips of extra width to blend over the seams.
|
||||
Inheriting noise classes can optionally override this function to provide a more optimal algorithm.
|
||||
</description>
|
||||
<tutorials>
|
||||
</tutorials>
|
||||
<methods>
|
||||
<method name="get_image">
|
||||
<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" />
|
||||
<description>
|
||||
Returns a 2D [Image] noise image.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_noise_1d">
|
||||
<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">
|
||||
<return type="float" />
|
||||
<argument index="0" name="x" type="float" />
|
||||
<argument index="1" name="y" type="float" />
|
||||
<description>
|
||||
Returns the 2D noise value at the given position.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_noise_2dv">
|
||||
<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">
|
||||
<return type="float" />
|
||||
<argument index="0" name="x" type="float" />
|
||||
<argument index="1" name="y" type="float" />
|
||||
<argument index="2" name="z" type="float" />
|
||||
<description>
|
||||
Returns the 3D noise value at the given position.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_noise_3dv">
|
||||
<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">
|
||||
<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" />
|
||||
<description>
|
||||
Returns a seamless 2D [Image] noise image.
|
||||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
</class>
|
|
@ -1,15 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<class name="NoiseTexture" inherits="Texture2D" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
|
||||
<brief_description>
|
||||
[OpenSimplexNoise] filled texture.
|
||||
A texture filled with noise generated by a [Noise] object.
|
||||
</brief_description>
|
||||
<description>
|
||||
Uses an [OpenSimplexNoise] to fill the texture data. You can specify the texture size but keep in mind that larger textures will take longer to generate and seamless noise only works with square sized textures.
|
||||
NoiseTexture can also generate normal map textures.
|
||||
Uses [FastNoiseLite] or other libraries to fill the texture data of your desired size.
|
||||
NoiseTexture can also generate normalmap textures.
|
||||
The class uses [Thread]s to generate the texture data internally, so [method Texture2D.get_image] may return [code]null[/code] if the generation process has not completed yet. In that case, you need to wait for the texture to be generated before accessing the image and the generated byte data:
|
||||
[codeblock]
|
||||
var texture = NoiseTexture.new()
|
||||
texture.noise = OpenSimplexNoise.new()
|
||||
texture.noise = FastNoiseLite.new()
|
||||
await texture.changed
|
||||
var image = texture.get_image()
|
||||
var data = image.get_data()
|
||||
|
@ -27,15 +27,18 @@
|
|||
<member name="height" type="int" setter="set_height" getter="get_height" default="512">
|
||||
Height of the generated texture.
|
||||
</member>
|
||||
<member name="noise" type="OpenSimplexNoise" setter="set_noise" getter="get_noise">
|
||||
The [OpenSimplexNoise] instance used to generate the noise.
|
||||
<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>
|
||||
<member name="noise_offset" type="Vector2" setter="set_noise_offset" getter="get_noise_offset" default="Vector2(0, 0)">
|
||||
An offset used to specify the noise space coordinate of the top left corner of the generated noise. This value is ignored if [member seamless] is enabled.
|
||||
<member name="noise" type="Noise" setter="set_noise" getter="get_noise">
|
||||
The instance of the [Noise] object.
|
||||
</member>
|
||||
<member name="seamless" type="bool" setter="set_seamless" getter="get_seamless" default="false">
|
||||
Whether the texture can be tiled without visible seams or not. Seamless textures take longer to generate.
|
||||
[b]Note:[/b] Seamless noise has a lower contrast compared to non-seamless noise. This is due to the way noise uses higher dimensions for generating seamless noise.
|
||||
If [code]true[/code], a seamless texture is requested from the [Noise] resource.
|
||||
[b]Note:[/b] Seamless noise textures may take longer to generate and/or can have a lower contrast compared to non-seamless noise depending on the used [Noise] resource. This is because some implementations use higher dimensions for generating seamless noise.
|
||||
</member>
|
||||
<member name="seamless_blend_skirt" type="float" setter="set_seamless_blend_skirt" getter="get_seamless_blend_skirt" default="0.1">
|
||||
Used for the default/fallback implementation of the seamless texture generation. It determines the distance over which the seams are blended. High values may result in less details and contrast. See [Noise] for further details.
|
||||
</member>
|
||||
<member name="width" type="int" setter="set_width" getter="get_width" default="512">
|
||||
Width of the generated texture.
|
577
modules/noise/fastnoise_lite.cpp
Normal file
577
modules/noise/fastnoise_lite.cpp
Normal file
|
@ -0,0 +1,577 @@
|
|||
/*************************************************************************/
|
||||
/* fastnoise_lite.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 "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);
|
||||
|
||||
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);
|
||||
|
||||
set_cellular_distance_function(DISTANCE_EUCLIDEAN);
|
||||
set_cellular_return_type(RETURN_CELL_VALUE);
|
||||
set_cellular_jitter(0.45);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
FastNoiseLite::~FastNoiseLite() {
|
||||
}
|
||||
|
||||
// General settings.
|
||||
|
||||
void FastNoiseLite::set_noise_type(NoiseType p_noise_type) {
|
||||
noise_type = p_noise_type;
|
||||
_noise.SetNoiseType((_FastNoiseLite::NoiseType)p_noise_type);
|
||||
emit_changed();
|
||||
notify_property_list_changed();
|
||||
}
|
||||
|
||||
FastNoiseLite::NoiseType FastNoiseLite::get_noise_type() const {
|
||||
return noise_type;
|
||||
}
|
||||
|
||||
void FastNoiseLite::set_seed(int p_seed) {
|
||||
seed = p_seed;
|
||||
_noise.SetSeed(p_seed);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
int FastNoiseLite::get_seed() const {
|
||||
return seed;
|
||||
}
|
||||
|
||||
void FastNoiseLite::set_frequency(real_t p_freq) {
|
||||
frequency = p_freq;
|
||||
_noise.SetFrequency(p_freq);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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) {
|
||||
fractal_type = p_type;
|
||||
_noise.SetFractalType((_FastNoiseLite::FractalType)p_type);
|
||||
emit_changed();
|
||||
notify_property_list_changed();
|
||||
}
|
||||
|
||||
FastNoiseLite::FractalType FastNoiseLite::get_fractal_type() const {
|
||||
return fractal_type;
|
||||
}
|
||||
|
||||
void FastNoiseLite::set_fractal_octaves(int p_octaves) {
|
||||
fractal_octaves = p_octaves;
|
||||
_noise.SetFractalOctaves(p_octaves);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
int FastNoiseLite::get_fractal_octaves() const {
|
||||
return fractal_octaves;
|
||||
}
|
||||
|
||||
void FastNoiseLite::set_fractal_lacunarity(real_t p_lacunarity) {
|
||||
fractal_lacunarity = p_lacunarity;
|
||||
_noise.SetFractalLacunarity(p_lacunarity);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
real_t FastNoiseLite::get_fractal_lacunarity() const {
|
||||
return fractal_lacunarity;
|
||||
}
|
||||
|
||||
void FastNoiseLite::set_fractal_gain(real_t p_gain) {
|
||||
fractal_gain = p_gain;
|
||||
_noise.SetFractalGain(p_gain);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
real_t FastNoiseLite::get_fractal_gain() const {
|
||||
return fractal_gain;
|
||||
}
|
||||
|
||||
void FastNoiseLite::set_fractal_weighted_strength(real_t p_weighted_strength) {
|
||||
fractal_weighted_strength = p_weighted_strength;
|
||||
_noise.SetFractalWeightedStrength(p_weighted_strength);
|
||||
emit_changed();
|
||||
}
|
||||
real_t FastNoiseLite::get_fractal_weighted_strength() const {
|
||||
return fractal_weighted_strength;
|
||||
}
|
||||
|
||||
void FastNoiseLite::set_fractal_ping_pong_strength(real_t p_ping_pong_strength) {
|
||||
fractal_pinp_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;
|
||||
}
|
||||
|
||||
// Cellular.
|
||||
|
||||
void FastNoiseLite::set_cellular_distance_function(CellularDistanceFunction p_func) {
|
||||
cellular_distance_function = p_func;
|
||||
_noise.SetCellularDistanceFunction((_FastNoiseLite::CellularDistanceFunction)p_func);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
FastNoiseLite::CellularDistanceFunction FastNoiseLite::get_cellular_distance_function() const {
|
||||
return cellular_distance_function;
|
||||
}
|
||||
|
||||
void FastNoiseLite::set_cellular_jitter(real_t p_jitter) {
|
||||
cellular_jitter = p_jitter;
|
||||
_noise.SetCellularJitter(p_jitter);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
real_t FastNoiseLite::get_cellular_jitter() const {
|
||||
return cellular_jitter;
|
||||
}
|
||||
|
||||
void FastNoiseLite::set_cellular_return_type(CellularReturnType p_ret) {
|
||||
cellular_return_type = p_ret;
|
||||
_noise.SetCellularReturnType((_FastNoiseLite::CellularReturnType)p_ret);
|
||||
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
FastNoiseLite::CellularReturnType FastNoiseLite::get_cellular_return_type() const {
|
||||
return cellular_return_type;
|
||||
}
|
||||
|
||||
// Domain warp specific.
|
||||
|
||||
void FastNoiseLite::set_domain_warp_enabled(bool p_enabled) {
|
||||
if (domain_warp_enabled != p_enabled) {
|
||||
domain_warp_enabled = p_enabled;
|
||||
emit_changed();
|
||||
notify_property_list_changed();
|
||||
}
|
||||
}
|
||||
|
||||
bool FastNoiseLite::is_domain_warp_enabled() const {
|
||||
return domain_warp_enabled;
|
||||
}
|
||||
|
||||
void FastNoiseLite::set_domain_warp_type(DomainWarpType p_domain_warp_type) {
|
||||
domain_warp_type = p_domain_warp_type;
|
||||
_domain_warp_noise.SetDomainWarpType((_FastNoiseLite::DomainWarpType)p_domain_warp_type);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
FastNoiseLite::DomainWarpType FastNoiseLite::get_domain_warp_type() const {
|
||||
return domain_warp_type;
|
||||
}
|
||||
|
||||
void FastNoiseLite::set_domain_warp_amplitude(real_t p_amplitude) {
|
||||
domain_warp_amplitude = p_amplitude;
|
||||
_domain_warp_noise.SetDomainWarpAmp(p_amplitude);
|
||||
emit_changed();
|
||||
}
|
||||
real_t FastNoiseLite::get_domain_warp_amplitude() const {
|
||||
return domain_warp_amplitude;
|
||||
}
|
||||
|
||||
void FastNoiseLite::set_domain_warp_frequency(real_t p_frequency) {
|
||||
domain_warp_frequency = p_frequency;
|
||||
_domain_warp_noise.SetFrequency(p_frequency);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
real_t FastNoiseLite::get_domain_warp_frequency() const {
|
||||
return domain_warp_frequency;
|
||||
}
|
||||
|
||||
void FastNoiseLite::set_domain_warp_fractal_type(DomainWarpFractalType p_domain_warp_fractal_type) {
|
||||
domain_warp_fractal_type = p_domain_warp_fractal_type;
|
||||
|
||||
// This needs manual conversion because Godots Inspector property API does not support discontiguous enum indices.
|
||||
_FastNoiseLite::FractalType type;
|
||||
switch (p_domain_warp_fractal_type) {
|
||||
case DOMAIN_WARP_FRACTAL_NONE:
|
||||
type = _FastNoiseLite::FractalType_None;
|
||||
break;
|
||||
case DOMAIN_WARP_FRACTAL_PROGRESSIVE:
|
||||
type = _FastNoiseLite::FractalType_DomainWarpProgressive;
|
||||
break;
|
||||
case DOMAIN_WARP_FRACTAL_INDEPENDENT:
|
||||
type = _FastNoiseLite::FractalType_DomainWarpIndependent;
|
||||
break;
|
||||
default:
|
||||
type = _FastNoiseLite::FractalType_None;
|
||||
}
|
||||
|
||||
_domain_warp_noise.SetFractalType(type);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
FastNoiseLite::DomainWarpFractalType FastNoiseLite::get_domain_warp_fractal_type() const {
|
||||
return domain_warp_fractal_type;
|
||||
}
|
||||
|
||||
void FastNoiseLite::set_domain_warp_fractal_octaves(int p_octaves) {
|
||||
domain_warp_fractal_octaves = p_octaves;
|
||||
_domain_warp_noise.SetFractalOctaves(p_octaves);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
int FastNoiseLite::get_domain_warp_fractal_octaves() const {
|
||||
return domain_warp_fractal_octaves;
|
||||
}
|
||||
|
||||
void FastNoiseLite::set_domain_warp_fractal_lacunarity(real_t p_lacunarity) {
|
||||
domain_warp_fractal_lacunarity = p_lacunarity;
|
||||
_domain_warp_noise.SetFractalLacunarity(p_lacunarity);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
real_t FastNoiseLite::get_domain_warp_fractal_lacunarity() const {
|
||||
return domain_warp_fractal_lacunarity;
|
||||
}
|
||||
|
||||
void FastNoiseLite::set_domain_warp_fractal_gain(real_t p_gain) {
|
||||
domain_warp_fractal_gain = p_gain;
|
||||
_domain_warp_noise.SetFractalGain(p_gain);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
real_t FastNoiseLite::get_domain_warp_fractal_gain() const {
|
||||
return domain_warp_fractal_gain;
|
||||
}
|
||||
|
||||
// Textures.
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void FastNoiseLite::_changed() {
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
void FastNoiseLite::_bind_methods() {
|
||||
// General settings.
|
||||
|
||||
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,PingPong"), "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,EuclideanSquared,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, "CellValue,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,SimplexReduced,BasicGrid"), "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);
|
||||
|
||||
BIND_ENUM_CONSTANT(TYPE_VALUE);
|
||||
BIND_ENUM_CONSTANT(TYPE_VALUE_CUBIC);
|
||||
BIND_ENUM_CONSTANT(TYPE_PERLIN);
|
||||
BIND_ENUM_CONSTANT(TYPE_CELLULAR);
|
||||
BIND_ENUM_CONSTANT(TYPE_SIMPLEX);
|
||||
BIND_ENUM_CONSTANT(TYPE_SIMPLEX_SMOOTH);
|
||||
|
||||
BIND_ENUM_CONSTANT(FRACTAL_NONE);
|
||||
BIND_ENUM_CONSTANT(FRACTAL_FBM);
|
||||
BIND_ENUM_CONSTANT(FRACTAL_RIDGED);
|
||||
BIND_ENUM_CONSTANT(FRACTAL_PING_PONG);
|
||||
|
||||
BIND_ENUM_CONSTANT(DISTANCE_EUCLIDEAN);
|
||||
BIND_ENUM_CONSTANT(DISTANCE_EUCLIDEAN_SQUARED);
|
||||
BIND_ENUM_CONSTANT(DISTANCE_MANHATTAN);
|
||||
BIND_ENUM_CONSTANT(DISTANCE_HYBRID);
|
||||
|
||||
BIND_ENUM_CONSTANT(RETURN_CELL_VALUE);
|
||||
BIND_ENUM_CONSTANT(RETURN_DISTANCE);
|
||||
BIND_ENUM_CONSTANT(RETURN_DISTANCE2);
|
||||
BIND_ENUM_CONSTANT(RETURN_DISTANCE2_ADD);
|
||||
BIND_ENUM_CONSTANT(RETURN_DISTANCE2_SUB);
|
||||
BIND_ENUM_CONSTANT(RETURN_DISTANCE2_MUL);
|
||||
BIND_ENUM_CONSTANT(RETURN_DISTANCE2_DIV);
|
||||
|
||||
BIND_ENUM_CONSTANT(DOMAIN_WARP_SIMPLEX);
|
||||
BIND_ENUM_CONSTANT(DOMAIN_WARP_SIMPLEX_REDUCED);
|
||||
BIND_ENUM_CONSTANT(DOMAIN_WARP_BASIC_GRID);
|
||||
|
||||
BIND_ENUM_CONSTANT(DOMAIN_WARP_FRACTAL_NONE);
|
||||
BIND_ENUM_CONSTANT(DOMAIN_WARP_FRACTAL_PROGRESSIVE);
|
||||
BIND_ENUM_CONSTANT(DOMAIN_WARP_FRACTAL_INDEPENDENT);
|
||||
}
|
||||
|
||||
void FastNoiseLite::_validate_property(PropertyInfo &property) const {
|
||||
if (property.name.begins_with("cellular") && get_noise_type() != TYPE_CELLULAR) {
|
||||
property.usage = PROPERTY_USAGE_NO_EDITOR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (property.name != "fractal_type" && property.name.begins_with("fractal") && get_fractal_type() == FRACTAL_NONE) {
|
||||
property.usage = PROPERTY_USAGE_NO_EDITOR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (property.name == "fractal_ping_pong_strength" && get_fractal_type() != FRACTAL_PING_PONG) {
|
||||
property.usage = PROPERTY_USAGE_NO_EDITOR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (property.name != "domain_warp_enabled" && property.name.begins_with("domain_warp") && !domain_warp_enabled) {
|
||||
property.usage = PROPERTY_USAGE_NO_EDITOR;
|
||||
return;
|
||||
}
|
||||
}
|
237
modules/noise/fastnoise_lite.h
Normal file
237
modules/noise/fastnoise_lite.h
Normal file
|
@ -0,0 +1,237 @@
|
|||
/*************************************************************************/
|
||||
/* fastnoise_lite.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 FASTNOISE_LITE_H
|
||||
#define FASTNOISE_LITE_H
|
||||
|
||||
#include "core/io/image.h"
|
||||
#include "core/object/ref_counted.h"
|
||||
#include "noise.h"
|
||||
#include "scene/resources/gradient.h"
|
||||
|
||||
#include <thirdparty/noise/FastNoiseLite.h>
|
||||
|
||||
typedef fastnoiselite::FastNoiseLite _FastNoiseLite;
|
||||
|
||||
class FastNoiseLite : public Noise {
|
||||
GDCLASS(FastNoiseLite, Noise);
|
||||
OBJ_SAVE_TYPE(FastNoiseLite);
|
||||
|
||||
public:
|
||||
enum NoiseType {
|
||||
TYPE_SIMPLEX = _FastNoiseLite::NoiseType_OpenSimplex2,
|
||||
TYPE_SIMPLEX_SMOOTH = _FastNoiseLite::NoiseType_OpenSimplex2S,
|
||||
TYPE_CELLULAR = _FastNoiseLite::NoiseType_Cellular,
|
||||
TYPE_PERLIN = _FastNoiseLite::NoiseType_Perlin,
|
||||
TYPE_VALUE_CUBIC = _FastNoiseLite::NoiseType_ValueCubic,
|
||||
TYPE_VALUE = _FastNoiseLite::NoiseType_Value,
|
||||
};
|
||||
|
||||
enum FractalType {
|
||||
FRACTAL_NONE = _FastNoiseLite::FractalType_None,
|
||||
FRACTAL_FBM = _FastNoiseLite::FractalType_FBm,
|
||||
FRACTAL_RIDGED = _FastNoiseLite::FractalType_Ridged,
|
||||
FRACTAL_PING_PONG = _FastNoiseLite::FractalType_PingPong,
|
||||
};
|
||||
|
||||
enum CellularDistanceFunction {
|
||||
DISTANCE_EUCLIDEAN = _FastNoiseLite::CellularDistanceFunction_Euclidean,
|
||||
DISTANCE_EUCLIDEAN_SQUARED = _FastNoiseLite::CellularDistanceFunction_EuclideanSq,
|
||||
DISTANCE_MANHATTAN = _FastNoiseLite::CellularDistanceFunction_Manhattan,
|
||||
DISTANCE_HYBRID = _FastNoiseLite::CellularDistanceFunction_Hybrid
|
||||
};
|
||||
|
||||
enum CellularReturnType {
|
||||
RETURN_CELL_VALUE = _FastNoiseLite::CellularReturnType_CellValue,
|
||||
RETURN_DISTANCE = _FastNoiseLite::CellularReturnType_Distance,
|
||||
RETURN_DISTANCE2 = _FastNoiseLite::CellularReturnType_Distance2,
|
||||
RETURN_DISTANCE2_ADD = _FastNoiseLite::CellularReturnType_Distance2Add,
|
||||
RETURN_DISTANCE2_SUB = _FastNoiseLite::CellularReturnType_Distance2Sub,
|
||||
RETURN_DISTANCE2_MUL = _FastNoiseLite::CellularReturnType_Distance2Mul,
|
||||
RETURN_DISTANCE2_DIV = _FastNoiseLite::CellularReturnType_Distance2Div
|
||||
};
|
||||
|
||||
enum DomainWarpType {
|
||||
DOMAIN_WARP_SIMPLEX = _FastNoiseLite::DomainWarpType_OpenSimplex2,
|
||||
DOMAIN_WARP_SIMPLEX_REDUCED = _FastNoiseLite::DomainWarpType_OpenSimplex2Reduced,
|
||||
DOMAIN_WARP_BASIC_GRID = _FastNoiseLite::DomainWarpType_BasicGrid
|
||||
};
|
||||
|
||||
enum DomainWarpFractalType {
|
||||
DOMAIN_WARP_FRACTAL_NONE,
|
||||
DOMAIN_WARP_FRACTAL_PROGRESSIVE,
|
||||
DOMAIN_WARP_FRACTAL_INDEPENDENT
|
||||
};
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
virtual void _validate_property(PropertyInfo &property) const override;
|
||||
|
||||
private:
|
||||
_FastNoiseLite _noise;
|
||||
_FastNoiseLite _domain_warp_noise;
|
||||
|
||||
Vector3 offset;
|
||||
NoiseType noise_type;
|
||||
Ref<Gradient> color_ramp;
|
||||
|
||||
int seed;
|
||||
real_t frequency;
|
||||
bool in_3d_space;
|
||||
|
||||
// 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;
|
||||
|
||||
// Cellular specific.
|
||||
CellularDistanceFunction cellular_distance_function;
|
||||
CellularReturnType cellular_return_type;
|
||||
real_t cellular_jitter;
|
||||
|
||||
// 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;
|
||||
|
||||
public:
|
||||
FastNoiseLite();
|
||||
~FastNoiseLite();
|
||||
|
||||
// General noise settings.
|
||||
|
||||
void set_noise_type(NoiseType p_noise_type);
|
||||
NoiseType get_noise_type() const;
|
||||
|
||||
void set_seed(int p_seed);
|
||||
int get_seed() const;
|
||||
|
||||
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);
|
||||
FractalType get_fractal_type() const;
|
||||
|
||||
void set_fractal_octaves(int p_octaves);
|
||||
int get_fractal_octaves() const;
|
||||
|
||||
void set_fractal_lacunarity(real_t p_lacunarity);
|
||||
real_t get_fractal_lacunarity() const;
|
||||
|
||||
void set_fractal_gain(real_t p_gain);
|
||||
real_t get_fractal_gain() const;
|
||||
|
||||
void set_fractal_weighted_strength(real_t p_weighted_strength);
|
||||
real_t get_fractal_weighted_strength() const;
|
||||
|
||||
void set_fractal_ping_pong_strength(real_t p_ping_pong_strength);
|
||||
real_t get_fractal_ping_pong_strength() const;
|
||||
|
||||
// Cellular specific.
|
||||
|
||||
void set_cellular_distance_function(CellularDistanceFunction p_func);
|
||||
CellularDistanceFunction get_cellular_distance_function() const;
|
||||
|
||||
void set_cellular_return_type(CellularReturnType p_ret);
|
||||
CellularReturnType get_cellular_return_type() const;
|
||||
|
||||
void set_cellular_jitter(real_t p_jitter);
|
||||
real_t get_cellular_jitter() const;
|
||||
|
||||
// Domain warp specific.
|
||||
|
||||
void set_domain_warp_enabled(bool p_enabled);
|
||||
bool is_domain_warp_enabled() const;
|
||||
|
||||
void set_domain_warp_type(DomainWarpType p_domain_warp_type);
|
||||
DomainWarpType get_domain_warp_type() const;
|
||||
|
||||
void set_domain_warp_amplitude(real_t p_amplitude);
|
||||
real_t get_domain_warp_amplitude() const;
|
||||
|
||||
void set_domain_warp_frequency(real_t p_frequency);
|
||||
real_t get_domain_warp_frequency() const;
|
||||
|
||||
void set_domain_warp_fractal_type(DomainWarpFractalType p_domain_warp_fractal_type);
|
||||
DomainWarpFractalType get_domain_warp_fractal_type() const;
|
||||
|
||||
void set_domain_warp_fractal_octaves(int p_octaves);
|
||||
int get_domain_warp_fractal_octaves() const;
|
||||
|
||||
void set_domain_warp_fractal_lacunarity(real_t p_lacunarity);
|
||||
real_t get_domain_warp_fractal_lacunarity() const;
|
||||
|
||||
void set_domain_warp_fractal_gain(real_t p_gain);
|
||||
real_t get_domain_warp_fractal_gain() const;
|
||||
|
||||
// Interface methods.
|
||||
|
||||
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_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;
|
||||
|
||||
void _changed();
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(FastNoiseLite::NoiseType);
|
||||
VARIANT_ENUM_CAST(FastNoiseLite::FractalType);
|
||||
VARIANT_ENUM_CAST(FastNoiseLite::CellularDistanceFunction);
|
||||
VARIANT_ENUM_CAST(FastNoiseLite::CellularReturnType);
|
||||
VARIANT_ENUM_CAST(FastNoiseLite::DomainWarpType);
|
||||
VARIANT_ENUM_CAST(FastNoiseLite::DomainWarpFractalType);
|
||||
|
||||
#endif // FASTNOISE_LITE_H
|
Before Width: | Height: | Size: 307 B After Width: | Height: | Size: 307 B |
68
modules/noise/noise.cpp
Normal file
68
modules/noise/noise.cpp
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*************************************************************************/
|
||||
/* noise.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.h"
|
||||
|
||||
Ref<Image> Noise::get_seamless_image(int p_width, int p_height, bool p_invert, real_t p_blend_skirt) {
|
||||
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);
|
||||
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);
|
||||
} else {
|
||||
return _generate_seamless_image<uint32_t>(src, p_width, p_height, p_invert, p_blend_skirt);
|
||||
}
|
||||
}
|
||||
|
||||
// Template specialization for faster grayscale blending.
|
||||
template <>
|
||||
uint8_t Noise::_alpha_blend<uint8_t>(uint8_t p_bg, uint8_t p_fg, int p_alpha) const {
|
||||
uint16_t alpha = p_alpha + 1;
|
||||
uint16_t inv_alpha = 256 - p_alpha;
|
||||
|
||||
return (uint8_t)((alpha * p_fg + inv_alpha * p_bg) >> 8);
|
||||
}
|
||||
|
||||
void Noise::_bind_methods() {
|
||||
// Noise functions.
|
||||
ClassDB::bind_method(D_METHOD("get_noise_1d", "x"), &Noise::get_noise_1d);
|
||||
ClassDB::bind_method(D_METHOD("get_noise_2d", "x", "y"), &Noise::get_noise_2d);
|
||||
ClassDB::bind_method(D_METHOD("get_noise_2dv", "v"), &Noise::get_noise_2dv);
|
||||
ClassDB::bind_method(D_METHOD("get_noise_3d", "x", "y", "z"), &Noise::get_noise_3d);
|
||||
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));
|
||||
}
|
239
modules/noise/noise.h
Normal file
239
modules/noise/noise.h
Normal file
|
@ -0,0 +1,239 @@
|
|||
/*************************************************************************/
|
||||
/* noise.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_H
|
||||
#define NOISE_H
|
||||
|
||||
#include "core/io/image.h"
|
||||
|
||||
class Noise : public Resource {
|
||||
GDCLASS(Noise, Resource);
|
||||
|
||||
// Helper struct for get_seamless_image(). See comments in .cpp for usage.
|
||||
template <typename T>
|
||||
struct img_buff {
|
||||
T *img;
|
||||
int width; // Array dimensions & default modulo for image.
|
||||
int height;
|
||||
int offset_x; // Offset index location on image (wrapped by specified modulo).
|
||||
int offset_y;
|
||||
int alt_width; // Alternate module for image.
|
||||
int alt_height;
|
||||
|
||||
enum ALT_MODULO {
|
||||
DEFAULT = 0,
|
||||
ALT_X,
|
||||
ALT_Y,
|
||||
ALT_XY
|
||||
};
|
||||
|
||||
// Multi-dimensional array indexer (e.g. img[x][y]) that supports multiple modulos.
|
||||
T &operator()(int x, int y, ALT_MODULO mode = DEFAULT) {
|
||||
switch (mode) {
|
||||
case ALT_XY:
|
||||
return img[(x + offset_x) % alt_width + ((y + offset_y) % alt_height) * width];
|
||||
case ALT_X:
|
||||
return img[(x + offset_x) % alt_width + ((y + offset_y) % height) * width];
|
||||
case ALT_Y:
|
||||
return img[(x + offset_x) % width + ((y + offset_y) % alt_height) * width];
|
||||
default:
|
||||
return img[(x + offset_x) % width + ((y + offset_y) % height) * width];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
union l2c {
|
||||
uint32_t l;
|
||||
uint8_t c[4];
|
||||
struct {
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
uint8_t a;
|
||||
};
|
||||
};
|
||||
|
||||
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) {
|
||||
/*
|
||||
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.
|
||||
|
||||
Noise::img_buff::operator() acts as a multi-dimensional array indexer.
|
||||
It does the array math, translates between the flipped and non-flipped quadrants, and manages offsets and modulos.
|
||||
|
||||
Here is how the larger source image and final output image map to each other:
|
||||
|
||||
Output size = p_width*p_height Source w/ extra 10% skirt `s` size = src_width*src_height
|
||||
Q1 Q2 Q4 Q3 s1
|
||||
Q3 Q4 Q2 Q1 s2
|
||||
s5 s4 s3
|
||||
|
||||
All of the loops use output coordinates, so Output:Q1 == Source:Q1
|
||||
Ex: Output(half_width, half_height) [the midpoint, corner of Q1/Q4] =>
|
||||
on Source it's translated to
|
||||
corner of Q1/s3 unless the ALT_XY modulo moves it to Q4
|
||||
*/
|
||||
|
||||
int skirt_width = MAX(1, p_width * p_blend_skirt);
|
||||
int skirt_height = MAX(1, p_height * p_blend_skirt);
|
||||
int src_width = p_width + skirt_width;
|
||||
int src_height = p_height + skirt_height;
|
||||
int half_width = p_width * .5;
|
||||
int half_height = p_height * .5;
|
||||
int skirt_edge_x = half_width + skirt_width;
|
||||
int skirt_edge_y = half_height + skirt_height;
|
||||
|
||||
Vector<uint8_t> dest;
|
||||
dest.resize(p_width * p_height * Image::get_format_pixel_size(p_src->get_format()));
|
||||
|
||||
img_buff<T> rd_src = {
|
||||
(T *)p_src->get_data().ptr(),
|
||||
src_width, src_height,
|
||||
half_width, half_height,
|
||||
p_width, p_height
|
||||
};
|
||||
|
||||
// `wr` is setup for straight x/y coordinate array access.
|
||||
img_buff<T> wr = {
|
||||
(T *)dest.ptrw(),
|
||||
p_width, p_height,
|
||||
0, 0, 0, 0
|
||||
};
|
||||
// `rd_dest` is a readable pointer to `wr`, i.e. what has already been written to the output buffer.
|
||||
img_buff<T> rd_dest = {
|
||||
(T *)dest.ptr(),
|
||||
p_width, p_height,
|
||||
0, 0, 0, 0
|
||||
};
|
||||
|
||||
// Swap the quadrants to make edges seamless.
|
||||
for (int y = 0; y < p_height; y++) {
|
||||
for (int x = 0; x < p_width; x++) {
|
||||
// rd_src has a half offset and the shorter modulo ignores the skirt.
|
||||
// It reads and writes in Q1-4 order (see map above), skipping the skirt.
|
||||
wr(x, y) = rd_src(x, y, img_buff<T>::ALT_XY);
|
||||
}
|
||||
}
|
||||
|
||||
// Blend the vertical skirt over the middle seam.
|
||||
for (int x = half_width; x < skirt_edge_x; x++) {
|
||||
int alpha = 255 * (1 - Math::smoothstep(.1f, .9f, float(x - half_width) / float(skirt_width)));
|
||||
for (int y = 0; y < p_height; y++) {
|
||||
// Skip the center square
|
||||
if (y == half_height) {
|
||||
y = skirt_edge_y - 1;
|
||||
} else {
|
||||
// Starts reading at s2, ALT_Y skips s3, and continues with s1.
|
||||
wr(x, y) = _alpha_blend<T>(rd_dest(x, y), rd_src(x, y, img_buff<T>::ALT_Y), alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Blend the horizontal skirt over the middle seam.
|
||||
for (int y = half_height; y < skirt_edge_y; y++) {
|
||||
int alpha = 255 * (1 - Math::smoothstep(.1f, .9f, float(y - half_height) / float(skirt_height)));
|
||||
for (int x = 0; x < p_width; x++) {
|
||||
// Skip the center square
|
||||
if (x == half_width) {
|
||||
x = skirt_edge_x - 1;
|
||||
} else {
|
||||
// Starts reading at s4, skips s3, continues with s5.
|
||||
wr(x, y) = _alpha_blend<T>(rd_dest(x, y), rd_src(x, y, img_buff<T>::ALT_X), alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fill in the center square. Wr starts at the top left of Q4, which is the equivalent of the top left of s3, unless a modulo is used.
|
||||
for (int y = half_height; y < skirt_edge_y; y++) {
|
||||
for (int x = half_width; x < skirt_edge_x; x++) {
|
||||
int xpos = 255 * (1 - Math::smoothstep(.1f, .9f, float(x - half_width) / float(skirt_width)));
|
||||
int ypos = 255 * (1 - Math::smoothstep(.1f, .9f, float(y - half_height) / float(skirt_height)));
|
||||
|
||||
// Blend s3(Q1) onto s5(Q2) for the top half.
|
||||
T top_blend = _alpha_blend<T>(rd_src(x, y, img_buff<T>::ALT_X), rd_src(x, y, img_buff<T>::DEFAULT), xpos);
|
||||
// Blend s1(Q3) onto Q4 for the bottom half.
|
||||
T bottom_blend = _alpha_blend<T>(rd_src(x, y, img_buff<T>::ALT_XY), rd_src(x, y, img_buff<T>::ALT_Y), xpos);
|
||||
// Blend the top half onto the bottom half.
|
||||
wr(x, y) = _alpha_blend<T>(bottom_blend, top_blend, ypos);
|
||||
}
|
||||
}
|
||||
Ref<Image> image = memnew(Image(p_width, p_height, false, p_src->get_format(), dest));
|
||||
p_src.unref();
|
||||
return image;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T _alpha_blend(T p_bg, T p_fg, int p_alpha) const {
|
||||
l2c fg, bg, out;
|
||||
|
||||
fg.l = p_fg;
|
||||
bg.l = p_bg;
|
||||
|
||||
uint16_t alpha;
|
||||
uint16_t inv_alpha;
|
||||
|
||||
// If no alpha argument specified, use the alpha channel in the color
|
||||
if (p_alpha == -1) {
|
||||
alpha = fg.c[3] + 1;
|
||||
inv_alpha = 256 - fg.c[3];
|
||||
} else {
|
||||
alpha = p_alpha + 1;
|
||||
inv_alpha = 256 - p_alpha;
|
||||
}
|
||||
|
||||
out.c[0] = (uint8_t)((alpha * fg.c[0] + inv_alpha * bg.c[0]) >> 8);
|
||||
out.c[1] = (uint8_t)((alpha * fg.c[1] + inv_alpha * bg.c[1]) >> 8);
|
||||
out.c[2] = (uint8_t)((alpha * fg.c[2] + inv_alpha * bg.c[2]) >> 8);
|
||||
out.c[3] = 0xFF;
|
||||
|
||||
return out.l;
|
||||
}
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
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_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_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 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);
|
||||
};
|
||||
|
||||
#endif // NOISE_H
|
|
@ -31,9 +31,10 @@
|
|||
#include "noise_texture.h"
|
||||
|
||||
#include "core/core_string_names.h"
|
||||
#include "noise.h"
|
||||
|
||||
NoiseTexture::NoiseTexture() {
|
||||
noise = Ref<OpenSimplexNoise>();
|
||||
noise = Ref<Noise>();
|
||||
|
||||
_queue_update();
|
||||
}
|
||||
|
@ -52,12 +53,15 @@ void NoiseTexture::_bind_methods() {
|
|||
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_noise_offset", "noise_offset"), &NoiseTexture::set_noise_offset);
|
||||
ClassDB::bind_method(D_METHOD("get_noise_offset"), &NoiseTexture::get_noise_offset);
|
||||
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_seamless", "seamless"), &NoiseTexture::set_seamless);
|
||||
ClassDB::bind_method(D_METHOD("get_seamless"), &NoiseTexture::get_seamless);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_seamless_blend_skirt", "seamless_blend_skirt"), &NoiseTexture::set_seamless_blend_skirt);
|
||||
ClassDB::bind_method(D_METHOD("get_seamless_blend_skirt"), &NoiseTexture::get_seamless_blend_skirt);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_as_normal_map", "as_normal_map"), &NoiseTexture::set_as_normal_map);
|
||||
ClassDB::bind_method(D_METHOD("is_normal_map"), &NoiseTexture::is_normal_map);
|
||||
|
||||
|
@ -70,11 +74,12 @@ void NoiseTexture::_bind_methods() {
|
|||
|
||||
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, "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, "noise", PROPERTY_HINT_RESOURCE_TYPE, "OpenSimplexNoise"), "set_noise", "get_noise");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "noise_offset"), "set_noise_offset", "get_noise_offset");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "noise", PROPERTY_HINT_RESOURCE_TYPE, "Noise"), "set_noise", "get_noise");
|
||||
}
|
||||
|
||||
void NoiseTexture::_validate_property(PropertyInfo &property) const {
|
||||
|
@ -83,6 +88,12 @@ void NoiseTexture::_validate_property(PropertyInfo &property) const {
|
|||
property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (property.name == "seamless_blend_skirt") {
|
||||
if (!seamless) {
|
||||
property.usage = PROPERTY_USAGE_NO_EDITOR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NoiseTexture::_set_texture_image(const Ref<Image> &p_image) {
|
||||
|
@ -123,7 +134,7 @@ void NoiseTexture::_queue_update() {
|
|||
|
||||
Ref<Image> NoiseTexture::_generate_texture() {
|
||||
// Prevent memdelete due to unref() on other thread.
|
||||
Ref<OpenSimplexNoise> ref_noise = noise;
|
||||
Ref<Noise> ref_noise = noise;
|
||||
|
||||
if (ref_noise.is_null()) {
|
||||
return Ref<Image>();
|
||||
|
@ -132,9 +143,9 @@ Ref<Image> NoiseTexture::_generate_texture() {
|
|||
Ref<Image> image;
|
||||
|
||||
if (seamless) {
|
||||
image = ref_noise->get_seamless_image(size.x);
|
||||
image = ref_noise->get_seamless_image(size.x, size.y, invert, seamless_blend_skirt);
|
||||
} else {
|
||||
image = ref_noise->get_image(size.x, size.y, noise_offset);
|
||||
image = ref_noise->get_image(size.x, size.y, invert);
|
||||
}
|
||||
|
||||
if (as_normal_map) {
|
||||
|
@ -168,7 +179,7 @@ void NoiseTexture::_update_texture() {
|
|||
update_queued = false;
|
||||
}
|
||||
|
||||
void NoiseTexture::set_noise(Ref<OpenSimplexNoise> p_noise) {
|
||||
void NoiseTexture::set_noise(Ref<Noise> p_noise) {
|
||||
if (p_noise == noise) {
|
||||
return;
|
||||
}
|
||||
|
@ -182,7 +193,7 @@ void NoiseTexture::set_noise(Ref<OpenSimplexNoise> p_noise) {
|
|||
_queue_update();
|
||||
}
|
||||
|
||||
Ref<OpenSimplexNoise> NoiseTexture::get_noise() {
|
||||
Ref<Noise> NoiseTexture::get_noise() {
|
||||
return noise;
|
||||
}
|
||||
|
||||
|
@ -204,26 +215,42 @@ void NoiseTexture::set_height(int p_height) {
|
|||
_queue_update();
|
||||
}
|
||||
|
||||
void NoiseTexture::set_noise_offset(Vector2 p_noise_offset) {
|
||||
if (noise_offset == p_noise_offset) {
|
||||
void NoiseTexture::set_invert(bool p_invert) {
|
||||
if (p_invert == invert) {
|
||||
return;
|
||||
}
|
||||
noise_offset = p_noise_offset;
|
||||
invert = p_invert;
|
||||
_queue_update();
|
||||
}
|
||||
|
||||
bool NoiseTexture::get_invert() const {
|
||||
return invert;
|
||||
}
|
||||
|
||||
void NoiseTexture::set_seamless(bool p_seamless) {
|
||||
if (p_seamless == seamless) {
|
||||
return;
|
||||
}
|
||||
seamless = p_seamless;
|
||||
_queue_update();
|
||||
notify_property_list_changed();
|
||||
}
|
||||
|
||||
bool NoiseTexture::get_seamless() {
|
||||
return seamless;
|
||||
}
|
||||
|
||||
void NoiseTexture::set_seamless_blend_skirt(real_t p_blend_skirt) {
|
||||
if (p_blend_skirt == seamless_blend_skirt) {
|
||||
return;
|
||||
}
|
||||
seamless_blend_skirt = p_blend_skirt;
|
||||
_queue_update();
|
||||
}
|
||||
real_t NoiseTexture::get_seamless_blend_skirt() {
|
||||
return seamless_blend_skirt;
|
||||
}
|
||||
|
||||
void NoiseTexture::set_as_normal_map(bool p_as_normal_map) {
|
||||
if (p_as_normal_map == as_normal_map) {
|
||||
return;
|
||||
|
@ -259,10 +286,6 @@ int NoiseTexture::get_height() const {
|
|||
return size.y;
|
||||
}
|
||||
|
||||
Vector2 NoiseTexture::get_noise_offset() const {
|
||||
return noise_offset;
|
||||
}
|
||||
|
||||
RID NoiseTexture::get_rid() const {
|
||||
if (!texture.is_valid()) {
|
||||
texture = RS::get_singleton()->texture_2d_placeholder_create();
|
|
@ -31,10 +31,10 @@
|
|||
#ifndef NOISE_TEXTURE_H
|
||||
#define NOISE_TEXTURE_H
|
||||
|
||||
#include "open_simplex_noise.h"
|
||||
#include "noise.h"
|
||||
|
||||
#include "core/io/image.h"
|
||||
#include "core/object/ref_counted.h"
|
||||
#include "scene/resources/texture.h"
|
||||
|
||||
class NoiseTexture : public Texture2D {
|
||||
GDCLASS(NoiseTexture, Texture2D);
|
||||
|
@ -51,10 +51,12 @@ private:
|
|||
mutable RID texture;
|
||||
uint32_t flags = 0;
|
||||
|
||||
Ref<OpenSimplexNoise> noise;
|
||||
Ref<Noise> noise;
|
||||
bool invert = false;
|
||||
Vector2i size = Vector2i(512, 512);
|
||||
Vector2 noise_offset;
|
||||
bool seamless = false;
|
||||
real_t seamless_blend_skirt = 0.1;
|
||||
bool as_normal_map = false;
|
||||
float bump_strength = 8.0;
|
||||
|
||||
|
@ -71,18 +73,21 @@ protected:
|
|||
virtual void _validate_property(PropertyInfo &property) const override;
|
||||
|
||||
public:
|
||||
void set_noise(Ref<OpenSimplexNoise> p_noise);
|
||||
Ref<OpenSimplexNoise> get_noise();
|
||||
void set_noise(Ref<Noise> p_noise);
|
||||
Ref<Noise> get_noise();
|
||||
|
||||
void set_width(int p_width);
|
||||
void set_height(int p_height);
|
||||
|
||||
void set_noise_offset(Vector2 p_noise_offset);
|
||||
Vector2 get_noise_offset() const;
|
||||
void set_invert(bool p_invert);
|
||||
bool get_invert() const;
|
||||
|
||||
void set_seamless(bool p_seamless);
|
||||
bool get_seamless();
|
||||
|
||||
void set_seamless_blend_skirt(real_t p_blend_skirt);
|
||||
real_t get_seamless_blend_skirt();
|
||||
|
||||
void set_as_normal_map(bool p_as_normal_map);
|
||||
bool is_normal_map();
|
||||
|
|
@ -29,13 +29,16 @@
|
|||
/*************************************************************************/
|
||||
|
||||
#include "register_types.h"
|
||||
|
||||
#include "fastnoise_lite.h"
|
||||
#include "noise.h"
|
||||
#include "noise_texture.h"
|
||||
#include "open_simplex_noise.h"
|
||||
|
||||
void register_opensimplex_types() {
|
||||
GDREGISTER_CLASS(OpenSimplexNoise);
|
||||
void register_noise_types() {
|
||||
GDREGISTER_CLASS(NoiseTexture);
|
||||
GDREGISTER_ABSTRACT_CLASS(Noise);
|
||||
GDREGISTER_CLASS(FastNoiseLite);
|
||||
}
|
||||
|
||||
void unregister_opensimplex_types() {
|
||||
void unregister_noise_types() {
|
||||
}
|
|
@ -28,10 +28,10 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef OPENSIMPLEX_REGISTER_TYPES_H
|
||||
#define OPENSIMPLEX_REGISTER_TYPES_H
|
||||
#ifndef NOISE_REGISTER_TYPES_H
|
||||
#define NOISE_REGISTER_TYPES_H
|
||||
|
||||
void register_opensimplex_types();
|
||||
void unregister_opensimplex_types();
|
||||
void register_noise_types();
|
||||
void unregister_noise_types();
|
||||
|
||||
#endif // OPENSIMPLEX_REGISTER_TYPES_H
|
||||
#endif // NOISE_REGISTER_TYPES_H
|
|
@ -1,112 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<class name="OpenSimplexNoise" inherits="Resource" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
|
||||
<brief_description>
|
||||
Noise generator based on Open Simplex.
|
||||
</brief_description>
|
||||
<description>
|
||||
This resource allows you to configure and sample a fractal noise space. Here is a brief usage example that configures an OpenSimplexNoise and gets samples at various positions and dimensions:
|
||||
[codeblock]
|
||||
var noise = OpenSimplexNoise.new()
|
||||
|
||||
# Configure
|
||||
noise.seed = randi()
|
||||
noise.octaves = 4
|
||||
noise.period = 20.0
|
||||
noise.persistence = 0.8
|
||||
|
||||
# Sample
|
||||
print("Values:")
|
||||
print(noise.get_noise_2d(1.0, 1.0))
|
||||
print(noise.get_noise_3d(0.5, 3.0, 15.0))
|
||||
print(noise.get_noise_4d(0.5, 1.9, 4.7, 0.0))
|
||||
[/codeblock]
|
||||
</description>
|
||||
<tutorials>
|
||||
</tutorials>
|
||||
<methods>
|
||||
<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="noise_offset" type="Vector2" default="Vector2(0, 0)" />
|
||||
<description>
|
||||
Generate a noise image in [constant Image.FORMAT_L8] format with the requested [code]width[/code] and [code]height[/code], based on the current noise parameters. If [code]noise_offset[/code] is specified, then the offset value is used as the coordinates of the top-left corner of the generated noise.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_noise_1d" qualifiers="const">
|
||||
<return type="float" />
|
||||
<argument index="0" name="x" type="float" />
|
||||
<description>
|
||||
Returns the 1D noise value [code][-1,1][/code] at the given x-coordinate.
|
||||
[b]Note:[/b] This method actually returns the 2D noise value [code][-1,1][/code] with fixed y-coordinate value 0.0.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_noise_2d" qualifiers="const">
|
||||
<return type="float" />
|
||||
<argument index="0" name="x" type="float" />
|
||||
<argument index="1" name="y" type="float" />
|
||||
<description>
|
||||
Returns the 2D noise value [code][-1,1][/code] at the given position.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_noise_2dv" qualifiers="const">
|
||||
<return type="float" />
|
||||
<argument index="0" name="pos" type="Vector2" />
|
||||
<description>
|
||||
Returns the 2D noise value [code][-1,1][/code] at the given position.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_noise_3d" qualifiers="const">
|
||||
<return type="float" />
|
||||
<argument index="0" name="x" type="float" />
|
||||
<argument index="1" name="y" type="float" />
|
||||
<argument index="2" name="z" type="float" />
|
||||
<description>
|
||||
Returns the 3D noise value [code][-1,1][/code] at the given position.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_noise_3dv" qualifiers="const">
|
||||
<return type="float" />
|
||||
<argument index="0" name="pos" type="Vector3" />
|
||||
<description>
|
||||
Returns the 3D noise value [code][-1,1][/code] at the given position.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_noise_4d" qualifiers="const">
|
||||
<return type="float" />
|
||||
<argument index="0" name="x" type="float" />
|
||||
<argument index="1" name="y" type="float" />
|
||||
<argument index="2" name="z" type="float" />
|
||||
<argument index="3" name="w" type="float" />
|
||||
<description>
|
||||
Returns the 4D noise value [code][-1,1][/code] at the given position.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_seamless_image" qualifiers="const">
|
||||
<return type="Image" />
|
||||
<argument index="0" name="size" type="int" />
|
||||
<description>
|
||||
Generate a tileable noise image in [constant Image.FORMAT_L8] format, based on the current noise parameters. Generated seamless images are always square ([code]size[/code] × [code]size[/code]).
|
||||
[b]Note:[/b] Seamless noise has a lower contrast compared to non-seamless noise. This is due to the way noise uses higher dimensions for generating seamless noise.
|
||||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
<members>
|
||||
<member name="lacunarity" type="float" setter="set_lacunarity" getter="get_lacunarity" default="2.0">
|
||||
Difference in period between [member octaves].
|
||||
</member>
|
||||
<member name="octaves" type="int" setter="set_octaves" getter="get_octaves" default="3">
|
||||
Number of OpenSimplex noise layers that are sampled to get the fractal noise. Higher values result in more detailed noise but take more time to generate.
|
||||
[b]Note:[/b] The maximum allowed value is 9.
|
||||
</member>
|
||||
<member name="period" type="float" setter="set_period" getter="get_period" default="64.0">
|
||||
Period of the base octave. A lower period results in a higher-frequency noise (more value changes across the same distance).
|
||||
</member>
|
||||
<member name="persistence" type="float" setter="set_persistence" getter="get_persistence" default="0.5">
|
||||
Contribution factor of the different octaves. A [code]persistence[/code] value of 1 means all the octaves have the same contribution, a value of 0.5 means each octave contributes half as much as the previous one.
|
||||
</member>
|
||||
<member name="seed" type="int" setter="set_seed" getter="get_seed" default="0">
|
||||
Seed used to generate random values, different seeds will generate different noise maps.
|
||||
</member>
|
||||
</members>
|
||||
</class>
|
|
@ -1,250 +0,0 @@
|
|||
/*************************************************************************/
|
||||
/* open_simplex_noise.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 "open_simplex_noise.h"
|
||||
|
||||
#include "core/core_string_names.h"
|
||||
|
||||
OpenSimplexNoise::OpenSimplexNoise() {
|
||||
_init_seeds();
|
||||
}
|
||||
|
||||
OpenSimplexNoise::~OpenSimplexNoise() {
|
||||
}
|
||||
|
||||
void OpenSimplexNoise::_init_seeds() {
|
||||
for (int i = 0; i < MAX_OCTAVES; ++i) {
|
||||
open_simplex_noise(seed + i * 2, &(contexts[i]));
|
||||
}
|
||||
}
|
||||
|
||||
void OpenSimplexNoise::set_seed(int p_seed) {
|
||||
if (seed == p_seed) {
|
||||
return;
|
||||
}
|
||||
|
||||
seed = p_seed;
|
||||
|
||||
_init_seeds();
|
||||
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
int OpenSimplexNoise::get_seed() const {
|
||||
return seed;
|
||||
}
|
||||
|
||||
void OpenSimplexNoise::set_octaves(int p_octaves) {
|
||||
if (p_octaves == octaves) {
|
||||
return;
|
||||
}
|
||||
|
||||
ERR_FAIL_COND_MSG(p_octaves > MAX_OCTAVES, vformat("The number of OpenSimplexNoise octaves is limited to %d; ignoring the new value.", MAX_OCTAVES));
|
||||
|
||||
octaves = CLAMP(p_octaves, 1, MAX_OCTAVES);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
void OpenSimplexNoise::set_period(float p_period) {
|
||||
if (p_period == period) {
|
||||
return;
|
||||
}
|
||||
period = p_period;
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
void OpenSimplexNoise::set_persistence(float p_persistence) {
|
||||
if (p_persistence == persistence) {
|
||||
return;
|
||||
}
|
||||
persistence = p_persistence;
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
void OpenSimplexNoise::set_lacunarity(float p_lacunarity) {
|
||||
if (p_lacunarity == lacunarity) {
|
||||
return;
|
||||
}
|
||||
lacunarity = p_lacunarity;
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
Ref<Image> OpenSimplexNoise::get_image(int p_width, int p_height, const Vector2 &p_noise_offset) const {
|
||||
Vector<uint8_t> data;
|
||||
data.resize(p_width * p_height);
|
||||
|
||||
uint8_t *wd8 = data.ptrw();
|
||||
|
||||
for (int i = 0; i < p_height; i++) {
|
||||
for (int j = 0; j < p_width; j++) {
|
||||
float v = get_noise_2d(float(j) + p_noise_offset.x, float(i) + p_noise_offset.y);
|
||||
v = v * 0.5 + 0.5; // Normalize [0..1]
|
||||
wd8[(i * p_width + j)] = uint8_t(CLAMP(v * 255.0, 0, 255));
|
||||
}
|
||||
}
|
||||
|
||||
Ref<Image> image = memnew(Image(p_width, p_height, false, Image::FORMAT_L8, data));
|
||||
return image;
|
||||
}
|
||||
|
||||
Ref<Image> OpenSimplexNoise::get_seamless_image(int p_size) const {
|
||||
Vector<uint8_t> data;
|
||||
data.resize(p_size * p_size);
|
||||
|
||||
uint8_t *wd8 = data.ptrw();
|
||||
|
||||
for (int i = 0; i < p_size; i++) {
|
||||
for (int j = 0; j < p_size; j++) {
|
||||
float ii = (float)i / (float)p_size;
|
||||
float jj = (float)j / (float)p_size;
|
||||
|
||||
ii *= Math_TAU;
|
||||
jj *= Math_TAU;
|
||||
|
||||
float radius = p_size / Math_TAU;
|
||||
|
||||
float x = radius * Math::sin(jj);
|
||||
float y = radius * Math::cos(jj);
|
||||
float z = radius * Math::sin(ii);
|
||||
float w = radius * Math::cos(ii);
|
||||
float v = get_noise_4d(x, y, z, w);
|
||||
|
||||
v = v * 0.5 + 0.5; // Normalize [0..1]
|
||||
wd8[(i * p_size + j)] = uint8_t(CLAMP(v * 255.0, 0, 255));
|
||||
}
|
||||
}
|
||||
|
||||
Ref<Image> image = memnew(Image(p_size, p_size, false, Image::FORMAT_L8, data));
|
||||
return image;
|
||||
}
|
||||
|
||||
void OpenSimplexNoise::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_seed"), &OpenSimplexNoise::get_seed);
|
||||
ClassDB::bind_method(D_METHOD("set_seed", "seed"), &OpenSimplexNoise::set_seed);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_octaves", "octave_count"), &OpenSimplexNoise::set_octaves);
|
||||
ClassDB::bind_method(D_METHOD("get_octaves"), &OpenSimplexNoise::get_octaves);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_period", "period"), &OpenSimplexNoise::set_period);
|
||||
ClassDB::bind_method(D_METHOD("get_period"), &OpenSimplexNoise::get_period);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_persistence", "persistence"), &OpenSimplexNoise::set_persistence);
|
||||
ClassDB::bind_method(D_METHOD("get_persistence"), &OpenSimplexNoise::get_persistence);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_lacunarity", "lacunarity"), &OpenSimplexNoise::set_lacunarity);
|
||||
ClassDB::bind_method(D_METHOD("get_lacunarity"), &OpenSimplexNoise::get_lacunarity);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_image", "width", "height", "noise_offset"), &OpenSimplexNoise::get_image, DEFVAL(Vector2()));
|
||||
ClassDB::bind_method(D_METHOD("get_seamless_image", "size"), &OpenSimplexNoise::get_seamless_image);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_noise_1d", "x"), &OpenSimplexNoise::get_noise_1d);
|
||||
ClassDB::bind_method(D_METHOD("get_noise_2d", "x", "y"), &OpenSimplexNoise::get_noise_2d);
|
||||
ClassDB::bind_method(D_METHOD("get_noise_3d", "x", "y", "z"), &OpenSimplexNoise::get_noise_3d);
|
||||
ClassDB::bind_method(D_METHOD("get_noise_4d", "x", "y", "z", "w"), &OpenSimplexNoise::get_noise_4d);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_noise_2dv", "pos"), &OpenSimplexNoise::get_noise_2dv);
|
||||
ClassDB::bind_method(D_METHOD("get_noise_3dv", "pos"), &OpenSimplexNoise::get_noise_3dv);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "seed"), "set_seed", "get_seed");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "octaves", PROPERTY_HINT_RANGE, vformat("1,%d,1", MAX_OCTAVES)), "set_octaves", "get_octaves");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "period", PROPERTY_HINT_RANGE, "0.1,256.0,0.1"), "set_period", "get_period");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "persistence", PROPERTY_HINT_RANGE, "0.0,1.0,0.001"), "set_persistence", "get_persistence");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lacunarity", PROPERTY_HINT_RANGE, "0.1,4.0,0.01"), "set_lacunarity", "get_lacunarity");
|
||||
}
|
||||
|
||||
float OpenSimplexNoise::get_noise_1d(float x) const {
|
||||
return get_noise_2d(x, 1.0);
|
||||
}
|
||||
|
||||
float OpenSimplexNoise::get_noise_2d(float x, float y) const {
|
||||
x /= period;
|
||||
y /= period;
|
||||
|
||||
float amp = 1.0;
|
||||
float max = 1.0;
|
||||
float sum = _get_octave_noise_2d(0, x, y);
|
||||
|
||||
int i = 0;
|
||||
while (++i < octaves) {
|
||||
x *= lacunarity;
|
||||
y *= lacunarity;
|
||||
amp *= persistence;
|
||||
max += amp;
|
||||
sum += _get_octave_noise_2d(i, x, y) * amp;
|
||||
}
|
||||
|
||||
return sum / max;
|
||||
}
|
||||
|
||||
float OpenSimplexNoise::get_noise_3d(float x, float y, float z) const {
|
||||
x /= period;
|
||||
y /= period;
|
||||
z /= period;
|
||||
|
||||
float amp = 1.0;
|
||||
float max = 1.0;
|
||||
float sum = _get_octave_noise_3d(0, x, y, z);
|
||||
|
||||
int i = 0;
|
||||
while (++i < octaves) {
|
||||
x *= lacunarity;
|
||||
y *= lacunarity;
|
||||
z *= lacunarity;
|
||||
amp *= persistence;
|
||||
max += amp;
|
||||
sum += _get_octave_noise_3d(i, x, y, z) * amp;
|
||||
}
|
||||
|
||||
return sum / max;
|
||||
}
|
||||
|
||||
float OpenSimplexNoise::get_noise_4d(float x, float y, float z, float w) const {
|
||||
x /= period;
|
||||
y /= period;
|
||||
z /= period;
|
||||
w /= period;
|
||||
|
||||
float amp = 1.0;
|
||||
float max = 1.0;
|
||||
float sum = _get_octave_noise_4d(0, x, y, z, w);
|
||||
|
||||
int i = 0;
|
||||
while (++i < octaves) {
|
||||
x *= lacunarity;
|
||||
y *= lacunarity;
|
||||
z *= lacunarity;
|
||||
w *= lacunarity;
|
||||
amp *= persistence;
|
||||
max += amp;
|
||||
sum += _get_octave_noise_4d(i, x, y, z, w) * amp;
|
||||
}
|
||||
|
||||
return sum / max;
|
||||
}
|
|
@ -1,99 +0,0 @@
|
|||
/*************************************************************************/
|
||||
/* open_simplex_noise.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 OPEN_SIMPLEX_NOISE_H
|
||||
#define OPEN_SIMPLEX_NOISE_H
|
||||
|
||||
#include "core/io/image.h"
|
||||
#include "core/object/ref_counted.h"
|
||||
#include "scene/resources/texture.h"
|
||||
|
||||
#include "thirdparty/misc/open-simplex-noise.h"
|
||||
|
||||
class OpenSimplexNoise : public Resource {
|
||||
GDCLASS(OpenSimplexNoise, Resource);
|
||||
OBJ_SAVE_TYPE(OpenSimplexNoise);
|
||||
|
||||
// The maximum number of octaves allowed. Note that these are statically allocated.
|
||||
// Higher values become exponentially slower, so this shouldn't be set too high
|
||||
// to avoid freezing the editor for long periods of time.
|
||||
static const int MAX_OCTAVES = 9;
|
||||
|
||||
osn_context contexts[MAX_OCTAVES];
|
||||
|
||||
int seed = 0;
|
||||
float persistence = 0.5; // Controls details, value in [0,1]. Higher increases grain, lower increases smoothness.
|
||||
int octaves = 3; // Number of noise layers
|
||||
float period = 64.0; // Distance above which we start to see similarities. The higher, the longer "hills" will be on a terrain.
|
||||
float lacunarity = 2.0; // Controls period change across octaves. 2 is usually a good value to address all detail levels.
|
||||
|
||||
public:
|
||||
OpenSimplexNoise();
|
||||
~OpenSimplexNoise();
|
||||
|
||||
void _init_seeds();
|
||||
|
||||
void set_seed(int seed);
|
||||
int get_seed() const;
|
||||
|
||||
void set_octaves(int p_octaves);
|
||||
int get_octaves() const { return octaves; }
|
||||
|
||||
void set_period(float p_period);
|
||||
float get_period() const { return period; }
|
||||
|
||||
void set_persistence(float p_persistence);
|
||||
float get_persistence() const { return persistence; }
|
||||
|
||||
void set_lacunarity(float p_lacunarity);
|
||||
float get_lacunarity() const { return lacunarity; }
|
||||
|
||||
Ref<Image> get_image(int p_width, int p_height, const Vector2 &p_noise_offset = Vector2()) const;
|
||||
Ref<Image> get_seamless_image(int p_size) const;
|
||||
|
||||
float get_noise_1d(float x) const;
|
||||
float get_noise_2d(float x, float y) const;
|
||||
float get_noise_3d(float x, float y, float z) const;
|
||||
float get_noise_4d(float x, float y, float z, float w) const;
|
||||
|
||||
_FORCE_INLINE_ float _get_octave_noise_2d(int octave, float x, float y) const { return open_simplex_noise2(&(contexts[octave]), x, y); }
|
||||
_FORCE_INLINE_ float _get_octave_noise_3d(int octave, float x, float y, float z) const { return open_simplex_noise3(&(contexts[octave]), x, y, z); }
|
||||
_FORCE_INLINE_ float _get_octave_noise_4d(int octave, float x, float y, float z, float w) const { return open_simplex_noise4(&(contexts[octave]), x, y, z, w); }
|
||||
|
||||
// Convenience
|
||||
|
||||
_FORCE_INLINE_ float get_noise_2dv(const Vector2 &v) const { return get_noise_2d(v.x, v.y); }
|
||||
_FORCE_INLINE_ float get_noise_3dv(const Vector3 &v) const { return get_noise_3d(v.x, v.y, v.z); }
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
};
|
||||
|
||||
#endif // OPEN_SIMPLEX_NOISE_H
|
8
thirdparty/README.md
vendored
8
thirdparty/README.md
vendored
|
@ -424,10 +424,10 @@ Collection of single-file libraries used in Godot components.
|
|||
* Upstream: https://archive.blender.org/wiki/index.php/Dev:Shading/Tangent_Space_Normal_Maps/
|
||||
* Version: 1.0 (2011)
|
||||
* License: zlib
|
||||
- `open-simplex-noise.{c,h}`
|
||||
* Upstream: https://github.com/smcameron/open-simplex-noise-in-c
|
||||
* Version: git (826f1dd1724e6fb3ff45f58e48c0fbae864c3403, 2020) + custom changes
|
||||
* License: Public Domain or Unlicense
|
||||
- `FastNoiseLite.h}`
|
||||
* Upstream: https://github.com/Auburn/FastNoiseLite
|
||||
* Version: git (6be3d6bf7fb408de341285f9ee8a29b67fd953f1, 2022) + custom changes
|
||||
* License: MIT
|
||||
- `pcg.{cpp,h}`
|
||||
* Upstream: http://www.pcg-random.org
|
||||
* Version: minimal C implementation, http://www.pcg-random.org/download.html
|
||||
|
|
25
thirdparty/misc/open-simplex-noise-LICENSE
vendored
25
thirdparty/misc/open-simplex-noise-LICENSE
vendored
|
@ -1,25 +0,0 @@
|
|||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
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 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.
|
||||
|
||||
For more information, please refer to <http://unlicense.org>
|
||||
|
133
thirdparty/misc/open-simplex-noise-no-allocate.patch
vendored
133
thirdparty/misc/open-simplex-noise-no-allocate.patch
vendored
|
@ -1,133 +0,0 @@
|
|||
diff -u orig/open-simplex-noise.c misc/open-simplex-noise.c
|
||||
--- orig/open-simplex-noise.c 2018-09-14 11:11:40.049810000 +0200
|
||||
+++ misc/open-simplex-noise.c 2018-09-14 11:09:39.726457000 +0200
|
||||
@@ -13,6 +13,11 @@
|
||||
* of any particular randomization library, so results
|
||||
* will be the same when ported to other languages.
|
||||
*/
|
||||
+
|
||||
+// -- GODOT start --
|
||||
+// Modified to work without allocating memory, also removed some unused function.
|
||||
+// -- GODOT end --
|
||||
+
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
@@ -34,11 +39,12 @@
|
||||
|
||||
#define DEFAULT_SEED (0LL)
|
||||
|
||||
-struct osn_context {
|
||||
+// -- GODOT start --
|
||||
+/*struct osn_context {
|
||||
int16_t *perm;
|
||||
int16_t *permGradIndex3D;
|
||||
-};
|
||||
-
|
||||
+};*/
|
||||
+// -- GODOT end --
|
||||
#define ARRAYSIZE(x) (sizeof((x)) / sizeof((x)[0]))
|
||||
|
||||
/*
|
||||
@@ -126,7 +132,9 @@
|
||||
int xi = (int) x;
|
||||
return x < xi ? xi - 1 : xi;
|
||||
}
|
||||
-
|
||||
+
|
||||
+// -- GODOT start --
|
||||
+/*
|
||||
static int allocate_perm(struct osn_context *ctx, int nperm, int ngrad)
|
||||
{
|
||||
if (ctx->perm)
|
||||
@@ -154,18 +162,21 @@
|
||||
memcpy(ctx->perm, p, sizeof(*ctx->perm) * nelements);
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
- /* Since 3D has 24 gradients, simple bitmask won't work, so precompute modulo array. */
|
||||
+ // Since 3D has 24 gradients, simple bitmask won't work, so precompute modulo array.
|
||||
ctx->permGradIndex3D[i] = (int16_t)((ctx->perm[i] % (ARRAYSIZE(gradients3D) / 3)) * 3);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
+*/
|
||||
+// -- GODOT end --
|
||||
|
||||
/*
|
||||
* Initializes using a permutation array generated from a 64-bit seed.
|
||||
* Generates a proper permutation (i.e. doesn't merely perform N successive pair
|
||||
* swaps on a base array). Uses a simple 64-bit LCG.
|
||||
*/
|
||||
-int open_simplex_noise(int64_t seed, struct osn_context **ctx)
|
||||
+// -- GODOT start --
|
||||
+int open_simplex_noise(int64_t seed, struct osn_context *ctx)
|
||||
{
|
||||
int rc;
|
||||
int16_t source[256];
|
||||
@@ -174,20 +185,9 @@
|
||||
int16_t *permGradIndex3D;
|
||||
int r;
|
||||
|
||||
- *ctx = (struct osn_context *) malloc(sizeof(**ctx));
|
||||
- if (!(*ctx))
|
||||
- return -ENOMEM;
|
||||
- (*ctx)->perm = NULL;
|
||||
- (*ctx)->permGradIndex3D = NULL;
|
||||
-
|
||||
- rc = allocate_perm(*ctx, 256, 256);
|
||||
- if (rc) {
|
||||
- free(*ctx);
|
||||
- return rc;
|
||||
- }
|
||||
-
|
||||
- perm = (*ctx)->perm;
|
||||
- permGradIndex3D = (*ctx)->permGradIndex3D;
|
||||
+ perm = ctx->perm;
|
||||
+ permGradIndex3D = ctx->permGradIndex3D;
|
||||
+// -- GODOT end --
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
source[i] = (int16_t) i;
|
||||
@@ -206,6 +206,8 @@
|
||||
return 0;
|
||||
}
|
||||
|
||||
+// -- GODOT start --
|
||||
+/*
|
||||
void open_simplex_noise_free(struct osn_context *ctx)
|
||||
{
|
||||
if (!ctx)
|
||||
@@ -220,6 +222,8 @@
|
||||
}
|
||||
free(ctx);
|
||||
}
|
||||
+*/
|
||||
+// -- GODOT end --
|
||||
|
||||
/* 2D OpenSimplex (Simplectic) Noise. */
|
||||
double open_simplex_noise2(struct osn_context *ctx, double x, double y)
|
||||
diff -u orig/open-simplex-noise.h misc/open-simplex-noise.h
|
||||
--- orig/open-simplex-noise.h 2018-09-14 11:11:19.659807000 +0200
|
||||
+++ misc/open-simplex-noise.h 2018-09-14 11:10:05.006460000 +0200
|
||||
@@ -35,11 +35,18 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
-struct osn_context;
|
||||
+// -- GODOT start --
|
||||
+// Modified to work without allocating memory, also removed some unused function.
|
||||
|
||||
-int open_simplex_noise(int64_t seed, struct osn_context **ctx);
|
||||
+struct osn_context {
|
||||
+ int16_t perm[256];
|
||||
+ int16_t permGradIndex3D[256];
|
||||
+};
|
||||
+
|
||||
+int open_simplex_noise(int64_t seed, struct osn_context *ctx);
|
||||
+//int open_simplex_noise_init_perm(struct osn_context *ctx, int16_t p[], int nelements);
|
||||
+// -- GODOT end --
|
||||
void open_simplex_noise_free(struct osn_context *ctx);
|
||||
-int open_simplex_noise_init_perm(struct osn_context *ctx, int16_t p[], int nelements);
|
||||
double open_simplex_noise2(struct osn_context *ctx, double x, double y);
|
||||
double open_simplex_noise3(struct osn_context *ctx, double x, double y, double z);
|
||||
double open_simplex_noise4(struct osn_context *ctx, double x, double y, double z, double w);
|
2255
thirdparty/misc/open-simplex-noise.c
vendored
2255
thirdparty/misc/open-simplex-noise.c
vendored
File diff suppressed because it is too large
Load diff
58
thirdparty/misc/open-simplex-noise.h
vendored
58
thirdparty/misc/open-simplex-noise.h
vendored
|
@ -1,58 +0,0 @@
|
|||
#ifndef OPEN_SIMPLEX_NOISE_H__
|
||||
#define OPEN_SIMPLEX_NOISE_H__
|
||||
|
||||
/*
|
||||
* OpenSimplex (Simplectic) Noise in C.
|
||||
* Ported to C from Kurt Spencer's java implementation by Stephen M. Cameron
|
||||
*
|
||||
* v1.1 (October 6, 2014)
|
||||
* - Ported to C
|
||||
*
|
||||
* v1.1 (October 5, 2014)
|
||||
* - Added 2D and 4D implementations.
|
||||
* - Proper gradient sets for all dimensions, from a
|
||||
* dimensionally-generalizable scheme with an actual
|
||||
* rhyme and reason behind it.
|
||||
* - Removed default permutation array in favor of
|
||||
* default seed.
|
||||
* - Changed seed-based constructor to be independent
|
||||
* of any particular randomization library, so results
|
||||
* will be the same when ported to other languages.
|
||||
*/
|
||||
|
||||
#if ((__GNUC_STDC_INLINE__) || (__STDC_VERSION__ >= 199901L))
|
||||
#include <stdint.h>
|
||||
#define INLINE inline
|
||||
#elif (defined (_MSC_VER) || defined (__GNUC_GNU_INLINE__))
|
||||
#include <stdint.h>
|
||||
#define INLINE __inline
|
||||
#else
|
||||
/* ANSI C doesn't have inline or stdint.h. */
|
||||
#define INLINE
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// -- GODOT start --
|
||||
// Modified to work without allocating memory, also removed some unused function.
|
||||
|
||||
struct osn_context {
|
||||
int16_t perm[256];
|
||||
int16_t permGradIndex3D[256];
|
||||
};
|
||||
|
||||
int open_simplex_noise(int64_t seed, struct osn_context *ctx);
|
||||
//int open_simplex_noise_init_perm(struct osn_context *ctx, int16_t p[], int nelements);
|
||||
// -- GODOT end --
|
||||
void open_simplex_noise_free(struct osn_context *ctx);
|
||||
double open_simplex_noise2(const struct osn_context *ctx, double x, double y);
|
||||
double open_simplex_noise3(const struct osn_context *ctx, double x, double y, double z);
|
||||
double open_simplex_noise4(const struct osn_context *ctx, double x, double y, double z, double w);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
22
thirdparty/noise/FastNoise-LICENSE
vendored
Normal file
22
thirdparty/noise/FastNoise-LICENSE
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
MIT License
|
||||
|
||||
Copyright(c) 2020 Jordan Peck (jordan.me2@gmail.com)
|
||||
Copyright(c) 2020 Contributors
|
||||
|
||||
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.
|
2589
thirdparty/noise/FastNoiseLite.h
vendored
Normal file
2589
thirdparty/noise/FastNoiseLite.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
18
thirdparty/noise/patches/FastNoiseLite.patch
vendored
Normal file
18
thirdparty/noise/patches/FastNoiseLite.patch
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
--- orig/FastNoiseLite.h 1900-01-00 00:00:00 +0000
|
||||
+++ noise/FastNoiseLite.h 1900-01-00 00:00:00 +0000
|
||||
@@ -52,6 +52,8 @@
|
||||
|
||||
#include <cmath>
|
||||
|
||||
+namespace fastnoiselite{
|
||||
+
|
||||
class FastNoiseLite
|
||||
{
|
||||
public:
|
||||
@@ -2583,4 +2585,5 @@
|
||||
-0.7870349638f, 0.03447489231f, 0.6159443543f, 0, -0.2015596421f, 0.6859872284f, 0.6991389226f, 0, -0.08581082512f, -0.10920836f, -0.9903080513f, 0, 0.5532693395f, 0.7325250401f, -0.396610771f, 0, -0.1842489331f, -0.9777375055f, -0.1004076743f, 0, 0.0775473789f, -0.9111505856f, 0.4047110257f, 0, 0.1399838409f, 0.7601631212f, -0.6344734459f, 0, 0.4484419361f, -0.845289248f, 0.2904925424f, 0
|
||||
};
|
||||
|
||||
-#endif
|
||||
+}
|
||||
+#endif // namespace fastnoiselite
|
Loading…
Reference in a new issue