0 votes

I am planing on making a little procedural generated 3d game in Godot 3.0 when it releases. My problem is that there is no noise function, and implementing it isn't gonna work for me, because:

  1. The function really confuses me.
  2. I don't think that a huge function wich I need to call a lot wich is scripted in gdscript would be very good.

So is there any chance a default noise function will get implemented in 3.0? And if not how have other people done it.
Also I don't wan't to completly recompile the engine, so editing the source isn't an option. Thanks for your help!

asked Aug 4 in Engine by GR00G0 (25 points)

You can probably do this by binding a noise library (such as OpenSimplex or FastNoise) as a GDNative library, which doesn't require to recompile the engine in 3.0.

Alternatively, you could write a shader to generate a texture that you can then download from the GPU to GDScript to make up your map, which will be even faster than a C++ generator, but also trickier^^

Thank you for your help. I just found a really good tutorial how simplex noise works. I heard about gdnative, but i am not sure what it does. What language is gdnative in and can i create a function like noise(x,y,z,w) and it can be used efficiently and without too much resources in any other gdscript? Thank you for your answer.

GDNative is a C interface for Godot, so that you can write native libraries (.dll/.so/etc) that Godot will be able to load as if they were scripts.
As such, it gives you access to the same script API, but allowing any language that can bridge to C. There are C++ bindings, but people also work on D, Rust, even Python bindings.
It requires a minimum of knowledge of C/C++ programming though, since it is lower-level than GDScript and the primary language is C. And obviously, it is also a lot faster if you do a C/C++ library.
The doc is a bit sparse at the moment, I gave it a try a few months ago but it has changed and improved since. Devs are working actively on it, and you can get help by asking them on the Discord community or IRC.

Ok that sounds good! But just in case I would be to stupid to use it with gdnative, would a funcion like the 4d noise described here: Noise work good in gdscript?

There is a simplex noise implementation in GDScript: https://github.com/OvermindDL1/Godot-Helpers/blob/master/Simplex/Simplex.gd
It doesn't have 4d noise though. OpenSimplex and FastNoise have it but they need to be bound with GDNative or a module. You can also find another way, or implement it yourself.

3 Answers

+1 vote
Best answer

Hello,

Still needing noise function?

I have found some modules on this blog:

The blog

You need to compile them with the master branch but you don't need to write it yourself as you don't want to. I have the module OpenSimplex in my godot and it works very good. Thanks to Zylann.

I know you already have an answer but a compiled module should work faster than one in gdscript.

answered Aug 22 by Cyanux (58 points)
selected Sep 9 by GR00G0
+1 vote

I'm using a diamond-square algorithm for my random generated maps. You may want to read this:
Diamond-square algorithm

This is my implementation in GDScript. I'm using a custom class (miarr) to store the result, you should modify it to use an array.

_width = pow(2, map_factor) + 1
_height = _width

var passes = 0
var r = rand_range(0, 60)
var dir = -1 if randf() < 0.5 else 1
while(passes<4):
    var step_size = (_width - 1)
    while(step_size > 1):
        var x = 0
        while(x < _width - 1):
            var y = 0
            while(y < _height - 1):
                diamond_step(x, y, step_size, r * dir)
                square_step(x, y, step_size, r * dir)
                y += step_size
            x += step_size
        step_size /= 2
        r -= 4
        r = clamp(r,0,60)
    passes += 1

Diamond

func diamond_step(x, y, step_size, r):
var avg = (_mi_arr.get_value(x,y) + 
           _mi_arr.get_value(x,y + step_size) + 
           _mi_arr.get_value(x + step_size, y + step_size) + 
           _mi_arr.get_value(x + step_size, y)) / 4
_mi_arr.set_value(x + step_size/2, y + step_size/2, avg + r)

Square

func square_step(x, y, step_size, r):
var avg = (_mi_arr.get_value(x,y) + _mi_arr.get_value(x+ step_size,y))/2
_mi_arr.set_value(x + step_size/2, y, avg + r) #up
avg = (_mi_arr.get_value(x,y + step_size) + _mi_arr.get_value(x + step_size,y+ step_size))/2
_mi_arr.set_value(x + step_size/2, y + step_size, avg + r) #down
avg = (_mi_arr.get_value(x,y) + _mi_arr.get_value(x,y+ step_size))/2
_mi_arr.set_value(x, y + step_size/2, avg + r) #left
avg = (_mi_arr.get_value(x + step_size,y) + _mi_arr.get_value(x + step_size,y + step_size))/2
_mi_arr.set_value(x + step_size, y + step_size/2, avg + r) #right
answered Aug 4 by davidoc (118 points)

That looks great, but the diamond square algorithm isn't made for procedural generation.

Well... it actually does. It can generate random maps. You might have a different definition of procedural generation^^

+1 vote

if I'm still behind, I did this before long:

https://github.com/PerduGames/SoftNoise-GDScript-

I found this recently too:

https://github.com/curly-brace/Godot-3.0-Noise-Shaders

answered Sep 14 by PerduGames (139 points)
edited Sep 14 by PerduGames
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.