Простой и быстрый алгоритм генерации ландшафта. Генерация трехмерных ландшафтов

Ландшафтный дизайн на компьютере Орлов Андрей Сергеевич

Глава 15 Генерация ландшафтов

Генерация ландшафтов

На страницах данной книги о ландшафтном дизайне под этим понятием подразумевалось создание и благоустройство территории, озеленение и планирование красивых уголков. В рассматриваемых программах в качестве заднего плана можно было использовать изображения различных ландшафтов, вносимых в базу данных приложения.

В данной главе познакомимся с программами, которые сами генерируют ландшафты. Таких приложений довольно много, остановимся на Terragen и CyberMotion 3D-Designer. Рассмотрим создание ландшафта и сохраним его в виде изображения, что позволит в дальнейшем использовать созданное изображение в качестве заднего плана при работе в программах ландшафтного дизайна. Начнем знакомство с программами – генераторами ландшафтов с приложения Terragen.

Из книги Прикладное программное обеспечение: системы автоматической обработки текстов автора Мальковский Михаил Георгиевич

1.2. Генерация текста С необходимостью генерации хотя бы простейших фраз разработчики практических систем столкнулись еще на заре их создания. Даже в столь примитивно организованной (в плане дружественности пользовательского интерфейса) среде, как DOS, при попытке

Из книги Документация NetAMS автора Автор неизвестен

OID, их автоматическая генерация и перезагрузки При создании конфигурационного файла, и при добавлении юнитов вручную oid можно не указывать. При этом значение oid генерируется автоматически, так что если набрать show config, значения oid выставятся каким–то случайным образом.

автора Реймонд Эрик Стивен

Из книги Искусство программирования для Unix автора Реймонд Эрик Стивен

Из книги BPwin и Erwin. CASE-средства для разработки информационных систем автора Маклаков Сергей Владимирович

9.2. Генерация специального кода Операционная система Unix оснащена несколькими мощными генераторами кода специального назначения, предназначенного для таких целей, как создание лексических анализаторов (tokenizers) и синтаксических анализаторов; они рассматриваются в главе

Из книги Инфраструктуры открытых ключей автора Полянская Ольга Юрьевна

15.4.4. Генерация make-файлов Одним из неочевидных преимуществ Unix make по сравнению с базами данных зависимостей, встроенных в многие IDE-среды, является то, что make-файлы представляют собой простые текстовые файлы, т.е. файлы, которые могут создаваться программами.В середине 1980-х

Из книги PGP: Кодирование и шифрование информации с открытым ключом. автора Левин Максим

2.6.1. Генерация словаря ERwin Для управления большими проектами ERwin имеет специальный инструмент - ERwin Dictionary, который обеспечивает коллективную работу над диаграммами и позволяет сохранять и документировать различные версии моделей данных. ERwin Dictionary представляет собой

Из книги Фундаментальные алгоритмы и структуры данных в Delphi автора Бакнелл Джулиан М.

