Understanding Perlin Noise (2014)
flafla2.github.io
flafla2.github.io
[1] https://gist.github.com/KdotJPG/b1270127455a94ac5d19
[2] http://staffwww.itn.liu.se/~stegu/simplexnoise/Noise.lua
The Lua library for simplex does some FFI trickery and avoids crossing Lua/C++ barrier. Mike Pall is credited in comments, so I guess I'm not surprised it's faster.
> in 2001 he was granted a patent for the use of 3D+ implementations of simplex noise for texture synthesis.
OpenSimplex is a variant of simplex noise developed specifically to work around that patent.
There would be not much practical use for it I think, but in theory it should be possible to "compress" a Minecraft world by figuring out the delta between the original generated state and the current state, and then for each chunk either saving the delta or the the full chunk, whatever is smaller.
- 2D Perlin Noise gives rather significant artifacts. If you look at the examples provided in the article you’ll notice that many of the edges in the examples are along the x and y direction. I use (open) simplex noise to avoid those. (When you are doing terrain generation those artifacts become easily noticeable)
- Gradient noises can be used to control more than just the intensity of something! I have used them to control the orientation of mountain ranges for example. Basically, you can use them to control anything that needs to be smooth and continuous over space.
The first thing I did when I got an rPi with a sensehat (which includes an 8x8 rgb display) was to make a plasma type display by generating 3 perlin noise maps and crossfading to a new set slowly every second or so.
I still have it running on my desk to this day and get constant comments. People seem to find it endlessly fascinating
Can anyone explain?
Tried going to the background pages linked, but links are broken.
1) It's approximately band-limited. In other words, it goes up and down in a somewhat random looking way that is neither too fast nor to slow. If you evaluate two points close by, they'll have approximately the same value. If you evaluate two points far away they'll have completely unrelated values. This is so because the way it is constructed, every "hill" is paired with a "valley" nearby and vice-versa. Those hills and valleys are of a fairly uniform size and in each pair are a consistent distance from each other. This helps to give it a fairly even appearance and means that we can use it as a building block for other patterns; we can do spectral synthesis (e.g.: [2]) and sum together multiple instances of Perlin noise at different scales and amplitudes to produce a particular look. (Though Gabor noise [3], is even better at this.)
2) It's deterministic. So long as your permutation tables and gradient tables are the same from run to run (either hard-coded into your program or generated from the same RNG seeding), the values that you get out of Perlin noise at a given point will stay the same across different runs of your program. This is nice for things like Minecraft where you can put in the same seed and be dropped into the same world. For movies, we can use it to make pattern on a surface, add detail to a volume, or make things move in interesting swirls [4] and know that they'll stay consistent from frame-to-frame rather than jumping to a completely different pattern.
3) It's random access. You can evaluate any point, anywhere, at any time without having to say, pre-compute a patch and filter it somehow. (Classic Perlin noise uses just a couple of tiny lookup tables initialized at the program start and even these can be traded for pure computation [5].) This makes it ammenable to parallelization.
4) It easily generalizes to arbitrary dimensions. Typical implementations provide functions for evaluating it on a 1D, 2D, 3D, and 4D domains. So if you need a 3D point that varies with time you can use the 4D version. Classic Perlin noise gets exponentially more expensive with higher dimensions, but the closely related Simplex noise [6] scales linearly. There are also vector-valued versions where the range is multidimensional; instead of just getting a scalar value out you can get a vector.
Hope that helps. Let me know if anything is unclear or you have further questions.
----
[1] http://www.eastfarthing.com/blog/2015-04-21-noise/
[2] http://paulbourke.net/fractals/noise/
[3] http://graphics.cs.kuleuven.be/publications/LLDD09PNSGC/
[4] https://www.cs.ubc.ca/~rbridson/docs/bridson-siggraph2007-cu...
[5] https://www.csee.umbc.edu/~olano/papers/GPUTEA.pdf
[6] https://www.csee.umbc.edu/~olano/s2002c36/ch02.pdf#page=18