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

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

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

Развиваем мысль дальше. Внутреннее наполнение контейнеров может быть каким угодно. Можно наделать много разных вариантов одной текстуры и мостить площадь случайными плитками из набора. Но как ни крути, даже при таком подходе остаётся повторяющаяся сетка от граней плитки. Следовательно, нужно придумать способ для перемешивания граней.

На само�� деле, правая и левая сторона одной плитки не обязательно должны сочетаться друг с другом, главное, чтобы они сочетались с соседними плитками. Можно сделать несколько вариантов текстуры с разными краями и упаковать их в атлас. Затем, во время укладывания текстур, просто брать случайную плитку с краем, который подходит к соседним уложенным плиткам.
К сожалению, размер атласа для полного набора плиток очень быстро растёт с количеством вариаций граней. Расчёт ведётся по следующей формуле: N2*M2, где N — количество горизонтальных граней, M — количество вертикальных граней. Например, для двух вариантов на горизонталь и вертикаль выходит шестнадцать разных плиток. Если просто нужна гарантированная возможность продолжить мозаику, то формула будет попроще: 2*N*M.

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

Как создать атлас плиток? Можно взять одну большую картинку и наложить на неё сверху сетку из цветных граней. Затем выбрать подходящий шов для каждого цвета и размножить его по сетке. Либо пойти от обратного: сначала сделать сетку, потом заполнить пустые места. Ниже есть ссылки на более подробную инструкцию.

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

Я набросал нехитрый код на C# для Unity3d для работы с мозаикой Вана, можете посмотреть на него по ссылккам ниже.
Unity Web Player | Windows | Linux | Mac | Исходники на GitHub
Пробел — новая случайная текстура, 1, 2, 3 — выбор атласа, Esc — выход.
Для пользователей Linux: Сделайте файл WangTiles исполняемым с помощью «chmod +x WangTiles» и запускайте.
Полезные ссылки по теме:
Инструкция по созданию атласов
Процедурная генерация подземелий
Подробнее про создание атласов разных размеров
Полуавтоматический генератор атласов
По просьбам трудящихся небольшое дополнение про создание атласов:
Берём понравившуюся большую картинку, накладываем сверху сетку для удобства в фотошопе или где ещё.

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

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

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

