Merge pull request #48805 from radishes/noise-image-offset
Add support for generating noise images with an offset
This commit is contained in:
commit
78d85de13b
|
@ -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.
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -52,6 +52,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);
|
||||||
|
|
||||||
|
@ -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::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::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::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 {
|
||||||
|
@ -130,7 +134,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_normal_map) {
|
if (as_normal_map) {
|
||||||
|
@ -198,6 +202,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;
|
||||||
|
@ -245,6 +257,10 @@ int NoiseTexture::get_height() const {
|
||||||
return size.y;
|
return size.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector2 NoiseTexture::get_noise_offset() const {
|
||||||
|
return noise_offset;
|
||||||
|
}
|
||||||
|
|
||||||
RID NoiseTexture::get_rid() const {
|
RID NoiseTexture::get_rid() const {
|
||||||
if (!texture.is_valid()) {
|
if (!texture.is_valid()) {
|
||||||
texture = RS::get_singleton()->texture_2d_placeholder_create();
|
texture = RS::get_singleton()->texture_2d_placeholder_create();
|
||||||
|
|
|
@ -56,6 +56,7 @@ private:
|
||||||
|
|
||||||
Ref<OpenSimplexNoise> noise;
|
Ref<OpenSimplexNoise> noise;
|
||||||
Vector2i size = Vector2i(512, 512);
|
Vector2i size = Vector2i(512, 512);
|
||||||
|
Vector2 noise_offset;
|
||||||
bool seamless = false;
|
bool seamless = false;
|
||||||
bool as_normal_map = false;
|
bool as_normal_map = false;
|
||||||
float bump_strength = 8.0;
|
float bump_strength = 8.0;
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -96,7 +96,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 {
|
||||||
Vector<uint8_t> data;
|
Vector<uint8_t> data;
|
||||||
data.resize(p_width * p_height);
|
data.resize(p_width * p_height);
|
||||||
|
|
||||||
|
@ -104,7 +104,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));
|
||||||
}
|
}
|
||||||
|
@ -161,7 +161,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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue