...

пятница, 20 июня 2014 г.

[Из песочницы] Grid Tiling: смешение нескольких тайлов

Думаю, многие из геймдев-программистов размышляли о том, как реализовать удобный map-tiling. Только представив всевозможные комбинации смешений, можно порядочно изломать свой мозг — я несколько раз пытался изобразить какой-либо простой в использовании алгоритм, который позволял бы отображать разнообразные тайло-карты. О том, что из этого получилось — а получилось нечто достаточно простое для реализации — можно узнать ниже.

Сколько раз текстуры необходимо смешать для того, чтобы изобразить всевозможные комбинации из двух тайлов на сеточном поле? А добавляя дополнительные тайлы это количество увеличивается до таких чисел, о которых даже страшно думать. Забудем на момент о всех этих сложностях и погрузимся в рассмотрение комбинаций, чтобы выявить какие-нибудь шаблоны, которые помогут нам победить трудности смешения.



Начнем со смешения двух тайлов. На рис.1 я изобразил простейшую тайловую разметку «как есть», а на рис.2 — нечто такое, что мы хотим иметь в итоге.



На рис.3-4 можно посмотреть более сложную разметку. Количество всевозможных комбинаций достаточно велико (а мы помним о предстоящем добавлении новых тайлов), и нам нужно найти некую закономерность, которая поможет упростить задачу.


В процессе я успел нарисовать здоровенное количество этих самых комбинаций и в итоге пришел к такому решению — если разделить тайл на 4 части, то его вид можно определить всего лишь по 3 смежным тайлам. Посмотрим на 5 разных шаблонов смешения:





Маленький квадрат в желтой рамке — это часть того тайла, который мы пытаемся обрисовать. То, как он будет выглядеть, определяется смежными H-V-C-тайлами.

H — смежный горизонтально (Horizontal)

V — смежный вертикально (Vertical)

C — угловой тайл (Corner)

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


В итоге у нас есть 3 смежных тайла, что означает всего лишь 8 различных их комбинаций. Почему я изобразил только 5 шаблонов? Давайте рассмотрим эти комбинации:

HCV (все смежные тайлы того же самого типа, что и рассматриваемый): шаблон 5 (отрисовываем часть тайла «как есть»)

H-V (H и V-тайлы такие же, тайл в углу отличается): шаблон 4

--V или -CV: шаблон 3 (две комбинации мутировали в один шаблон — это упрощает дело; можете нарисовать их и посмотреть, что действительно можно обойтись только одной картинкой)

H-- или HC-: шаблон 2

--- или -C-: шаблон 1


Изначальная куча комбинаций уменьшилась до всего лишь 8 и даже больше — нам необходимо только 5 разных шаблонов для любой тайловой разметки. Причем шаблон номер 5 весьма прост — мы рисуем нашу часть тайла без какого-либо смешения. Получается, для каждой части необходимо получить 4 разные маски смешения для шаблонов 1-4. Учитывая то, что тайл мы дважды располовинили, нам понадобится маска 4х4, при помощи которой мы можем намешать разметку из двух тайлов в любых вариантах.




Маска для одной части тайла




Маска 4х4


Достаточно занудная, не так ли. Естественно, вы можете придумать что-нибудь еще более красивое; для демонстрации происходящего я буду использовать вот такую маску.

Первая картинка — это маска для той части тайла, которую мы исследовали чуть ранее, а вторая — комбинация масок для всех четырех частей:

— верхне-левая часть (порядок соответствует номерам шаблонов: 1-2-3-4)

— верхне-правая часть

— нижне-правая часть

— нижне-левая часть

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



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


Резюмируя вышеописанное — алгоритм таков:

— рисуем тайл-1

— рисуем по маске тайл-2


Итак, со смешением двух тайлов будем считать что разобрались. Как насчет добавления еще парочки?


Сначала определимся с последовательностью. Хотите знать, что получится если мы заменим порядок отрисовки тайлов, то есть начнем с тайла-2, а маску положим на первый? Вот картинка:



Весьма отличается, не так ли. То есть порядок имеет значение. Мы рисуем первый тайл, а сверху накладываем второй. Какие-нибудь идеи насчет третьего? Элементарно — просто добавляем новый слой поверх той картинки, что мы получили ранее. Правда тут есть пара моментов, которые необходимо учесть.


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

Вычисляя маску для разметки желтой травы необходимо считать речной тайл таким же, что и желтый (помните HCV-шаблоны? К примеру, если все эти тайлы — речные, мы считаем, что подходит шаблон номер 5). А для вычисления маски под реку все ранее отрисованные тайлы считаем чужими (в аналогичном HCV-примере нужен будет шаблон номер 1).


Последим за алгоритмом. Допустим, зеленое поле это тайл-1 (первое в стеке), желтая трава — тайл-2, а река — тайл-3.

— рисуем всю сетку тайлом-1 — генерируем маску для каждого тайла, при этом все тайлы, меньшие 2, представляют черный цвет маски (полностью прозрачный), а те, что больше или равны — белый (отрисовываются)

— рисуем тайл-2 (при этом отрисовываются все тайлы, начиная со второго, причем как тайл-2!)

— генерируем вторую маску, теперь все тайлы, меньшие 3 — прозрачные, 3 и более — отрисовываются

— рисуем тайл-3

— … (продолжаем, пока тайлы не кончатся)


Звучит просто? Особенно в сравнении со сложностью комбинирования каждой пары тайлов друг с другом. Если мое объяснение не такое шикарное, как я предполагал — просто посмотрите поэтапную работу алгоритма на скриншотах, это должно прояснить ситуацию:



(Простите за две пересекающиеся реки. Всё ради тайлинга!)


Вот такая вот основная идея. При этом можно использовать различные маски при отрисовке разных слоёв. Смешение нашей желтой травы и зеленого поля может выполняться с одной маской, а для более симпатичных речных берегов можно подобрать другую. Также можно подумать насчет дополнительной текстуры — для тех же симпатичных берегов только альфы будет недостаточно, поэтому почему бы не положить по маске аналогично размеченную специальную текстуру. В общем, есть простор для мыслей при использовании этого алгоритма, лишь бы всё это вписалось в фантазию и возможности железа. Надеюсь, вы найдете этот метод полезным, или хотя бы он навеет какие-либо свои интересные идеи!


* Небольшой постскриптум: так исторически сложилось, что эту статью я сначала написал на английском. Возможно, если бы при написании русской версии я не подсматривал на оригинал, язык был бы более человеческим; по-крайней мере я старался! В любом случае, прошу прощения за внезапные сложночитаемые обороты.


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Комментариев нет:

Отправить комментарий