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

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

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

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

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

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

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

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

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

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

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

Космический корабль, текстурирован тайлами Sketchfab

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

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

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

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

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

Пример атласа тайлов 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-развёртки.

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

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

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

Справа пример без паддинга 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

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

Overlapping

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

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

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

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

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

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

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

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

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

2,354 px/cm

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

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

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

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

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

You spin me right round

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Выпрямляем UV

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

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

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

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

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

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

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

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

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

2,366 px/cm

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

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

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

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

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

Завершение

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

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

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

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

0
63 комментария
Написать комментарий...
Zendel

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

Ответить
Развернуть ветку
Serj

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

Ответить
Развернуть ветку
Руслан Феликин
Автор

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

Ответить
Развернуть ветку
5 комментариев
Аккаунт удален

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

Ответить
Развернуть ветку
Petr Matafonov

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

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

Ответить
Развернуть ветку
2 комментария
Darkusoid

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

Ответить
Развернуть ветку
Руслан Феликин
Автор

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

Ответить
Развернуть ветку
12 комментариев
Dmitry Timofeev

Спасибо. Хорошая статья.

Ответить
Развернуть ветку
Половый бинокль

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

Ответить
Развернуть ветку
Mebemory

Статья хороша, но техничка:

Процедурное текстурирование
В этом методе текстуры накладываются трипланарным проецированием, без использования UV развертки

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

Этот метод не популярен, как минимум из-за плохой оптимизации"

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

Cюда можно добавить еще кучу минусов, которые будут зависеть от задач и в каком именно 3D пакете или игровом движке это делается

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

Ответить
Развернуть ветку
Руслан Феликин
Автор

Не ожидал, что будет столько заинтересованных, спасибо за добрые комментарии и критику. Чтож, постараюсь писать еще

Ответить
Развернуть ветку
Animavulnus

Из овера самим можно вытащить модельки с разверткой и текстурами, чтобы покрутить посмотреть как там все это делается?

Ответить
Развернуть ветку
Руслан Феликин
Автор

Оverwatch DataTool + для него блендер аддон, чтобы автоматом все импортировать. Я хотел рендер Сигмы сделать, а потом еще и изучил модельки

Ответить
Развернуть ветку
Ярослав

Это проще у гугла спросить 
Ссылок много

Ответить
Развернуть ветку
Ярослав

Программами для выдирания материалов из игры. 
Хотя это скорее уже все сделали - так что можно на торрентах поискать)

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

Ничего не понял. Почему нельзя просто на текстуре дорисовать за рамками острова? Или это ваша программа так не даёт делать?

Ответить
Развернуть ветку
Руслан Феликин
Автор

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

Ответить
Развернуть ветку
6 комментариев
PixelMachineGun

Классная статья, спасибо!

Ответить
Развернуть ветку
Meta

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

Ответить
Развернуть ветку
Alex Korystov

Супер!
Лайк, подписка, колокольчик. Давай ещё)

Ответить
Развернуть ветку
Stanislav Alexandrov

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

Ответить
Развернуть ветку
AngelWiTu

Дружище, не бросай писать такие посты:) Вышло интересно и познавательно

Ответить
Развернуть ветку
Аккаунт удален

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

Ответить
Развернуть ветку
Petr Matafonov

Процедурная генерация спасет мир.

Ответить
Развернуть ветку
гомофобный пикник

Статья огонь, спасибо! Лайк, подписка

Ответить
Развернуть ветку
Георгий Животовский

Чмоки в лобик , статья шикарная 

Ответить
Развернуть ветку
R4M5EY

Годнота.. от души!
Лайк -> В закладки -> Репост -> Подписка

Ответить
Развернуть ветку
Dmitry Bashkatov

Отличная статья!

Ответить
Развернуть ветку
марк флинт 🌐

Спасибо! Отличная статья!

Ответить
Развернуть ветку
Vaskrol

Я вроде не увидел ещё тут способ текстурирования, который я часто применяю для мобилок. Когда у тебя есть одна текстура с кучей цветов, градиентов, всяких бесшовных паттернов от края до края и местами разных надписей и логотипов, и ты можешь использовать её для текстуринга вообще чуть ли не всех моделей в игре.  Например, чтобы использовать 5 одинаковых моделей машинок или мобов, но с разными UV. Это позволит на их всех повесить одинаковый материал и иметь машинки разного цвета и рисовать в один Draw Call.

Ответить
Развернуть ветку
Руслан Феликин
Автор

Да видел такое. У него есть определение, название?

Ответить
Развернуть ветку
1 комментарий
TheNeko

Класс!

Ответить
Развернуть ветку
Alexey Davydov

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

Ответить
Развернуть ветку
Руслан Феликин
Автор

В теме оптимизации в игровых движках я уже не шарю. Не могу сказать

Ответить
Развернуть ветку
1 комментарий
Сергей Заплетин

Очень полезно. спасиибоо

Ответить
Развернуть ветку
Hrofti

Норм статья. Молодец. Хорошую базу описал.

Ответить
Развернуть ветку
Читать все 63 комментария
null