python

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

  • пятница, 27 февраля 2015 г. в 02:11:50
http://habrahabr.ru/post/251419/


Возможно, кто-то помнит замечательную олдскульную космическую игру 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. Если вы нашли и смогли исправить ошибку в коде или украсили рендер — пишите и предлагайте изменения.