godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
89.37k stars 20.24k forks source link

Simplex Noise functions (2D, 3D, and 4D) #1268

Closed bdero closed 6 years ago

bdero commented 9 years ago

Simplex Noise (also known as improved Perlin Noise) has many uses in modern game development, as it lies at the heart of procedural generation. Infinite terrain, voxel worlds, clouds, and just about any texture with realistic, natural patterns can be generated using Simplex Noise. It's commonplace in modern game engines.

Simple examples of simplex noise use:

Fortunately, it's also pretty easy to implement.

The ideal implementation would involve allowing the user to set the RNG's seed somehow (whether it's set using a separate function in advance or passed as a parameter to the noise functions), and exposing the noise functions in "@GDScript", which might look something like this:

float simplex2d(x, y)
float simplex3d(x, y, z)
bil-bas commented 9 years ago

You would want 4d noise too, so you can get noise in 3d + time. That said, it makes considerably more sense to find and use existing glsl code yourself in shaders rather than use in gdscript (where it would be running in c++ underneath). The parallelism of the video card would make the calculations manythousands of times faster to be real time.

bdero commented 9 years ago

@Spooner Great point with the 4d noise and using shaders whenever possible. Rethinking this, I can't really come up with any real use case where it would be favourable to use simplex noise in CPU time over GPU. It might still be favourable for light one-off things, but even for stuff like voxel engines, generating initial block placement would probably best be done with fragment shaders..

zauberparacelsus commented 9 years ago

I'd like to also suggest the addition of Voronoi/Worley noise and Musgrave noise. Both are useful for procedural generation, especially when used in combination with one another.

zauberparacelsus commented 9 years ago

Okay, apparently simplex noise is covered by a patent for implementations using three or more dimensions. There is, however, an alternative implementation called OpenSimplex that skirts the patent issues, though afaik it is only implemented in Java.

zauberparacelsus commented 9 years ago

Found an implementation of opensimplex written in C: https://github.com/smcameron/open-simplex-noise-in-c

est31 commented 8 years ago

The problem with simplex noise is that its patent protected. One would have to chose an implementation that avoids to be covered by the patent's claims.

zauberparacelsus commented 8 years ago

@est31 Which is why I suggested OpenSimplex, which (despite the name) is NOT based off of the patented implementation of Simplex.

nunodonato commented 8 years ago

Coming from 2d game dev, I've used noise functions extensively in my games, and never in shaders. So I would have to vote to keep it out of the shader-related stuff :)

est31 commented 8 years ago

Until its supported natively by godot, there is a 2D/3D simplex implementation in gdscript: https://github.com/OvermindDL1/Godot-Helpers/blob/master/Simplex/Simplex.gd

razcore-rad commented 8 years ago

Someone wrote a C version of simplex noise. I think will be of much help with implementing it in the core game engine. https://github.com/smcameron/open-simplex-noise-in-c. If I get time I'll try to make a module for it meanwhile (if no one else beats me to it :d)

zauberparacelsus commented 8 years ago

@razvanc-r It is worth noting that it is Open Simplex, not Simplex. The implementation is different than that of Simplex, and (importantly) is not encumbered by patents.

sergicollado commented 8 years ago

It would be nice to have noise functionality in godot :+1:

Zylann commented 8 years ago

I'm playing with terrain generation and noise functions would be very useful to speed up GDScript implementations. I tried with shaders but in Godot it feels too limited yet and I don't know if it can multi-thread well (maybe with Vulkan compute shaders in the future?).

I also found this library, FastNoise, which is MIT-licensed: https://github.com/Auburns/FastNoise. It's very small and suited for real-time, so it could be integrated easily I think :)

I would also point out that not only a noise3d(x,y,z) is good to have, but also noise3d(x,y,z, grid) so we can ask C++ to generate a whole grid of values at once, in various formats (floats, bytes, flags...). Then I think noise should not be just functions, but objects, so we can set their seed, offsets, storage format, parameters, add, multiply, compose them etc. without the need to iterate all values one by one in GDScript.

Side note: composing arrays of 1D, 2D, 3D numbers could be implemented outside the scope of noise generation. It sounds like something a GPU does with textures already, but would still be of use on multi-thread CPUs for non-graphic number crunching, if the GPU is already used a lot of lacks features.

Zylann commented 8 years ago

I've just got FastNoise to work in Godot as a module. World generation is blazing fast now :)

# A glimpse of the usage
var noise = Noise.new()
noise.set_seed(666)
noise.set_frequency(32)
noise.set_octaves(3)
...
var h = noise.get_noise_3d(x, y, t)

