Skip to content

Commit

Permalink
Merge pull request #76486 from Lasuch69/add-noisetexture3d-no-mipmaps
Browse files Browse the repository at this point in the history
Add NoiseTexture3D
  • Loading branch information
akien-mga committed Apr 27, 2023
2 parents 5cc50c1 + 0de6ad6 commit fb3d3bf
Show file tree
Hide file tree
Showing 11 changed files with 895 additions and 21 deletions.
1 change: 1 addition & 0 deletions modules/noise/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ def get_doc_classes():
"FastNoiseLite",
"Noise",
"NoiseTexture2D",
"NoiseTexture3D",
]


Expand Down
16 changes: 9 additions & 7 deletions modules/noise/doc_classes/Noise.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@
<return type="Image" />
<param index="0" name="width" type="int" />
<param index="1" name="height" type="int" />
<param index="2" name="invert" type="bool" default="false" />
<param index="3" name="in_3d_space" type="bool" default="false" />
<param index="4" name="normalize" type="bool" default="true" />
<param index="2" name="depth" type="int" />
<param index="3" name="invert" type="bool" default="false" />
<param index="4" name="in_3d_space" type="bool" default="false" />
<param index="5" name="normalize" type="bool" default="true" />
<description>
Returns a 2D [Image] noise image.
Note: With [param normalize] set to [code]false[/code] the default implementation expects the noise generator to return values in the range [code]-1.0[/code] to [code]1.0[/code].
Expand Down Expand Up @@ -65,10 +66,11 @@
<return type="Image" />
<param index="0" name="width" type="int" />
<param index="1" name="height" type="int" />
<param index="2" name="invert" type="bool" default="false" />
<param index="3" name="in_3d_space" type="bool" default="false" />
<param index="4" name="skirt" type="float" default="0.1" />
<param index="5" name="normalize" type="bool" default="true" />
<param index="2" name="depth" type="int" />
<param index="3" name="invert" type="bool" default="false" />
<param index="4" name="in_3d_space" type="bool" default="false" />
<param index="5" name="skirt" type="float" default="0.1" />
<param index="6" name="normalize" type="bool" default="true" />
<description>
Returns a seamless 2D [Image] noise image.
Note: With [param normalize] set to [code]false[/code] the default implementation expects the noise generator to return values in the range [code]-1.0[/code] to [code]1.0[/code].
Expand Down
50 changes: 50 additions & 0 deletions modules/noise/doc_classes/NoiseTexture3D.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="NoiseTexture3D" inherits="Texture3D" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
<brief_description>
A texture filled with noise generated by a [Noise] object.
</brief_description>
<description>
Uses [FastNoiseLite] or other libraries to fill the texture data of your desired size.
The class uses [Thread]s to generate the texture data internally, so [method Texture3D.get_data] 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 = NoiseTexture3D.new()
texture.noise = FastNoiseLite.new()
await texture.changed
var data = texture.get_data()
var image = data[0]
[/codeblock]
</description>
<tutorials>
</tutorials>
<members>
<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="depth" type="int" setter="set_depth" getter="get_depth" default="64">
Depth of the generated texture.
</member>
<member name="height" type="int" setter="set_height" getter="get_height" default="64">
Height of the generated texture.
</member>
<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" type="Noise" setter="set_noise" getter="get_noise">
The instance of the [Noise] object.
</member>
<member name="normalize" type="bool" setter="set_normalize" getter="is_normalized" default="true">
If [code]true[/code], the noise image coming from the noise generator is normalized to the range [code]0.0[/code] to [code]1.0[/code].
Turning normalization off can affect the contrast and allows you to generate non repeating tileable noise textures.
</member>
<member name="seamless" type="bool" setter="set_seamless" getter="get_seamless" default="false">
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="64">
Width of the generated texture.
</member>
</members>
</class>
14 changes: 7 additions & 7 deletions modules/noise/noise.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@

#include <float.h>

Ref<Image> Noise::get_seamless_image(int p_width, int p_height, bool p_invert, bool p_in_3d_space, real_t p_blend_skirt, bool p_normalize) const {
Ref<Image> Noise::get_seamless_image(int p_width, int p_height, int p_depth, bool p_invert, bool p_in_3d_space, real_t p_blend_skirt, bool p_normalize) const {
ERR_FAIL_COND_V(p_width <= 0 || p_height <= 0, Ref<Image>());

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;

Ref<Image> src = get_image(src_width, src_height, p_invert, p_in_3d_space, p_normalize);
Ref<Image> src = get_image(src_width, src_height, p_depth, p_invert, p_in_3d_space, p_normalize);
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);
Expand All @@ -58,7 +58,7 @@ uint8_t Noise::_alpha_blend<uint8_t>(uint8_t p_bg, uint8_t p_fg, int p_alpha) co
return (uint8_t)((alpha * p_fg + inv_alpha * p_bg) >> 8);
}

Ref<Image> Noise::get_image(int p_width, int p_height, bool p_invert, bool p_in_3d_space, bool p_normalize) const {
Ref<Image> Noise::get_image(int p_width, int p_height, int p_depth, bool p_invert, bool p_in_3d_space, bool p_normalize) const {
ERR_FAIL_COND_V(p_width <= 0 || p_height <= 0, Ref<Image>());

Vector<uint8_t> data;
Expand All @@ -74,7 +74,7 @@ Ref<Image> Noise::get_image(int p_width, int p_height, bool p_invert, bool p_in_
real_t max_val = -FLT_MAX;
for (int y = 0, i = 0; y < p_height; y++) {
for (int x = 0; x < p_width; x++, i++) {
values.set(i, p_in_3d_space ? get_noise_3d(x, y, 0.0) : get_noise_2d(x, y));
values.set(i, p_in_3d_space ? get_noise_3d(x, y, p_depth) : get_noise_2d(x, y));
if (values[i] > max_val) {
max_val = values[i];
}
Expand Down Expand Up @@ -105,7 +105,7 @@ Ref<Image> Noise::get_image(int p_width, int p_height, bool p_invert, bool p_in_
uint8_t ivalue;
for (int y = 0, i = 0; y < p_height; y++) {
for (int x = 0; x < p_width; x++, i++) {
float value = (p_in_3d_space ? get_noise_3d(x, y, 0.0) : get_noise_2d(x, y));
float value = (p_in_3d_space ? get_noise_3d(x, y, p_depth) : get_noise_2d(x, y));
ivalue = static_cast<uint8_t>(CLAMP(value * 127.5f + 127.5f, 0.0f, 255.0f));
wd8[i] = p_invert ? (255 - ivalue) : ivalue;
}
Expand All @@ -124,6 +124,6 @@ void Noise::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_noise_3dv", "v"), &Noise::get_noise_3dv);

// Textures.
ClassDB::bind_method(D_METHOD("get_image", "width", "height", "invert", "in_3d_space", "normalize"), &Noise::get_image, DEFVAL(false), DEFVAL(false), DEFVAL(true));
ClassDB::bind_method(D_METHOD("get_seamless_image", "width", "height", "invert", "in_3d_space", "skirt", "normalize"), &Noise::get_seamless_image, DEFVAL(false), DEFVAL(false), DEFVAL(0.1), DEFVAL(true));
ClassDB::bind_method(D_METHOD("get_image", "width", "height", "depth", "invert", "in_3d_space", "normalize"), &Noise::get_image, DEFVAL(false), DEFVAL(false), DEFVAL(true));
ClassDB::bind_method(D_METHOD("get_seamless_image", "width", "height", "depth", "invert", "in_3d_space", "skirt", "normalize"), &Noise::get_seamless_image, DEFVAL(false), DEFVAL(false), DEFVAL(0.1), DEFVAL(true));
}
4 changes: 2 additions & 2 deletions modules/noise/noise.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,8 @@ class Noise : public Resource {
virtual real_t get_noise_3dv(Vector3 p_v) const = 0;
virtual real_t get_noise_3d(real_t p_x, real_t p_y, real_t p_z) const = 0;

virtual Ref<Image> get_image(int p_width, int p_height, bool p_invert = false, bool p_in_3d_space = false, bool p_normalize = true) const;
virtual Ref<Image> get_seamless_image(int p_width, int p_height, bool p_invert = false, bool p_in_3d_space = false, real_t p_blend_skirt = 0.1, bool p_normalize = true) const;
virtual Ref<Image> get_image(int p_width, int p_height, int p_depth, bool p_invert = false, bool p_in_3d_space = false, bool p_normalize = true) const;
virtual Ref<Image> get_seamless_image(int p_width, int p_height, int p_depth, bool p_invert = false, bool p_in_3d_space = false, real_t p_blend_skirt = 0.1, bool p_normalize = true) const;
};

#endif // NOISE_H
4 changes: 2 additions & 2 deletions modules/noise/noise_texture_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,9 @@ Ref<Image> NoiseTexture2D::_generate_texture() {
Ref<Image> new_image;

if (seamless) {
new_image = ref_noise->get_seamless_image(size.x, size.y, invert, in_3d_space, seamless_blend_skirt, normalize);
new_image = ref_noise->get_seamless_image(size.x, size.y, 0, invert, in_3d_space, seamless_blend_skirt, normalize);
} else {
new_image = ref_noise->get_image(size.x, size.y, invert, in_3d_space, normalize);
new_image = ref_noise->get_image(size.x, size.y, 0, invert, in_3d_space, normalize);
}
if (color_ramp.is_valid()) {
new_image = _modulate_with_gradient(new_image, color_ramp);
Expand Down
Loading

0 comments on commit fb3d3bf

Please sign in to comment.