Генерация текстур планет как в игре Star Control 2

b7765764aa864ca6ab751a3bb123a53a.png Возможно, кто-то помнит замечательную олдскульную космическую игру Star Control 2. В свое время меня поразила огромная звездная карта с неизведанными планетами, которые предстояло исследовать на фоне разворачивающейся глобальной катастрофы. С тех пор как авторами были опубликованы исходные коды, игра была портирована под новым именем The Ur-Quan Masters на большинство современных платформ.Покопавшись в исходниках, я обнаружил простой алгоритм, генерирующий текстуры планет, и написал программу на Python, позволяющую генерировать аналогичные текстуры.

Формируем карту высот с помощью алгоритма Fault Formation («формирование разломов») Раскрашиваем карту высот, используя опорные RGB цвета и градиент между ними Формирование карты высот Создаем матрицу высот той же размерности, что и генерируемая текстура планеты. Север сверху, юг снизу, а горизонталь матрицы представляет собой круговую развертку планеты вдоль параллели. Значение высот может меняться только в пределах от 0 до 255, поэтому удобно отображать их оттенками серого цвета Заполняем матрицу базовым значением высоты (base elevation), например, 128:  18e9ed44de3649a085d4d2df136fb494.png   459e4b49da174e58835c62c694afd31f.png 

Генерируем две случайные непересекающиеся линии с севера на юг. Эти линии «формируют разлом» — делят поверхность планеты на две части, одну из которых мы поднимаем на фиксированную константу (elevation delta), а другую опускаем на эту же константу. Для наглядности пусть константа равна 10:  07d9c2006f0449bba1804fa1d8a405e5.png   dd76740a5b314a4b8d1dd6749abad1c2.png 

Повторяем предыдущий пункт заданное количество раз (iterations num).На рисунках ниже: 10 итераций, 100 итераций, 1000 итераций:  09cd883540cd431f95c380744d20ddf2.png   937cbedbbd6c45e386fd49a6735e79b6.png 

 fbead073a44a4172bd47ee7bc4838f62.png   68e3977f37c042dab33da1ed65b1342f.png 

 8580dc4f957b465d90ebb6fce1167fb2.png   799a771a849d4d6fa54261112e459888.png 

Раскрашивание карты высот RGB цветами Делим весь диапазон высот (от 0 до 255) на N более-менее равных частей с N + 1 опорными точками на границах этих частей Задаем RGB цвет для каждой опорной точки диапазона Вычисляем RGB цвет для всех промежуточных точек диапазона, линейно интерполируя компоненты цвета между опорными точками. Иными словами, заполняем значения высот градиентом между опорными цветами Генерируем текстуру планеты, заменяя каждую ячейку матрицы высот на вычисленный в предыдущем пункте RGB цвет Вот несколько возможных вариантов раскрашивания одной и той же карты высот: e2c9fd0afc4a4ce1ace0d0244d16ba56.png   a5d2aae041d64ac786dd313e0bbac61b.png07456f29d2c5498ba09e634183df5f95.png

f3a50625da9e430b80159e970a7f771f.png   22b1af98997646ec853f38d0edc207ea.pngf78688c0dd704533842b9e45c68a789f.png

b48f254c772341df9cb9a9224cf0ca06.png   2234a366bfd340a9afcc953daf4c1871.png2ceb201e41b2451782bb42484b5b06e5.png 

Для запуска программы необходимо установить Python 2.7 и несколько библиотек к нему: NumPy, PIL и PyOpenGL.Программу можно скачать из репозитория git: https://github.com/barabanus/starcontrol

Программа состоит из двух независимых скриптов: planet.py (генерирует текстуру), и space.py (рисует вращающуюся планету с наложенной текстурой).

Некоторые особенности управления:

Для изменения опорного цвета кликните левой кнопкой мыши на квадратике с цветом. В MacOS во всплывающем диалоге есть возможность сэмплировать цвет с экрана Для создания нового опорного цвета кликните левой кнопкой мыши на градиенте Для удаления опорного цвета кликните правой кнопкой мыши на квадратике с цветом Для сохранения текстуры кликните по ней левой кнопкой мыши. При этом запускается скрипт, рисующий вращающуюся планету с этой текстурой Программа создавалась на MacOS, тестировалась на WinXP. Если вы нашли и смогли исправить ошибку в коде или украсили рендер — пишите и предлагайте изменения.

© Habrahabr.ru