Add support for generating noise images with an offset.

(cherry picked from commit 97c8d9f348)
This commit is contained in:
Casey Foote 2021-05-17 21:51:05 -07:00 committed by Rémi Verschelde
parent 68f92e6785
commit ecf8d99d37
No known key found for this signature in database
GPG key ID: C3336907360768E1
6 changed files with 31 additions and 6 deletions

View file

@ -31,6 +31,9 @@
<member name="noise" type="OpenSimplexNoise" setter="set_noise" getter="get_noise"> <member name="noise" type="OpenSimplexNoise" setter="set_noise" getter="get_noise">
The [OpenSimplexNoise] instance used to generate the noise. The [OpenSimplexNoise] instance used to generate the noise.
</member> </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>
<member name="seamless" type="bool" setter="set_seamless" getter="get_seamless" default="false"> <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. 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. [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.

View file

@ -31,8 +31,10 @@
</argument> </argument>
<argument index="1" name="height" type="int"> <argument index="1" name="height" type="int">
</argument> </argument>
<argument index="2" name="noise_offset" type="Vector2" default="Vector2( 0, 0 )">
</argument>
<description> <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. 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> </description>
</method> </method>
<method name="get_noise_1d" qualifiers="const"> <method name="get_noise_1d" qualifiers="const">

View file

@ -62,6 +62,9 @@ void NoiseTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_noise", "noise"), &NoiseTexture::set_noise); 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("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_seamless", "seamless"), &NoiseTexture::set_seamless); 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("get_seamless"), &NoiseTexture::get_seamless);
@ -82,6 +85,7 @@ void NoiseTexture::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "as_normalmap"), "set_as_normalmap", "is_normalmap"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "as_normalmap"), "set_as_normalmap", "is_normalmap");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "bump_strength", PROPERTY_HINT_RANGE, "0,32,0.1,or_greater"), "set_bump_strength", "get_bump_strength"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "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::OBJECT, "noise", PROPERTY_HINT_RESOURCE_TYPE, "OpenSimplexNoise"), "set_noise", "get_noise");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "noise_offset"), "set_noise_offset", "get_noise_offset");
} }
void NoiseTexture::_validate_property(PropertyInfo &property) const { void NoiseTexture::_validate_property(PropertyInfo &property) const {
@ -137,7 +141,7 @@ Ref<Image> NoiseTexture::_generate_texture() {
if (seamless) { if (seamless) {
image = ref_noise->get_seamless_image(size.x); image = ref_noise->get_seamless_image(size.x);
} else { } else {
image = ref_noise->get_image(size.x, size.y); image = ref_noise->get_image(size.x, size.y, noise_offset);
} }
if (as_normalmap) { if (as_normalmap) {
@ -205,6 +209,14 @@ void NoiseTexture::set_height(int p_height) {
_queue_update(); _queue_update();
} }
void NoiseTexture::set_noise_offset(Vector2 p_noise_offset) {
if (noise_offset == p_noise_offset) {
return;
}
noise_offset = p_noise_offset;
_queue_update();
}
void NoiseTexture::set_seamless(bool p_seamless) { void NoiseTexture::set_seamless(bool p_seamless) {
if (p_seamless == seamless) { if (p_seamless == seamless) {
return; return;
@ -252,6 +264,10 @@ int NoiseTexture::get_height() const {
return size.y; return size.y;
} }
Vector2 NoiseTexture::get_noise_offset() const {
return noise_offset;
}
void NoiseTexture::set_flags(uint32_t p_flags) { void NoiseTexture::set_flags(uint32_t p_flags) {
flags = p_flags; flags = p_flags;
VS::get_singleton()->texture_set_flags(texture, flags); VS::get_singleton()->texture_set_flags(texture, flags);

View file

@ -56,6 +56,7 @@ private:
Ref<OpenSimplexNoise> noise; Ref<OpenSimplexNoise> noise;
Vector2i size; Vector2i size;
Vector2 noise_offset;
bool seamless; bool seamless;
bool as_normalmap; bool as_normalmap;
float bump_strength; float bump_strength;
@ -79,6 +80,9 @@ public:
void set_width(int p_width); void set_width(int p_width);
void set_height(int p_height); void set_height(int p_height);
void set_noise_offset(Vector2 p_noise_offset);
Vector2 get_noise_offset() const;
void set_seamless(bool p_seamless); void set_seamless(bool p_seamless);
bool get_seamless(); bool get_seamless();

View file

@ -102,7 +102,7 @@ void OpenSimplexNoise::set_lacunarity(float p_lacunarity) {
emit_changed(); emit_changed();
} }
Ref<Image> OpenSimplexNoise::get_image(int p_width, int p_height) const { Ref<Image> OpenSimplexNoise::get_image(int p_width, int p_height, const Vector2 &p_noise_offset) const {
PoolVector<uint8_t> data; PoolVector<uint8_t> data;
data.resize(p_width * p_height); data.resize(p_width * p_height);
@ -110,7 +110,7 @@ Ref<Image> OpenSimplexNoise::get_image(int p_width, int p_height) const {
for (int i = 0; i < p_height; i++) { for (int i = 0; i < p_height; i++) {
for (int j = 0; j < p_width; j++) { for (int j = 0; j < p_width; j++) {
float v = get_noise_2d(j, i); 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] v = v * 0.5 + 0.5; // Normalize [0..1]
wd8[(i * p_width + j)] = uint8_t(CLAMP(v * 255.0, 0, 255)); wd8[(i * p_width + j)] = uint8_t(CLAMP(v * 255.0, 0, 255));
} }
@ -167,7 +167,7 @@ void OpenSimplexNoise::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_lacunarity", "lacunarity"), &OpenSimplexNoise::set_lacunarity); 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_lacunarity"), &OpenSimplexNoise::get_lacunarity);
ClassDB::bind_method(D_METHOD("get_image", "width", "height"), &OpenSimplexNoise::get_image); 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_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_1d", "x"), &OpenSimplexNoise::get_noise_1d);

View file

@ -75,7 +75,7 @@ public:
void set_lacunarity(float p_lacunarity); void set_lacunarity(float p_lacunarity);
float get_lacunarity() const { return lacunarity; } float get_lacunarity() const { return lacunarity; }
Ref<Image> get_image(int p_width, int p_height) const; 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; Ref<Image> get_seamless_image(int p_size) const;
float get_noise_1d(float x) const; float get_noise_1d(float x) const;