Skip to content

Commit

Permalink
Merge pull request #48805 from radishes/noise-image-offset
Browse files Browse the repository at this point in the history
Add support for generating noise images with an offset
  • Loading branch information
akien-mga authored May 20, 2021
2 parents 28c7e28 + 97c8d9f commit 78d85de
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 6 deletions.
3 changes: 3 additions & 0 deletions modules/opensimplex/doc_classes/NoiseTexture.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
<member name="noise" type="OpenSimplexNoise" setter="set_noise" getter="get_noise">
The [OpenSimplexNoise] instance used to generate the noise.
</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">
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.
Expand Down
4 changes: 3 additions & 1 deletion modules/opensimplex/doc_classes/OpenSimplexNoise.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@
</argument>
<argument index="1" name="height" type="int">
</argument>
<argument index="2" name="noise_offset" type="Vector2" default="Vector2( 0, 0 )">
</argument>
<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>
</method>
<method name="get_noise_1d" qualifiers="const">
Expand Down
18 changes: 17 additions & 1 deletion modules/opensimplex/noise_texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ 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_seamless", "seamless"), &NoiseTexture::set_seamless);
ClassDB::bind_method(D_METHOD("get_seamless"), &NoiseTexture::get_seamless);

Expand All @@ -71,6 +74,7 @@ void NoiseTexture::_bind_methods() {
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");
}

void NoiseTexture::_validate_property(PropertyInfo &property) const {
Expand Down Expand Up @@ -130,7 +134,7 @@ Ref<Image> NoiseTexture::_generate_texture() {
if (seamless) {
image = ref_noise->get_seamless_image(size.x);
} else {
image = ref_noise->get_image(size.x, size.y);
image = ref_noise->get_image(size.x, size.y, noise_offset);
}

if (as_normal_map) {
Expand Down Expand Up @@ -198,6 +202,14 @@ void NoiseTexture::set_height(int p_height) {
_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) {
if (p_seamless == seamless) {
return;
Expand Down Expand Up @@ -245,6 +257,10 @@ 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();
Expand Down
4 changes: 4 additions & 0 deletions modules/opensimplex/noise_texture.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class NoiseTexture : public Texture2D {

Ref<OpenSimplexNoise> noise;
Vector2i size = Vector2i(512, 512);
Vector2 noise_offset;
bool seamless = false;
bool as_normal_map = false;
float bump_strength = 8.0;
Expand All @@ -79,6 +80,9 @@ class NoiseTexture : public Texture2D {
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_seamless(bool p_seamless);
bool get_seamless();

Expand Down
6 changes: 3 additions & 3 deletions modules/opensimplex/open_simplex_noise.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,15 +96,15 @@ void OpenSimplexNoise::set_lacunarity(float p_lacunarity) {
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 {
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(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]
wd8[(i * p_width + j)] = uint8_t(CLAMP(v * 255.0, 0, 255));
}
Expand Down Expand Up @@ -161,7 +161,7 @@ void OpenSimplexNoise::_bind_methods() {
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"), &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_noise_1d", "x"), &OpenSimplexNoise::get_noise_1d);
Expand Down
2 changes: 1 addition & 1 deletion modules/opensimplex/open_simplex_noise.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class OpenSimplexNoise : public Resource {
void set_lacunarity(float p_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;

float get_noise_1d(float x) const;
Expand Down

0 comments on commit 78d85de

Please sign in to comment.