4.1.1 stable: noise generation; rectangular dimension issues
-
Hey all,
Thanks for taking a look!
In summary: I'm trying to roughly reproduce and eventually extend some functionality that Godot already provides via the noise library found below, but from within a Godot editor plugin and using GDscript.Godot's Noise class that I'm using for design reference:
https://github.com/godotengine/godot/blob/f2ba8ec6ca2e4ff493cba11f95621d10ab8bb363/modules/noise/noise.cppHere's a cleaned up and stripped down reproduction of my project with the issue and tool setup as I'm using it:
https://github.com/TC93DEV/noisytool_brokenIf you import the repo as a Godot project you'll see in the main editor window a new tab called "NoisyTool". This window is provided by the noisy_scene.tscn and all the logic is contained in the script noisy_cfg.gd attached to the CFG node in the scene. If the "NoisyTool" tab doesn't show maybe just check that the plugin is enabled in Project Settings -> Plugin, though, I've exported it enabled in the project so I expect it will be.
It works and as far as I can tell it works well when the given dimensions for width and height are equal - when I'm producing a square image.
Problems arise if I double the width and try to produce a rectangular noise map. The produced image is instead a stitched together copy of the one image occupying double the space. If you quadruple width verse height, you get four images stitched together, and so and so forth. Instead I'm trying to replicate contiguous noise values produced by the noise.cpp::get_image method; one big contiguous chunk regardless of the height/width.
I am pretty sure I'm screwing up in either accessing the 2D array or populating the PackedByteArray for the Image.create_from_data() function.
I'm confident that the issue does not lie in any part of the rendering process be that viewport/scene setup or shader - you can save a png of the image produced by the Image.create() function before we ever make it to the viewport, texture conversion or shader and the duplication is already present. Substituting an image using the noise.cpp::get_image function on the very same FastNoiseLite object and handing it to the same shader gives the expected good result with no duplication using rectangular dimensions.
I'm not going for a line for line conversion of the Godot Noise class to GDscript and I know there are handy functions in Noise class to abstract away this stuff but I'm interested to learn, and so that I can extend parts of the generation process from the comfort of the Godot editor and GDscript, maybe build a fancy compute shader pipeline later and so on.
I've tried a fair bit of troubleshooting; different ways of populating and accessing the 2D noise values like a flattened 2D->1D array using row first indexing (x + y * y), an actual 2D array, a single index value incrementing and so on. Printing the raw values checking for duplication - I can't see any. All manner of inspection of the raw values when crossing the middle boundary of the w*d for any irregularity and I'm just not spotting what I've cooked.
Any advice anyone might have would be greatly appreciated.
-
Solved this one after enough coffee and cigarettes. It ended up being daft. The offending function:
func buffer_from_2d_array(array_2d: Array ) -> PackedByteArray: var img_buffer: PackedByteArray = [] img_buffer.resize(width * height) var idx: int = 0 for x in range(width): for y in range(height): img_buffer[idx] = array_2d[x][y] * 255 # *255 to make the values sensible for the image idx += 1 return img_buffer
Which now, correctly, does not iterate for size of the image in either axis but the actual count of elements that the byte array building the image depends upon:
func buffer_from_2d_array(array_2d: Array, size: Vector2i) -> PackedByteArray: var img_buffer: PackedByteArray = [] img_buffer.resize(size.x * size.y) var idx: int = 0 for cell in array_2d: for value in cell: img_buffer[idx] = value * 255 # *255 to make the values sensible for the image idx += 1 return img_buffer
@TC93DEV said in 4.1.1 stable: noise generation; rectangular dimension issues:
I am pretty sure I'm screwing up in either accessing the 2D array or populating the PackedByteArray for the Image.create_from_data() function.
/aggressivenodding
-