Процедурная генерация местности с блоками
Я использую three.js для создания процедурно созданного ландшафта с использованием Perlin Noise.
Я создаю ландшафт, используя серию блоков, но их высота вдоль границ не соответствует друг другу, как вы можете видеть ниже.
Как мне подходить к сопоставлению карт высот между блоками?
Я использую алгоритм шума Perlin для генерации высоты; проблема в том, что высота каждой точки не зависит от высоты ближайших точек. У меня есть другой алгоритм шума, но у меня та же проблема..
1 ответ
Здесь есть действительно хорошее видео о бесконечной местности: https://www.youtube.com/watch?v=IKB1hWWedMk
Он находится в обработке, но ту же концепцию можно применить к любой используемой вами библиотеке шума - я собираюсь предположить, что вы используете шум Перлина. В этом случае вам нужно посмотреть значения, которые вы передаете в эту функцию, и изменить их в зависимости от размера ваших блоков.
Например, представьте сетку блоков 3х3. Если ваш средний блок (x, y), и каждый блок имеет размер 10x10 единиц, если вы двигаетесь "на север" (из-за отсутствия лучшего термина), вам нужно получить (x, y - 10) от ваша функция шума.
Видео объясняет это лучше, чем я, но, надеюсь, это помогло. Без дополнительных знаний о функции, которую вы используете, я не могу дать более подробный ответ.
Этот ответ объяснит, как решить эту проблему для одной оси x. Затем сделать то же самое для оси y (z в three.js) несложно.
Первый шаг - убедиться, что шум Перлина использует одно и то же случайное начальное число для каждого блока. Это гарантирует, что блоки используют одну и ту же карту шума Perlin и поэтому могут плавно переходить между ними.
Вторая часть - это отображение между вашими блочными единицами и тем, что передается в функцию шума Перлина. Например, ваш блок x может быть от -512 до 512 единиц, поэтому вы получите значение высоты для каждой вершины x, передав от -0, 5 до 0, 5 для каждой вершины x в функцию шума. НапримерvertextHeight = perlin(vertexX / 1024, vertextY / 1024)
Затем ваш второй блок будет смещен, чтобы его край соприкасался с первым блоком. Например, его позиция по x будет на +1024 больше, чем у первого блока, и поэтому будет изменяться от 512 до 1536. Таким образом, в этом смысле у block0 будет смещение по x, равное 0, а у блока1 будет смещение по x, равное 1024. 1024 является значением ширина / размер блока в единицах three.js.
Наконец, вам нужно задать такие же смещения для функции шума, но с масштабированием на основе сопоставления, описанного выше. В этом примере 512 станет 0, 5, а 1536 станет 1, 5, что выглядит следующим образом:
size = 1024;
vertextHeight = perlin((vertexX + offsetX) / size, (vertextY + offsetY) / size)`
Следовательно, значение x, присвоенное функции шума на границе между блоком 0 и блоком 1, будет одинаковым, и поэтому будет возвращено такое же значение высоты.