Генерация пар ключей При помощи этого сервиса генерируется пара ключей (открытый ключ/секретный ключ), секретный ключ хранится в файле, защищенном паролем или иными средствами (например, на смарт-карте или при помощи другого аппаратного или программного средства,

Из книги Инфобизнес на полную мощность [Удвоение продаж] автора

Генерация ключа RSA. Для генерации вашей собственной уникальной пары открытый/секретный ключ заданного размера, наберите:pgp -kgPGP покажет вам меню рекомендуемых размеров ключа (простой уровень, коммерческий уровень или военный уровень) и запросит требуемый размер ключа

Из книги Социальные сети [Источники новых клиентов для бизнеса] автора Парабеллум Андрей Алексеевич

Генерация случайных чисел Прежде всего, давайте опишем, что мы понимаем под случайным числом (random number). Без четкого определения термина мы будем неуверенно себя чувствовать при разработке и реализации генератора случайных чисел.Будет ли число 2 случайным числом? Просто

Из книги Разработка ядра Linux автора Лав Роберт

Из книги Описание языка PascalABC.NET автора Коллектив РуБоард

Из книги автора

Генерация контента Как часто нужно писать статьи, выкладывать новые материалы? В среднем, оптимальный вариант – один раз в сутки. У вас на сайте и во всех ваших соцсетях должно постоянно что-то появляться. Хотя мы пишем значительно больше.Видео удобнее выкладывать на YouTube,

Из книги автора

Генерация потенциальных клиентов Остановимся более подробно на том, как с помощью соцсетей проходить каждый из указанных этапов и как грамотно их использовать. Ранее уже говорилось о том, что нужно правильно настроить сайт. Тогда генерация новых клиентов будет идти за

Из книги автора

Генерация заплат Все изменения исходного кода ядра Linux распространяются в виде заплат (patch). Заплаты представляют собой результат вывода утилиты GNU diff(1) в формате, который может подаваться на вход программы patch(1). Наиболее просто сгенерировать заплату можно в случае, когда

Доброго времени суток, Хабровчане! В этой статье я хочу рассказать про простой и быстрый способ генерации ландшафта. Прежде чем мы приступим к разбору самого алгоритма, хотелось бы отметить, что по отношению к генерации ландшафта мною данный алгоритм на просторах сети замечен не был, однако подобный алгоритм для генерации уровней был описан в статье, ссылка на которую будет в конце.

В какой ситуации удобен алгоритм

Недавно столкнулся с задачей: написать простую стратегию с трёхмерным ландшафтом. Так как я в данный момент обладаю маленьким опытом программирования на языке С++, мои попытки написать «diamond-square» закончились ошибками на ровном месте (ссылка на статью по «diamond-square» также будет в конце). Требовался простой в написании алгоритм, не дающий реалистичный ландшафт, так что данный метод поможет в первую очередь новичкам.

Алгоритм и результат

Прежде чем описывать сам алгоритм поделюсь его результатами:


Алгоритм заключается в том, что программа в случайных координатах заполняет карту прямоугольниками случайного размера. Карта имеет вид двухмерного массива, представляющего карту высот нашего ландшафта.

Для простоты создадим структуру прямоугольника:

Struct tRect { int x1, y1, x2, y2; }
Переменные x1 и y1 - левая нижняя координата прямоугольника, x2 и y2 - правая верхняя.

Наша карта представлена в виде массива HM;
- mapsizey и mapsizex - переменные, определяющие размер вашей карты;
- genStep - переменная, отвечающая за количество наших прямоугольников;
- zscale - некий коэффициент растяжения карты в высоту. Можно заменить числом.
- recSizex и recSizey - пределы размеров прямоугольника.

Теперь необходимо заполнить нашу карту прямоугольниками:

For (int i=0; i mapsizey) genRect.y2 = mapsizey; if (genRect.x2 > mapsizex) genRect.x2 = mapsizex; for (int i2 = genRect.x1; i2 Рельеф со скриншота был получен значениями:

genStep = 1024
zscale = 512
mapsizex и mapsizey = 128
recSize = 10

Далее вы выводите карту на экран любым доступным вам способом. В моём случае - openGl+glfw.

Преимущества и недостатки алгоритма

Преимущества:

  • Простота и скорость в написании самого алгоритма
  • Скорость исполнения алгоритма
Недостатки:
  • Примитивность
  • При маленьком шаге заполнения карты ландшафт становится «квадратным»
  • Отсутствует возможность разбивать ландшафт на биомы по ходу генерации карты высот
Данный способ, как уже было сказано выше, подходит в первую очередь для новичков и людей, сильно ограниченных временем.

Надеюсь, данная статья была Вам полезной.

  • Tutorial

Думаю все заметили, что сейчас стало появляться множество всяких бродилок с выживанием в стиле Minecraft . Сделать такую решился и я. Начало было лёгким - Unity3d имеет огромный функционал для сознания простеньких игр (и не только). Персонаж, игровые объекты, в общем основу сделать быстро. Но какой minecraft без рандомно генерируемого мира? Это стало первой трудной задачей. И думаю не только для меня. Просмотрев весь гугл и потратив кучу времени на эту бесполезную вещь я решил написать эту статью дабы сократить страдания других.

План действия

Для начала хорошо бы было разобраться, что подразумевается под генерацией ландшафта:

Итак, поняв общий план действий, надо приступать к делу.

Частые ошибки

С самого начала я думал, что всё будет очень просто и для рандомной генерации ландшафта можно обойтись обычной функцией Random(). Но это самый неправильный способ. Его результат это вовсе не красивая карта, а расчёска в приближении.

Шум Перлина

Существуют множество способов создания карты высот, но почти все они схожи в одном - использование шумов. Самый первый алгоритм, который мне попался это метод с использованием шума Перлина
Perlin noise (Шум Перлина, также иногда Классический шум Перлина) - математический алгоритм по генерированию процедурной текстуры псевдо-случайным методом. Используется в компьютерной графике для увеличения реализма или графической сложности поверхности геометрических объектов. Также может использоваться для генерации эффектов дыма, тумана и т.д.

Думаю многих испугала приставка псевдо, но от неё легко избавиться. Далее представлен способ реализации шума в Unity3d:

Using UnityEngine; using System.Collections; public class PerlinNoisePlane: MonoBehaviour { public float power = 3.0f; public float scale = 1.0f; private Vector2 startPoint = new Vector2(0f, 0f); void Start () { MakeNoise (); } void MakeNoise() { MeshFilter mf = GetComponent(); // Ищем mesh Vector3 vertices = mf.mesh.vertices; // Получаем его вершины for (int i = 0; i < vertices.Length; i++) { float x = startPoint.x + vertices[i].x * scale; // X координата вершины float z = startPoint.y + vertices[i].z * scale; // Z координата вершины vertices[i].y = (Mathf.PerlinNoise (x, z) - 0.5f) * power; // Задаём высоту для точки с вышеуказанными координатами } mf.mesh.vertices = vertices; // Присваиваем вершины mf.mesh.RecalculateBounds(); // Обновляем вершины mf.mesh.RecalculateNormals(); // Обновляем нормали } }
Я бы не сказал, что данный способ даёт ошеломляюще реалистичные результаты, но он довольно неплох для создания пустынь или равнин.

Алгоритм diamond-square

После долгих часов скитаний по интернету наткнулся на этот алгоритм, и он оправдал все мои ожидания. Он даёт прекрасные результаты. Для расчитывания вершин есть очень простая формула.
Представим себе плоскость, её 4 вершины и точку по центру. Её высота будет равна сумме высот 4 вершин, делённая на их кол-во и некого случайного числа с коэффициентом. Вот код для unity3d (халява копи-пастерам):

Using UnityEngine; using System.Collections; public class TerrainGenerator: MonoBehaviour { public float R; // Коэффициент скалистости public int GRAIN=8; // Коэффициент зернистости public bool FLAT = false; // Делать ли равнины public Material material; private int width=2048; private int height=2048; private float WH; private Color32 cols; private Texture2D texture; void Start () { int resolution = width; WH = (float)width+height; // Задаём карту высот Terrain terrain = FindObjectOfType (); float[,] heights = new float; // Создаём карту высот texture = new Texture2D(width, height); cols = new Color32; drawPlasma(width, height); texture.SetPixels32(cols); texture.Apply(); // Используем шейдер (смотри пункт 3 во 2 части) material.SetTexture ("_HeightTex", texture); // Задаём высоту вершинам по карте высот for (int i=0; i 1.0f) { middle = 1.0f; } } divide(x, y, newWidth, newHeight, c1, edge1, middle, edge4); divide(x + newWidth, y, newWidth, newHeight, edge1, c2, edge2, middle); divide(x + newWidth, y + newHeight, newWidth, newHeight, middle, edge2, c3, edge3); divide(x, y + newHeight, newWidth, newHeight, edge4, middle, edge3, c4); } } }

Данная статья зародилась в моей голове, после того, как нам выдали курсач по мультимедийным технологиям в универе. «Универ… пф-ф-ф...» - так подумает мой читатель. Да только иногда здесь бывают дельные вещи. Вот, почему.

В курсаче предполагается создание виртуального ландшафта в старенькой программе VistaPro. В силу того, что раньше я ни с чем подобным не работал, я не могу сказать, насколько она функциональная. Но её большой плюс заключается в том, что она крайне проста в использовании (а другие террагены подчас довольно нетривиальны, что может вызвать некоторые трудности. Час же работы может не гарантировать успеха, в отличие от моего антиквариата), а освоить её от и до: разобрать весь функционал можно меньше чем за день не зная до этого ровным счётом ничего о ней. Небольшим, но всё-таки плюсом является совсем малый вес (~3 МБ). Разумеется, сейчас есть много подобных террагенов, которые обгоняют по функциональности VistaPro.

Здесь можно найти остальные части:

Данная статья претендует на описание сего софта, дабы показать возможности творения и помочь разобраться с программулиной людям, кого данная тема интересует, ибо в сети не очень много информации о VistaPro. Помимо этого интересно, что данная вещь представляет собой архаическую субстанцию 90х годов, которая, может быть использована и сейчас вполне себе неплохо.

Я максимально подробно пишу всё, будто я это делаю для школьника 4-5 лет, ибо сам часто сталкиваюсь с тем, что написано очень заумно, в результате приходится тратить много времени на то, чтобы разобрать: а что же всё-таки написано?.. Конечно, мой читатель может сказать, что слишком большое количество деталей читать бывает слишком скучно и утомительно. Но, пока я остановлюсь именно на таком стиле изложения.

Итак, здесь можно будет найти описание функционала VistaPro, а также иллюстрацию работы большинства опций.

К сожалению, части статьи верстаются в разное время с разными ладшафтами, поэтому ладшафты от разу к разу будут самими разными.

Кроме того, я поэтапно создам мирок или два для демонстрации возможностей программулины.

Посмотреть то, что может VistaPro можно, например, тут, на видосике:

Что же, начнём.

Скачать сей объект можно здеся:

Creation. Генерация карт

Для начала, стартанём экзешник. Откроется окно в стиле Windows 98. Это немного пугает изначально. Но потом привыкаешь.

Для того, чтобы не засорять пока что голову всякой чешуёй вроде работы с камерой и т.п. Погенерим, прежде всего, ландшафт, чтобы перед глазами постоянно мелькали картиночки. Может быть это слегка заинтересует моего читателя, после чего он захочет потыркать кнопочки программки и сам её поисследовать.

Итак, выполняем следующие действия.

Теперь, дорогой читатель, ты умеешь делать небольшой финт ушами для перехода от пирамиды к пирамидам(зачеркнуто), хотя слегка и хаотичным.

Итак, мы научились генерить карту. Для чистоты эксперимента, я открою новый файлик, в котором ничего нет, только чистое поле с пирамидкой. Отседова мы начнём попытки получить что-то ещё.

Все названия кнопочек я буду выделять жирным шрифтом.

Seed value

Под Seed value (Seed value будем везде брать равным 0, либо, в редких случаях другому числу. Чаще всего 1) находится магическая чиселка, которая задаёт некоторое начальное число генерации. Оно появляется случайно при нажатии на Randomize seed . Очевидно, что генерируя ландшафт с одинаковым Seed value , получим одинаковые карты, с разными - разные.

При генерации новой карты, можно действовать двумя методами. Либо нажать Randomize seed , либо активировать поле Seed value и нажать клавишу Enter . В первом случае будет сгенерено новое число Seed value , во втором случае значение не поменяется. Так удобно действовать, когда нужно экспериментировать с ландшафтом для получения одинаковых карт.

Feature Size

Идём далее. Feature size . Данная фитча позволяет сказать, насколько ландшафт будет разреженным. Или по-другому: этим свойством можно задать масштаб. Я возьму разные значения Seed value Например, при Feature size = 1 будет выглядеть так (две следующие картинки созданы для Feature size = 1):



При Feature size = 8 так (две следующие картинки созданы для Feature size = 8):



Разница очевидна. В принципе, некоторыми махинациями можно преобразовать ландшафт из структуры FeatureSize = 1 в структуру FeatureSize = 8. Но об этом позже. Это осуществляется во вкладке Manipulation :

Сравните (FeatureSize = 1 и FeatureSize = 8):





И ещё(FeatureSize = 1 и FeatureSize = 8):



Отрендеренные для тех же значений соответственно:



Set landscape

Рассмотрим Set landscape size . Эта опция задаёт размер мира. Automatic! - это то же самое, что и Small . Не отличается ничем.

Размер мира влиет на максимальное и минимальное значение координат X и Y.

Mega (С пяток секунд сидели, тупили. Здесь, при рендеренге, комп слегка подвис, поэтому рендерить я буду только на Small , за редким исключением):

Кроме того, размер влияет на чёткость структур (чем больше, тем чётче, т.е. масштаб больше), время генерации. Сравните (Feature size = 8) Mega и Small :



На данном этапе мы формируем поверхность. Фактически происходит работа тектонических процессов.

Fractal roughness

Как задавать высоту гор? Для этого рассмотрим параметр Fractal roughness . Для Fractal Roughness == 100 мы уже видели (смотрите выше). Возьмём теперь 0. Ответ напрашивается. Высота гор равна нулю, значит их просто нет. Плоскость:



А при Fractal roughness = 1000 наступает ад. Встречайте Гималаи.



Enlarge section

Enlarge section - выделение определённого участка и интерполяция (Interpolate ) его на всю карту, либо растяжение (Duplicate ) его по всей карте. Выбрать интерполяцию или дублирование можно сразу после того, как будет выбрана область.

Интерполяция подразумевает сглаживание грубых участков карты, а дублирование (или растяжение) это действие не выполняет. Для того, чтобы было понятно, в чём отличие, я поставлю Landscape size == Small . На больших картах, а точнее на карте ландшафта, этого эффекта практически не заметно. Сравните (я взял верхний левый угол):







Тот же участок, только для большой карты:

Smooth

На примере Enlarge section верхнего левого угла с опцией Duplicate , будет отлично видно, как работает сглаживание (Smooth ). После многократного нажатия вот что получим:




Erode

Теперь продемонстрируем ещё одну опцию - эрозия или старение (Erode ). Данный процесс выравнивает ландшафт, делает его однородным. Что это собой представляет? Мы запускаем процесс, после чего на карте чёрным цветом маркируются области с одинаковой высотой. Это происходит итеративно. В зависимости от изначальной ситуации это может происходить быстро (гладкий, изреженный острыми горами ландшафт, т.е. старые горы), либо медленно (ландшафт изрежен острыми горами, т.е. молодые горы). Скорость со временем нарастает: чем старше горы, тем сильнее будут заметны эрозийные процессы. Ландшафт получен после сглаживания (Smooth ) из предыдущего. Кстати, на больших картах эрозия работает тоже крайне долго. Устаёшь ждать.



Если сглаживания не проводить (не жамкаем много раз на кнопочку Smooth ), то получим нечто такое:



Получаются огромные плато в горах.

Сглаживание в отличие от эрозии делает гладкими горы, но не делает никаких плато.

Roughen

Но, постойте… А что если некий Вовочка подошёл и испортил наши офигитительские горы, которые мы получили, подбирая, например, Seed value . Скажем он их очень сильно сгладил. В таком случае можно откатиться (право, не до начального состояния), но всё-таки. Это делается с помощью Roughen . Я ещё раз срендерю ландшафт. После чего его сглажу. Здесь получится практически идентичный вышеприведённой карте ландшафт:

Сглаженный (без Roughen ):

После Roughen :



Но данная опция не проявляет себя, если на неё жамкать многократно, как например, на Smooth .

Stretch

Теперь жамкнем Stretch . Эффект получается как от Fractal roughness при генерации:



Ну, и на последок, картинка с Size landscape = Mega :

А теперь немного про вкладку Camera, окошко с ландшафтом и окошко камеры. Но основной упор я сделаю на это в следующий раз.

Экран VistaPro

В программе практически везде и всегда доступны 4 области: ландшафт, камера, параметры, вкладки.

Ландшафт

На карте с ландшафтом есть несколько объектов. Жёлтый квадратик - то место, где находится камера, жёлтый крестик - место, куда она направлена (далее, в разделе создания анимации, я скажу об этом моменте отдельно. Это очень важно для удаления эффекта тряски), две красные линии , ограничивающие угол обзора. Есть два слайдера : по оси Х, и по оси Y (выделены красным), которые позволяют осуществлять навигацию по карте - смещение центра карты вверх и вниз. Также есть маркеры "+" , "-" и "=" , осуществляющие увеличение, уменьшение масштаба и возвращение в исходное, центрированное состояние соответственно. Помимо этого есть ещё две опции: «C» - центрирование относительно положения камеры (относительно жёлтого квадратика) (следует попробовать сдвинуть камеру в строну, а после этого заюзать данную функцию), «T» - центрирвоание относительно фокуса (взгляда) (относительно жёлтого крестика). Для этого стоит сместить фокус, зажав Place target в разделе Camera , пощёлкать по карте ландшафта, после чего нажать «T»

На карте с ландшафтом можно найти координаты точки. Для этого подводим мышку в нужное место (на скрине мышку не заметно, но поверьте мне, что она есть на карте). Над окном ландшафта появятся координаты X=* Y=* Z=*.

Камера - это окошко в левом углу. Здесь можно увидеть в первом приближении, что будет срендерено. Это очень удобно, так как рендер занимает некоторое время, а здесь можно примерно представить, что будет видно на картинке.

Крестик в центре окна совпадает с крестиком, который тыркнут на ландшафте - это направление камеры. Для понимания того, что происходит, лучше попробовать что-нибудь поделать на карте и с камерой (Для этого будет идеальным сгенерить рандомную карту).

Рендеринг карты можно локализовать, выделив определённую область. Простите Вашего покорного слугу, но я не удержался и взял заготовленный ландшафт. Он чуть интереснее Пирамиды Хеопса. Сравните:



Для того, чтобы отследить этот эффект, следует нажать клавишу «BB» , после чего выделить область на ландшафте:



После рендеринга получим:

Чтобы убрать данный эффект, нажмите BB ещё разочек:

Кнопочки "+" и "-" около камеры меняют угол обзора, что непосредственно будет отражаться на изображении перед камерой: выпуклое, сжимающиеся в точку изображение или вогнутое соответственно. На ландшафте также происходят изменения (две красные прямые съезжаются и разъезжаются соответственно).

Смотрим в точку:



А тут смотрим с широким углом обзора:



Есть небольшой баг (возьму заготовленный ландшафт): место, куда указывает жёлтый плюсик на ландшафте не соответствует изображению перед камерой при бесконечно малых углах. Особенно хорошо это видно на границе водораздела: выставляем указатель камеры на ландшафте на землю (крутить камеру можно в разделе Camera -> Place target ), максимально близко к воде, после чего делаем фокусное расстояние очень большим (1000+ - долго-долго жмём на "+" ), после чего замечаем что камера смотрит на воду, а на ландшафте она сфокусирована на земле. Но это, разумеется, мелочи:

Каждый элемент интерфейса обладает подсказкой. Достаточно подвести к нему курсор, после чего высветится информация в левом нижнем углу, на label:

Внизу, под параметрами есть две кнопочки, которые доступны из любой вкладки: Render и Display . С одной из мы уже знакомы: Render . С помощью неё мы можем сгенерить ландшафт. Есть также Display . С помощью этой кнопочки можно загрузить последний срендереный ландшафт.

Вкладки

Вкладки представляют собой определённый разделы для моделирования мира. Рассмотрим каждый из них в целом, а затем разберём отдельно:

  • Camera
    Данный раздел едва ли нужно пояснять. Здесь всё о положении камеры. Практически всё, что можно сделать с наблюдателем, можно сделать именно отседова.
  • Light
    Свет - аналогичная ситуация. Солнце, солнечные затмения, освещённость и другие приятности можно найти тут.
  • Sky
    Здесь можно завалить или подправить горизонт, включить облака, сделать тучи, добавить луну, а также поразвлекаться с атмосферой так, как хочется.
  • Terrain
    Снег в горах, деревья, палитра текстур гор и многое другое.
  • Water
    Здесь можно утопить свой мир цунами (плохо, право, топится).
  • Tree
    Кэп.
  • Texture
    Добавить свои или подправить родные.
  • Manipulation
    Игры демиургов - здесь находятся кнопочки, позволяющие править мир целиком (видимо, по-другому и нельязя, только всё и сразу).
  • Creation
    Генерим карту.
  • Placement
    Построй свой город.
  • Image
    Шумы, размеры картинки, а также другие параметры.
  • VR Control
    Виртуальная реальность.
  • Path
    Путь передвижения камеры (данная фишка нужна для анимации).
  • Animation
    Создаём своё видео.


Есть вопросы?

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: