Как улучшить качество текстур: разбор методов оптимизации UV

Привет, DTF, у вас тут вроде говорят о геймдеве, иногда. Я хочу рассказать о UV Unwrapping, о том, как качество UV влияет на качество текстур. У новичков частенько всплывают вопросы, в стиле «а почему такое низкое качество, 4К же поставил» — естественно, без упоминания того, что развернули автоматически или объект размерами как дом, а текстурируется одним уникальным материалом.

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

Методы текстурирования

Тайловое текстурирование

Видеокарта просчитывает текстуру один раз, когда UV Shells (острова) выходят за пределы квадрата, текстура копируется и никаких новых просчетов не происходит. Паттерны текстуры с обеих сторон продолжают друг друга, чтобы не было швов.

Модель из Overwatch (локация «Темный лес») Слева UV Развертка

Тайлами текстурят большие объекты: грунт, дома, стены, крупногабаритная техника или космические корабли, например. В тайловом методе внешний вид UV перестает быть понятным, будет выглядеть как неразборчивое месиво и это не важно, главное — выходной результат.

Как улучшить качество текстур: разбор методов оптимизации UV

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

Пример смешивания двух тайлов на стене. Модель из Overwatch (локация «Темный лес»)

Почему на больших объектах используются тайлы? Чем больше плоскость, тем ниже плотность пикселей, а отсюда и низкое качество, так называемое «мыло». Этого можно избежать, повышая разрешение текстур или часто применять overlapping.

Космический корабль, текстурирован тайлами <a href="https://api.dtf.ru/v2.8/redirect?to=https%3A%2F%2Fsketchfab.com%2F3d-models%2Fdss-harbinger-battle-cruiser-474f62d00ed54212b37f93ce91569c53&postId=202100" rel="nofollow noreferrer noopener" target="_blank">Sketchfab</a>
Космический корабль, текстурирован тайлами Sketchfab

Атлас тайлов или тримы

Trim sheet или «тримы» — это текстуры для вытянутых элементов: доски, стены, плинтусы. Тримы бесшовные в одном направлении, иногда в них ещё добавляют декали. Примеры таких текстур.

На этой текстуре: узоры, грязь, линии и все они используются множество раз, на нескольких моделях, разработчики укладывают это в один материал, чтобы снизить количество вызовов отрисовки (Draw Call) в сцене.

Trim sheet (Overwatch карта Кастильо)
Trim sheet (Overwatch карта Кастильо)

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

Пример атласа тайлов <a href="https://api.dtf.ru/v2.8/redirect?to=http%3A%2F%2Fwww.victorkarp.com%2Fscifitileset1.html&postId=202100" rel="nofollow noreferrer noopener" target="_blank">Victor Karp</a>
Пример атласа тайлов Victor Karp

Классический метод текстурирования или уникальный

Под «уникальным» подразумевается то, что материал будет только на одном или на нескольких похожих объектах, необязательно для каждой детали делать отдельный материал — всё зависит от модели, размеров и требования к качеству.

Для уникального материала делается грамотно упакованная развёртка — что значит «грамотно», буду разбирать ниже, а пока пример плохой и хорошей развёртки.

Пример развёрток одной и той же модели
Пример развёрток одной и той же модели

Процедурное текстурирование

Этот метод не популярен как минимум из-за плохой оптимизации. Сюда можно добавить ещё кучу минусов, которые будут зависеть от задач и от того, в каком именно 3D-пакете или игровом движке это делается.

Говоря о процедурном текстурировании, я имею в виду материалы, что учитывают форму геометрии и добавляют детали. В этом методе текстуры накладываются трипланарным проецированием, без использования UV-развёртки. Хороший пример из движка Unigine.

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

В упомянутом Unigine сейчас нет нодового редактора, а значит нельзя создать текстуру прямо в движке. Использовать готовую текстуру и накладывать эффекты сверху — это даже не совсем процедурное текстурирование. Данный способ упомянут лишь для ознакомления. Описывать подробно не имеет смысла, потому что процесс процедурного текстурирования отличается от программы к программе, а в некотором софте такая возможность и вовсе отсутствует.

Так как текстурить-то

Определяйтесь исходя из размеров объекта, требований к оптимизации.

  • Нужно затекстурить большой объект, в хорошем качестве и минимум материалов — используйте тайлы.
  • Объект не очень большой и необходимы детали на текстуре — лучше делать уникальные материалы.
  • Вас не заботит оптимизация, только качество — в таком случае можете даже не читать эту статью и делать как удобно.

Как понять, насколько объект большой, когда разделять модель на уникальные материалы или на тайловые? Тут вам поможет texel density.

Texel Density

Аббревиатура из двух слов «Texture» и «Element» — текстура и элемент. Величина, которая является отношением размера текстуры (в пикселях) к габаритам 3D-модели в сцене. Если интересно подробнее, то вот несколько ссылок по этой теме: Habr: Texel density, artstation: Texel Density, blender3d: Texel Density, artstation: Texel Density Theory, artstation: What a Texel Density.

Я сделал модель, что это — не знаю, просто для примера. На ней буду демонстрировать все этапы оптимизации UV-развёртки.

Как улучшить качество текстур: разбор методов оптимизации UV

Чтобы следить за результатом, буду постоянно проверять TD (Texel Density) Разворачивать буду в Blender 3D + Аддоны. Если у вас другой софт, просто найдите аналогичный инструментарий у себя или обратите внимание на программы RIZOM UV и UVlayout

Как улучшить качество текстур: разбор методов оптимизации UV

Сделал авторазвёртку стандартным инструментарием, если верить расширению Texel Density Checker то мой общий тексель сейчас при разрешении 2048px составляет 1,560 пикселя на сантиметр — это усредненное значение на всю модель, в некоторых местах есть незначительная разница. А ещё аддон говорит мне, что я использую только 44% UV-пространства, больше половины пикселей текстуры уйдут в никуда. Это очень плохо.

На задней стороне корпуса есть окошко, туда я собираюсь вводить текст при текстурировании, далее буду следить за TD именно на нём, сейчас в этом участке 1.338 px/cm — маловато.

1.338 px/cm
1.338 px/cm

Для начала подниму процент используемого UV-пространства, расставив все острова плотнее. Сделаю это автоматически с помощью аддона UVPackMaster (PRO).

Напомню, что существуют программы RIZOM UV и UVlayout — в них также есть плотная авторазвертка. Если ваша модель не слишком детализированная, то проще и даже лучше сделать это вручную.

Расставив UV-острова плотнее, их размеры удалось увеличить, ну и TD соответственно, в ранее упомянутом окне сейчас 1.531 px/cm. Однако это ещё не достаточно плотная UV, можно уменьшить Padding — расстояние между островами

Плотная упаковка UV

Насколько плотно друг к другу упаковывать UV острова, почему между ними должно быть расстояние — вполне достаточно знать рекомендуемое расстояние паддинга:

  • текстура 256px = Padding 2px;
  • текстура 512px = Padding 4px;
  • текстура 1024 = Padding 8px;
  • текстура 2048 = Padding 16px.

Это только рекомендации, значения могут быть другими, в зависимости от того, как настроен Mip Mapping, в игровом движке.

Padding и Mip Mapping

Padding (иногда Dilation), это текстурный отступ, нужен чтобы на модели не было швов, при генерации MipMap. При экспорте текстур, Substance Painter предложит вам настроить расстояние паддинга, который будет сделан автоматически, подобная функция есть во многих программах.

Генерация паддинга в Substance Painter Substance docs

Mip Mapping. Вкратце — при отдалении камеры, у текстур снижается разрешение, для оптимизации. Это почти то же что и лоды, но для текстур. Разрешение текстур снижается, а значит растёт размер пикселей и те выходят за пределы UV-острова, попадая на другие, если между ними не будет расстояния, на модели появляются швы.

Справа пример без паддинга <a href="https://api.dtf.ru/v2.8/redirect?to=https%3A%2F%2Fdocs.substance3d.com%2Fspdoc%2Fpadding-134643719.html&postId=202100" rel="nofollow noreferrer noopener" target="_blank">Substance docs</a>
Справа пример без паддинга Substance docs

Это ещё не всё — паддинг нужен для запекания фасок на карте нормалей, но это уже отдельная и долгая тема.

Если хотите больше подробностей о том что такое Padding и MipMap, то вот несколько ссылок: Polycount: Edge padding, Polycount: Mip Mapping, Substance docs: Padding, Wiki: MipMap, GameDev.ru: MipMap, Habr: Пиксельные отступы.

Вернемся к моей модели, я буду текстурить в разрешении 2048px, поэтому запакую с паддингом в 16px, теперь TD 1.616 px/cm, незначительный прирост, в моём случаё изначально расстояние было не слишком большое.

1.616 px/cm
1.616 px/cm

С плотностью вроде разобрались, но это ерунда. Есть способ о котором возможно слышали многие, он значительно повлияет на качество текстуры.

Overlapping

Overlapping называют наложение UV-островов друг на друга, его используют на похожих по форме объектах или вовсе идентичных, это позволяет сэкономить место на UV-квадрате и как следствие улучшить качество текстур.

Корпус модели симметричен по форме, можно развернуть только половину, а на вторую накладывать ту же текстуру. Я добавил модификатор Mirrror, на UV-пространстве освободилось довольно много места, можно пойти дальше, корпус цилиндра симметричен по двум осям.

Как улучшить качество текстур: разбор методов оптимизации UV

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

Текстура царапин повторяется по двум осям из за чего становится похожа на ручной узор а не царапины

Overlapping можно использовать не только на симметричной половине, но ещё и на любых повторяющихся элементах геометрии.

Шесть повторяющихся элементов
Шесть повторяющихся элементов

Эти детали разверну как одну, а ещё наложу друг на друга боковые полигоны. Чтобы не повторять эти действия по несколько раз — сначала разверните объект, а потом скопируйте, или размножьте его через модификатор

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

Как улучшить качество текстур: разбор методов оптимизации UV

Теперь запакуем с overlapping, проверим результат. TD 2,354 px/cm — гораздо лучше. Напомню, что было 1,616 px/cm. Результат уже виден наглядно, по размеру шахматной текстуры.

2,354 px/cm
2,354 px/cm

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

Проблема overlapping: зеркальность

Как улучшить качество текстур: разбор методов оптимизации UV

Тексты очень плохо дружат с overlapping — их буквально отзеркаливает. Очевидное решение: не используйте overlapping именно там, где будете что-то писать. В случае с этой машинкой можно просто развернуть дверь отдельно, но это не единственный выход. Для текста можно использовать декали (сделать ещё один полигон сверху и наложить на него надпись с прозрачным фоном).

Динамит Эш из игры Overwatch, цилиндры «оверлапятся», для текстов сделали отдельную текстуру.
Динамит Эш из игры Overwatch, цилиндры «оверлапятся», для текстов сделали отдельную текстуру.

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

You spin me right round

Запекание ambient occlusion с overlapping, неуместные тени

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

Как улучшить качество текстур: разбор методов оптимизации UV

Несколько вариантов решения:

Первый вариант — отодвинуть геометрию друг от друга, если конечно это отделяемая геометрия. В Painter или в Marmoset Toolbag двигать не обязательно — есть функция Only Same Mesh Name. Для АО включается отдельно.

Если не понимаете, о чём речь, то вам лучше посмотреть уроки по запеканию карт, я сейчас не буду заострять внимание на этом.

Второй способ — исключить повторяющиеся элемент из запекания. Для этого выделяем оверлап острова и отводим в любую сторону, ровно на один квадрат. В Blender 3D это делается двумя нажатиями: «G» и «1».

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

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

Запекание Normal map с overlapping, искажения

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

Как улучшить качество текстур: разбор методов оптимизации UV

Например: я запёк карты в какой-то программе и экспортировал в игровой движок или ещё куда. На одной стороне всё нормально, а с другой появились какие-то линии, треугольники, градиенты и прочее описание артефакта.

Как улучшить качество текстур: разбор методов оптимизации UV

Тут я вручную триангулировал симметричную сторону неправильно, по бокам появились искажения. Как я уже говорил, это может произойти автоматически

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

Запекание Normal map с overlapping, артефакты, рёбра треугольников

На карте нормалей появилась пунктирная линия, идущая вдоль ребра треугольника
На карте нормалей появилась пунктирная линия, идущая вдоль ребра треугольника

Этот артефакт воспроизводится, когда есть overlapping, модель триангулирована и включен antialiasing в настройках запекания. Основная причина, как я понял, в antialiasing. Исправляю я её исключением симметричной стороны из запекания — как это делается, я уже писал выше.

Вроде перечислил все проблемы. По крайней мере те, с которыми я сам сталкивался, вернемся к оптимизации UV.

Выпрямляем UV

Когда мы делаем линии с наклоном, то получаем вот такие лестницы:

Как улучшить качество текстур: разбор методов оптимизации UV

Решить эту проблему на все 100%, к сожалению, нельзя. Если на геометрии есть изгибы, то не получится делать острова исключительно из прямых ребер, но есть парочка вариантов как минимизировать это.

Увеличить разрешение текстур — очевидно и не всегда вариант, но стоило упомянуть. Более высокое разрешение не устранит проблему, но её будет меньше видно.

Как улучшить качество текстур: разбор методов оптимизации UV

Выпрямить ребра UV-развёртки — насколько это возможно, наглядно.

Помимо устранения лестниц такие ровные UV-острова проще упаковать. На моей модели есть несколько деталей, которым стоило бы упростить форму.

В каждом 3D-пакете есть возможность посмотреть растяжение UV, в Blender3D например в 2D окне/view/overlays/stretching, синий цвет UV — это хорошо, красный — плохо. Просто следите за этим, правьте только те детали, что не станут краснеть.

Как быть в тех случаях, когда сама геометрия не ровная? Оставить как есть, но если рёбра наклонены не слишком сильно, то можно попробовать выпрямить. В Painter есть функция трипланарного проецирования — она растянет текстуру по неправильной UV так, что на геометрии она будет выглядеть корректно, но с этим лучше не перебарщивать.

Что вообще из себя представляет трипланарное проецирование? Это не сложно понять как минимум по названию, но если у вас есть интерес, то напишу отдельную статью.

Программе стало проще упаковывать UV с прямыми линиями, отчего я поднял TD, с 2,354 до 2,366 px/cm — мелочь конечно, но я не ради этого выпрямлял их, да и не тот пример. Была бы модель изначально с кучей неровностей то можно было бы показать разницу.

2,366 px/cm
2,366 px/cm

Распределение текселя

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

Как улучшить качество текстур: разбор методов оптимизации UV

На мою модель можно посмотреть со всех сторон, но внутренняя сторона корпуса, как мне кажется, занимает много места, а взгляд туда не падает.

Как улучшить качество текстур: разбор методов оптимизации UV

Совсем немного уменьшу размеры UV-островов внутренних стенок и снова запакую, программа сама отмасштабирует все остальное, чтобы закрыть свободные участки. Это позволило немного поднять TD, было 2,366 стало 2,590 px/cm

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

Завершение

Теперь можно закрасить это и сравнить качество первоначальной развертки c текущей. Сравнение текста.

Текст был мыльным и местами не разборчив, он особенно станет неразборчив при малейшем отдалении камеры. Сравнение металлических деталей и углов:

Фаски стали лучше скрывать острые углы а швы менее заметны. Общий вид:

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

423423
65 комментариев

В закладки, материал - супер!

18
Ответить

За статью, спасибо. Но ничего не написал про "Харды" и группы сглаживание  Это места с углом 90 градусов и меньше. На них UV "шелы" должны быть разорваны в этом месте. Про нормали ничего не написал, без них тоже будет шляпа, а не текстура, ибо шейдеры не последнее имеют значение. В 3ds max например, просто обязательно использование скрипта weightednormals, в других программах не знаю. Каждый "шелл" - это одна группа сглаживания, сверху weightednormals. Без вышеописанного, будут видны швы и хреновый шейдинг в движке, какой бы вы "паддинг" не ставили, хоть 1024 пикселей.

7
Ответить

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

7
Ответить

Комментарий недоступен

4
Ответить

Статью не читал, только пролистал. И комментарии. Но разве плейн с альфа-каналом под текст не самая очевидная в мире вещь? Я в 3D – дуб дубом, но надписи так на предметы и наношу.

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

Ответить

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

Ответить

Раньше я пользовался UVlayout, потом нашел нужные аддоны для бленда и понял что в нем не хуже, не приходится перекидывать модель туда сюда что добавляет удобства

5
Ответить