Browse Source

Add support for generating noise images with an offset.

(cherry picked from commit 97c8d9f3484de06728235e516b8885bba277efd6)
Casey Foote 4 years ago
parent
commit
ecf8d99d37

+ 3 - 0
modules/opensimplex/doc_classes/NoiseTexture.xml

@@ -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.

+ 3 - 1
modules/opensimplex/doc_classes/OpenSimplexNoise.xml

@@ -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">

+ 17 - 1
modules/opensimplex/noise_texture.cpp

@@ -62,6 +62,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);
 
@@ -82,6 +85,7 @@ void NoiseTexture::_bind_methods() {
 	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::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 {
@@ -137,7 +141,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_normalmap) {
@@ -205,6 +209,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;
@@ -252,6 +264,10 @@ int NoiseTexture::get_height() const {
 	return size.y;
 }
 
+Vector2 NoiseTexture::get_noise_offset() const {
+	return noise_offset;
+}
+
 void NoiseTexture::set_flags(uint32_t p_flags) {
 	flags = p_flags;
 	VS::get_singleton()->texture_set_flags(texture, flags);

+ 4 - 0
modules/opensimplex/noise_texture.h

@@ -56,6 +56,7 @@ private:
 
 	Ref<OpenSimplexNoise> noise;
 	Vector2i size;
+	Vector2 noise_offset;
 	bool seamless;
 	bool as_normalmap;
 	float bump_strength;
@@ -79,6 +80,9 @@ public:
 	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();
 

+ 3 - 3
modules/opensimplex/open_simplex_noise.cpp

@@ -102,7 +102,7 @@ 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 {
 	PoolVector<uint8_t> data;
 	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 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));
 		}
@@ -167,7 +167,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);

+ 1 - 1
modules/opensimplex/open_simplex_noise.h

@@ -75,7 +75,7 @@ public:
 	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;