Perlin noise implementation is not Perlin noise (but value noise) #15775
Labels
@ Documentation
Improvements or additions to documentation
@ Mapgen
Unconfirmed bug
Bug report that has not been confirmed to exist/be reproducible
Luanti version
Operating system and version
Debian
CPU model
No response
GPU model
No response
Active renderer
No response
Summary
The current implementation is a "fractal" and "eased" variant of what is called value noise:
luanti/src/noise.cpp
Lines 169 to 176 in dd0070a
luanti/src/noise.cpp
Lines 212 to 214 in dd0070a
luanti/src/noise.h
Lines 236 to 239 in dd0070a
luanti/src/noise.cpp
Lines 281 to 294 in dd0070a
gradientMap2D
However, one key ingredient for "true" Perlin noise is missing: in Perlin noise, each corner is also randomly assigned a gradient. This makes the grid structure a bit less apparent. Interestingly, the functions are even called
noise2d_gradient
andnoise3d_gradient
, but do not actually compute gradients but perform interpolation, nor doesgradientMap2D
. There is also adotProduct
function, but it is not used.Why this matters:
Value noise has even more visible grid structures than Perlin noise, because it always has its minima and maxima at grid points. In Perlin noise, because of the gradients, "blobs" can be in-between of grid points (there is nevertheless a bias towards axis-aligned ridges, unfortunately; a simple improvement is to use a non-aligned grid during generation). Nevertheless, Perlin noise has somewhat a grid pattern to it.
Confer:
Steps to reproduce
Reduce the number of octaves to see the behavior of the mapgens without stacking.
E.g.,
(notice
octaves=1
andspread
16 for scaling) looks like this:You can tell that here for every point in a 16x16 grid, the y value was chosen randomly, then a non-linear (eased) interpolation was used inbetween.
This is the typical pattern of 1 octave eased interpolation value noise (own code):
![Image](https://private-user-images.githubusercontent.com/3997899/411684144-19f673bf-e0e9-40ee-b54c-a2dc1706269e.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzkzODM5NDgsIm5iZiI6MTczOTM4MzY0OCwicGF0aCI6Ii8zOTk3ODk5LzQxMTY4NDE0NC0xOWY2NzNiZi1lMGU5LTQwZWUtYjU0Yy1hMmRjMTcwNjI2OWUucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI1MDIxMiUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNTAyMTJUMTgwNzI4WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9YjAxZTBjOGY0MGY4ZjFlMTdiMzY5MzgxODU4MGI2MTcwMzhmZmZmMjc5MDMwYmZmYmUwOGIwMWY4NWZmZjhlYyZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QifQ.jztH9mAE1eVwjVk5SCb-MPozX5texVUOokWeELH1bjw)
whereas Perlin noise with one octave looks more like this (using this, the value ranges naturally do not agree, and I don't know how good or bad this implementation is):
![Image](https://private-user-images.githubusercontent.com/3997899/411684387-1fd5074e-b157-48f9-8e5c-7b8833c25b95.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzkzODM5NDgsIm5iZiI6MTczOTM4MzY0OCwicGF0aCI6Ii8zOTk3ODk5LzQxMTY4NDM4Ny0xZmQ1MDc0ZS1iMTU3LTQ4ZjktOGU1Yy03Yjg4MzNjMjViOTUucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI1MDIxMiUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNTAyMTJUMTgwNzI4WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9MjI1NzY4NTNhNjBmNmVkNzE3NjlhZmVjNjgxNWY2ZGYxOGI1Mzk1ZjQ4YzQzNDk1MTE0MmViNDFkNDEzNmVhZiZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QifQ.Hi_UkxdujZav9pMuYBdyPvcBy9HuAspVcV9lRPFvigE)
As you can see, true Perlin noise does look more interesting than value noise.
Possible solutions
Consider simplex noise instead of/in addition to classical Perlin noise #11468
The text was updated successfully, but these errors were encountered: