Пользователь
0,0
рейтинг
26 февраля 2015 в 13:20

Разработка → Генерация текстур планет с помощью алгоритма Fault Formation


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

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


Алгоритм


  1. Формируем карту высот с помощью алгоритма Fault Formation («формирование разломов»)
  2. Раскрашиваем карту высот, используя опорные RGB цвета и градиент между ними

Формирование карты высот


  1. Создаем матрицу высот той же размерности, что и генерируемая текстура планеты. Север сверху, юг снизу, а горизонталь матрицы представляет собой круговую развертку планеты вдоль параллели. Значение высот может меняться только в пределах от 0 до 255, поэтому удобно отображать их оттенками серого цвета
  2. Заполняем матрицу базовым значением высоты (base elevation), например, 128:

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

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

        
     

        
     

        
     


Раскрашивание карты высот RGB цветами


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

Вот несколько возможных вариантов раскрашивания одной и той же карты высот:

   


   


   

 

Программа


Для запуска программы необходимо установить Python 2.7 и несколько библиотек к нему: NumPy, PIL и PyOpenGL.

Программу можно скачать из репозитория git: https://github.com/barabanus/starcontrol

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

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

Программа создавалась на MacOS, тестировалась на WinXP. Если вы нашли и смогли исправить ошибку в коде или украсили рендер — пишите и предлагайте изменения.
Максим Ганенко @barabanus
карма
39,7
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (12)

  • +2
    Алгоритм интересный но мне кажется не лучший выбор для текстурирования планет. На приведенных примерах слишком сильно просвечивают прямые линии, а как говорилось в фильме «Прометей» — Бог не использует прямые линии. Возможно стоит добавить размытие (blur).
    • 0
      Авторы игры в общем-то так и делали — добавляли dither и blur. В будущем я модифицирую программу с возможностью добавлять стек фильтров, кратерами, атмосферой и т.д.
    • +3
      Интересно, а если использовать этот-же алгоритм, то вместо линий использовать кривые, или просто окружности большого радиуса… должно получится интереснее. А ещё попробовать комбинировать эти два метода.
    • 0
      Именно для разрывных нарушений рельефа иногда использует :) Не абсолютно прямые, но близко к тому. Посмотрите на океаны в Google Earth, к примеру. Трансформные разломы Атлантики и Индийского океана.
      Интересно добавить кольцевых структур (кратеры и астроблемы).
  • 0
    Да, чудные были времена…

    Кстати, что думаете про сжатие координат из цилиндрической в сферическую? Искажение сильно влияет на прорисовку полярных областей?
    • 0
      Этот алгоритм подходит для отображения планет только в одном ракурсе. Полюса выглядят ужасно.
    • 0
      Думаю, что алгоритм можно изменить, чтобы он хорошо отображал полюса. Сейчас цикличность обеспечивается только на уровне горизонтали. Для полюсов цикличность должна быть по вертикали.
      • +1
        Тот же алгоритм, но имеющий цикличность и по горизонтали, и по вертикали

        Взято отсюда
  • +2
    Я просто оставлю это здесь.
    Всем хорошего вечера :3
    • +1
      Отличный ресурс!
      • +2
        Там можно и скрипт этот скачать, скомпилить и использовать его с командной строки. Можно указывать seed для генератора, и генерить текструы сразу для разных видов сфер. Например проекцию для икосайдера. Что меня люто порадовало.
  • 0

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.