Друг только что связал меня с этим вопросом, и я подумал, что попытаюсь прояснить пару вещей, которые не учтены в принятом ответе.
Интересная и полезная статья Элиаса использует «значение шума», а не «шум Перлина». Значение шума включает в себя подгонку кривой случайных точек. Градиентный шум (основным примером которого является шум Перлина) создает решетку из точек с 0 значениями и дает каждому случайный градиент. Их часто путают друг с другом!
http://en.wikipedia.org/wiki/Gradient_noise
Во-вторых, использование 3-го значения в качестве семени дорого. Если вы хотите случайный рельеф, вместо этого рассмотрите перевод случайного количества вашего происхождения. 3D-звонки будут стоить дороже, чем 2D-звонки. И все, что вы делаете, это используете значение z, чтобы выбрать определенный фрагмент 2D-шума.
В-третьих, прямой вызов функции будет возвращать значения, которые являются достаточно плавными и в целом скользящими, а не такими грубыми, как реальная местность, поскольку ее случайность ограничена одной частотой. Чтобы получить более сложный рельеф, хорошей техникой является суммирование нескольких вызовов, проходящих через шумовое пространство на разных частотах, обычно устанавливающих «фрактальные» значения.
Таким образом, например, сумма вместе noise(x, y) + (1/2)(noise(x*2, y*2) + (1/4)(noise(x*4, y*4)
...
Полученная сумма, вероятно, будет часто выходить за пределы диапазона от -1 до 1, поэтому вам придется нормализовать результат, прежде чем значения будут полезны. Я хотел бы предложить установить ряд факторов (1, 1/2, 1/4 и т. Д.), Чтобы вы гарантированно оставались в пределах [-1, 1], что может быть достигнуто путем прогрессивного взвешивания в зависимости от того, сколько «октавы» вы используете. (Но я не знаю, действительно ли это самый эффективный способ сделать это.)
Пример с четырьмя октавами: (1/15)(noise(x, y) + (2/15)(noise(2x, 2y) + (4/15)(noise(4x, 4y) + (8/15)(noise(8x, 8y)
Затем используйте нормализацию "турбулентного шума", взяв сумму и сделав ее = |sum|
(т. е. используя функцию abs). Это даст рельефу местности определенные угловые гребни долины, а не плавные движения.
Я работаю над визуализатором SimplexNoise, надеюсь со временем открыть его на GitHub, как проект Java. Первый черновик визуализатора можно найти и запустить через этот пост на java-gaming.org:
http://www.java -gaming.org / темы / симплекс-шумовые эксперименты с целью достижения-процессуального поколения / 27163 / view.html
Акцент на первом проекте более учебный, с примерами сгенерированного кода (но они на Java).
Отличная статья о том, как работает SimplexNoise (и Perlin vs Gradient background):
http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf
Стефан Густавсон проделал отличную работу!