But I read about the patent issues with Simplex noise so I also started to integrate OpenSimplex, following the same kind of GDScript interface.

A notable difference is that by design, OpenSimplex allocates memory for permutations per noise instance, which FastNoise doesn't. It shouldn't be a serious issue because it's uncommon to have many instances of noise generators, but might be worth mentionning.

Zylann commented 8 years ago

I finished an OpenSimplex Godot integration :) https://github.com/Zylann/godot_opensimplex

bdero commented 8 years ago

Thank you for your work @Zylann , I took a look and it looks like a great implementation. The native inclusion of the fractal noise class seems epecially good, since it covers probably the most common use pattern. If the whole repository is MIT licensed, you may want to consider moving the LICENSE file up to the root of the repo and including the license or a link to the license at the bottom of the readme.

Edit: Oops, I just realized the license in the lib directory is not MIT. Either way, whatever license the rest of the code is, it might be a good idea to place it in the readme.

Zylann commented 8 years ago

The license of the OpenSimplex C library is public domain. I added a LICENSE file for the rest of the code :)

sergicollado commented 8 years ago

Oh!!! I can't wait to check your wrapper, thanks Zylann!!

Zylann commented 8 years ago

Just in case, here is my FastNoise integration I was talking about earlier: https://github.com/Zylann/godot_fastnoise It has more features and usage is a bit simpler, but it has the Simplex noise patent issue.

Zylann commented 8 years ago

Apparently the patent on Simplex noise (referred as Perlin Noise) covers its use for image generation: "A method for generating images" So using it for terrain generation should be fine, isn't it? Or can the resulting terrain be considered an "image" when drawn on the screen?

est31 commented 8 years ago

I am no lawyer, but isn't the terrain displayed on the screen via images (aka "frames")?

So its probably fine if you don't display the generated terrain on an image.

razcore-rad commented 8 years ago

Why isn't this bundled with the engine already? :)

vnen commented 8 years ago

Why isn't this bundled with the engine already? :)

Because nobody sent any PR...

reduz commented 8 years ago

Lets wait until we can supply binary modules for 3.0, then we bundle this On Jun 24, 2016 14:47, "George Marques" notifications@github.com wrote:

Why isn't this bundled with the engine already? :)

Because nobody sent any PR...

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/godotengine/godot/issues/1268#issuecomment-228413384, or mute the thread https://github.com/notifications/unsubscribe/AF-Z24NfsQYJdm8guxDIBVsavj-N29Ttks5qPBhHgaJpZM4DUCsT .

razcore-rad commented 8 years ago

Oh, didn't know there's plan to add binary modules. That would be great cause to recompile it every time... well, that's why I don't use these modules now :). Probably not only me either.

hyperglow commented 8 years ago

Hey guys,

Do you think the noise module implementation is usable to generate animated 4d textures?

Would ne awesome...

Zylann commented 8 years ago

My two modules (OpenSimplex and FastNoise for Godot) both provide a 4d simplex noise generator so you can at most animate a 3D texture (the 4th dimension being time).

hyperglow commented 8 years ago

The way would be call the function for every pixel and fill a pixel buffer set it as texture? Is gd script fast enough for this?

Zylann commented 8 years ago

If you need to do it only once or bake the animated images, GDScript can do the job with a native module (or even a pure script implementation, which will be much slower: https://github.com/OvermindDL1/Godot-Helpers/blob/master/Simplex/Simplex.gd). If you need to do that every frame... you have to forget about native modules, and do that with a shader. However I'm not sure if the current Godot shader language has enough features to make it simple :') (also, note that the patent on Simplex noise targets this usage).

Megalomaniak commented 8 years ago

All we really need is to be able to do iteration in shaders/shadergraphs and we will be able to implement our own cell/noises in shaders, I mean besides just the basic hash noise which is possible already now.

bdero commented 8 years ago

I made a comment much earlier (around the time when I made this issue) about how I couldn't think of non image/hightmap-related use cases for simplex noise, but really there are many. For instance, if you want to make your camera shake a certain way using simplex noise, or you want to simulate the smooth random direction change of an insect as it's moving.

razcore-rad commented 8 years ago

This isn't just about shaders, simplex noise (as other types of random functions) can be used for an infinite other purposes, not just visuals. Coherent noise can be done with http://libnoise.sourceforge.net/ for example (which is just another name for something like simplex noise, but doesn't come attached with patent issues etc.)

Megalomaniak commented 8 years ago

Yeah I've been eyeing that libnoise myself, and I do agree that noise is useful in more way's than just the one. :)

However my point still stands, as far as shaders are concerned all we need is to be able to do iteration in shaders to generate our own noise, and I'm inclined to say that noise can already be generated in GDScript. This in no way is meant to say that we couldn't make good use of something like libnoise implementation, though(it would be fantastic, alas no MIT License there - it's LGPL).

Zylann commented 8 years ago

Personally, for some game projects I often need more than shaders (in which I actually sample textures, which is faster), and when I do for other purposes it's usually a huge CPU bottleneck when done in GDScript. My requirements are usually the ability to setup seeds and query any point in 1, 2, 3 or 4D infinite seamless space, with preferably as less memory allocations as possible. I was pretty amazed by FastNoise for this, as it allocates zero memory, is lightweight, provides a few different noises which are not limited in space and generation is very fast. On the other hand I keep hearing about libnoise but I wonder if it can fulfill the same requirements in game development?

Megalomaniak commented 8 years ago

Oh, yeah, fastnoise is a compatible license so a definite +1 to that. :)

Zylann commented 7 years ago

@reduz OpenSimplexNoise would be a DLScript? I have no problem with that, if it were about libnoise or complete frameworks... But how about having the basics in core? It covers lots of use cases by itself. If more complex stuff is needed on more advanced projects, then custom modules or DLScript are better suited for it due to the size it adds.

Or when you said "bundle", did you mean Godot will be bundled with some modules that will be supported in official export templates rather than being 3rd party?

Also, the fact OpenSimplexNoise would be a DLScript implies that C++ code making use of it without overhead would also have to be a DLScript...

willnationsdev commented 6 years ago

@Zylann are we thinking your noise module would be integrated for the 3.1 release, or is this something that would have to be a GDNative submodule for some reason (would prefer a module implementation)?

Zylann commented 6 years ago

Given how widespread the usage is, a module would be great. I made an OpenSimplex implementation as a module, feel free to check it out

willnationsdev commented 6 years ago

I thought you used FastNoise too though? @Zylann

Zylann commented 6 years ago

Would be fine too (might even be better) if you don't mind patents

willnationsdev commented 6 years ago

@Zylann How would patents get involved? FastNoise is MIT-licensed, so there shouldn't be any issue in integrating a Noise Reference-type into Godot (I would think).

Zylann commented 6 years ago

It's not about the implementation license, but the patent on the method itself. I think it was mentionned earlier in this thread

willnationsdev commented 6 years ago

@Zylann Ohhhh, I get it now. So you were wanting to substitute the portions of FastNoise that would infringe on the patent for 2D content with Open Simplex implementations? Or are we just doing Open Simplex all the way?

Zylann commented 6 years ago

Put shortly, I prefer FastNoise because it is faster, lighter in memory and has more features. But due to patents I also ported an OpenSimplex module, which is slower, has less features and allocates more memory. I didn't write the libs, and I didn't work on mixing them because I use my free time for other things at the moment :p

Zylann commented 6 years ago

So due to that, I proposed OpenSimplex all the way despite my preference, but feem free to tweak the module.

Chaosus commented 6 years ago

I suppose this patent is active only in empire of evil(USA) :) Because in Russia and Europe patents for program methods are not exist. I wonder if someone decided to push game with patented FastNoise algo to Steam the problems could happens ? However its not easy provably...

vnen commented 6 years ago

However its not easy provably...

This is not the right way to think. And probably false, if they know the game is made in Godot, which has the source available, it's easy to connect the dots.

Patent for software and algorithms does not exist AFAIK, but this case falls into a sort of grey area, since it's described as an "apparatus" which includes a computer and a display. Nevertheless, I'm not a lawyer and don't know all the implications of it, therefore I would be on the safe side. If someone with proper knowledge of the USA law explain why this would be okay, then fine, otherwise I prefer the status quo.

In any case, the patent only covers image generation. The problem is if some user unknowingly uses it to create images in the game, which could cause them trouble and such trouble likely would fall into Godot's lap since they were just using the engine.

Chaosus commented 6 years ago

Ah, then having it as separate library is the only option. Pushing slow unpatented version to Godot does not firstly seems like a good idea, but if someone would prefer to use faster version instead slower for image generation, this fact will be hidden(if not open source) by slow version and hardly proven(I guess Godot binary is not easy for decompile). Am I on the right way to think ? :)

willnationsdev commented 6 years ago

Well, I'm trying to create a unified implementation that uses FastNoise in most cases, but suddenly switches over to OpenSimplex any time you want to do a 2D simplex noise operation.

Zylann commented 6 years ago

@Chaosus technically, OpenSimplex should still be faster than PerlinNoise, only slower than Simplex.