Fajargo

Fajargo

Пикабушник
поставил 4125 плюсов и 1203 минуса
отредактировал 0 постов
проголосовал за 0 редактирований
Награды:
10 лет на Пикабу
1548 рейтинг 326 подписчиков 9 подписок 16 постов 10 в горячем

Работа над ошибками в 3D. Эпилог. Запечка лавочек. ч.2

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


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


Под словом "качественная" я понимаю не только отсутствие артефактов при шейдинге (ибо это само собой разумеется), но и, во-первых, возможность работать с текстурой в дальнейшем, и, во-вторых, возможность при необходимости использовать её для других ассетов.


Основа хорошей нормалки лежит в правильной подготовке low poly. Вообще, существует золотое правило: low poly и без нормалки должна шейдиться корректно. Зависит это от двух основных моментов:


1. Триангуляция

2. Вертексные нормали


Начнем по порядку и поговорим о триангуляции. Важно помнить, что ни один софт по работе с 3D не воспринимает ни один вид полигонов кроме треугольников. Во вьюпорте вы можете видеть и четырехугольники, и пяти, и шести и сколькоугодноугольники. Софт же воспринимает всю модель исключительно как набор трисов. Соответственно, шейдинг модели также будет учитывать наличие треугольников. Для того, чтобы лучше понять тему, возьмем следующий объект:

Работа над ошибками в 3D. Эпилог. Запечка лавочек. ч.2 3D, Gamedev, Длиннопост

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

Работа над ошибками в 3D. Эпилог. Запечка лавочек. ч.2 3D, Gamedev, Длиннопост

Любой четырехугольник имеет два варианта триангуляции, зависящих от того, какие углы соединить. В случае с моделью, разбитой на четырехугольники, мы просто оставляем выбор варианта за софтом. С одной стороны, в этом нет ничего плохого. Карта нормалей спокойно компенсирует артефакт триангуляции. С другой...


Чтобы обнаружить скрытую угрозу, предлагаю вручную триангулировать наш объект в обоих вариантах:

Работа над ошибками в 3D. Эпилог. Запечка лавочек. ч.2 3D, Gamedev, Длиннопост

Теперь давайте запечем нормалку. Берем high poly:

Работа над ошибками в 3D. Эпилог. Запечка лавочек. ч.2 3D, Gamedev, Длиннопост

Запекать мы будем на low poly с триангуляцией варианта 1. Включаем текстуры, смотрим на low poly с вариантом 1:

Работа над ошибками в 3D. Эпилог. Запечка лавочек. ч.2 3D, Gamedev, Длиннопост

Идеально. Как и предполагалось, карта нормалей отлично компенсировала искажения, все поверхности ровные, все хорошо. Но теперь давайте используем ту же карту нормалей в low poly со вторым вариантом триангуляции:

Работа над ошибками в 3D. Эпилог. Запечка лавочек. ч.2 3D, Gamedev, Длиннопост

Для тех, кто по прежнему не до конца понял суть проблемы, давайте расскажу. Когда вы работаете с моделью, состоящей из четырехугольников, вы оставляете за софтом право самостоятельно распоряжаться триангуляцией. И софт это делает. Например, вы подготовили low poly, high poly и решили все это запечь. В этот момент софт фиксирует свой вариант триангуляции и компенсирует те нормали, которые он сам и решил. Потом наступает момент, когда вы выгружаете модель в движок. А вот мнение движка по поводу того, как будет выглядеть триангуляция, может разительно отличаться от мнения 3D софта. И, в этом случае, в движке мы получим то, что видим на последнем скриншоте. Артефакты. Тут может помочь только ручная ретриангуляция объекта, что в случае с ассетами на десятки тысяч полигонов может свести вас с ума.


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


Некоторые товарищи, кстати, любят накинуть компенсирующие лупы на low poly перед запеканием, а после со спокойным сердцем их удалить. Так вот. Делать этого не нужно. Любая коррекция сетки после запекания приведет к неверной компенсаци нормалкой. В итоге, объект будет выглядеть не так, как вы запланировали изначально.


Теперь давайте перейдем к вертексным нормалям. Это еще один из столпов правильного шейдинга.


Для разбора возьмем следующий объект:

Работа над ошибками в 3D. Эпилог. Запечка лавочек. ч.2 3D, Gamedev, Длиннопост

На нем, по-прежнему, используется одна smooth group. Давайте отключим сетку и посмотрим, как шейдится наш объект.

Работа над ошибками в 3D. Эпилог. Запечка лавочек. ч.2 3D, Gamedev, Длиннопост

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

Работа над ошибками в 3D. Эпилог. Запечка лавочек. ч.2 3D, Gamedev, Длиннопост

Давайте взглянем на получившуюся карту нормалей:

Работа над ошибками в 3D. Эпилог. Запечка лавочек. ч.2 3D, Gamedev, Длиннопост

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


Ответ кроется в настройке вертексных нормалей. Давайте включим их отображение на нашем объекте:

Работа над ошибками в 3D. Эпилог. Запечка лавочек. ч.2 3D, Gamedev, Длиннопост

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

Работа над ошибками в 3D. Эпилог. Запечка лавочек. ч.2 3D, Gamedev, Длиннопост

Шейдинг low poly при такой настройке будет выглядеть следующим образом:

Работа над ошибками в 3D. Эпилог. Запечка лавочек. ч.2 3D, Gamedev, Длиннопост

А нормалка станет выглядеть вот так:

Работа над ошибками в 3D. Эпилог. Запечка лавочек. ч.2 3D, Gamedev, Длиннопост

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

Работа над ошибками в 3D. Эпилог. Запечка лавочек. ч.2 3D, Gamedev, Длиннопост

Эпилог


Ну, вот, пожалуй и все. Вроде, я рассказал все, что планировал. За время написания этих постов на меня подписалось 270 человек. Довольно неплохое число, учитывая "непрофильность" ресурса. Как бы то ни было, мне очень приятно, что тема интересна большому количеству людей. Это значит, что желание развивать свои навыки у кого-то да есть. Простите, что иногда посты не были структурированы, что приходилось подолгу их ждать, что чукча, в конце концов, не писатель) Надеюсь, что из этих 270 человек, хотя бы двое будут использовать мои советы в своих работах, а главное продолжат искать новые знания везде, где только можно и станет рано или поздно крутым 3Dшником.


Серия "Работа над ошибками в 3D" завершена, но я с удовольствием отвечу на интересующие вас вопросы, которые вы зададите в комментах, ибо я по прежнему остаюсь пикабушником)


Огромное вам всем спасибо за внимание! Любите то что вы делаете и стремитесь делать это хорошо!


С уважением, Fajargo. Специально для Pikabu

Показать полностью 15

Работа над ошибками в 3D. Часть 7. Запечка Лавочек. ч.1

И, наконец-то, здравствуйте, товарищи!


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


В этот раз я не буду давать ссылки на предыдущие посты (да простят меня SMM-щики). Если вас интересует данная тема, просто заходите в мой профиль. Там вы без труда найдете все, что я успел написать. И, если вы не знакомы с моим "творчеством", то перед прочтением этого поста рекомендую ознакомиться с предыдущими. Многое станет понятнее.


Полетели!


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


Начать разбор данной темы мне бы хотелось с ответа на вопрос в комментарии в одном из предыдущих постов:


"Тогда хотелось бы что бы рассказали про нужность запека нормалей. Множество людей сейчас бездумно лепят хайполи, и после пекут нормали и др по 4 к в саб пайнтере и довольные кичится, не думая о том, что 1 такая текстура забивает 10% памяти даже топовой видеокарты. При этом если посмотреть на модели (в частности пропсы) от больших компаний(тот же Дайс, 4a games), то на пропсах будут заметно, что никто им не делал уникальную юв и никто не пек нормали. Это просто проекция куба для юв и 1 материал для всех пропсов деревянного, металлического или др. типа. Единственные места, где были запеки - это оружие и персонажи, те то, что всегда в кадре.
Так хотелось бы услышать где и когда нужно печь карты, а когда лучше избежать этого, когда лучше сделать фаски, а когда лучше избежать и того и другого."


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


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


Запомним это. Чуть позже мы вернемся к каждой их этих категорий.


Теперь нам необходимо вспомнить еще один важный аспект: нормаль - это не волшебство, а конкретный параметр, который содержит любая геометрия и без всяких текстурных карт. При этом карта нормалей служит только лишь для передачи информации о нормалях от high poly к low poly. Для большего понимания моей писанины вот вам картинка:

Работа над ошибками в 3D. Часть 7. Запечка Лавочек. ч.1 3D, Gamedev, Длиннопост

Как мы видим, серьезных отличий в отображении данных объектов не заметно даже при учете того, что low poly не использует карту нормалей. Нам достаточно "родных" нормалей объекта. Для того чтобы еще лучше продемонстрировать свою мысль, я покажу вам карту нормалей, которая получится, если мы запечем наш high poly:

Работа над ошибками в 3D. Часть 7. Запечка Лавочек. ч.1 3D, Gamedev, Длиннопост

Кроме еле заметных полос на гранях мы видим совершенно чистую карту нормалей. Говорит это о том, что в данной ситуации использовать "нормалку" вообще бессмысленно. И без того сомнительная выгода от ее использования начисто стирается весом карты и ресурсами на ее просчеты.


Возвращаясь к вопросу, с которого мы начали, мы видим, что в данной ситуации мы с легкостью можем "положить" на использование формообразующей "нормалки". Это сэкономит нам кучу нервов, времени и ресурсов при итоговой оптимизации.


Плюс это освобождает нам руки при повторном использовании фактурных материалов. Есть ли смысл уникально запекать каждое здание, если один и тот же материал кирпичной кладки мы используем на 30% архитектуры  уровня? Нет. Есть ли смысл плодить кучу материалов, ссылающихся на одну и ту же по сути текстуру, если мы можем использовать один? Нет.


Отсюда-то и возникает вывод. Многие начинающие артисты упираются в паплайн: UV, затем бейкаем, затем текстурим. При этом профессиональный пайплайн с легкостью и без зазрения совести подгоняет UV нового объекта под бесшовный материал, а зачастую и под уникальный материал другого ассета, если на некоторых участках объекта текстура повторяется. Работа с "реальными" нормалями может сильно упростить жизнь при оптимизации проекта.


Тут стоит сделать небольшое отступление и поговорить о внесении разнообразия в ассет, который использует "чужие" текстуры. Тут существует два пути. Первый - это использование смешения материалов за счет vertex color. Этот путь используется преимущественно в архитектуре. Более подробно можно об этом посмотреть тут:


http://www.gdcvault.com/play/1023965/Building-Beauclair-Capi...


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


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


И еще одно крохотное отступление: да, использование текстур от другого ассета вызывает больше draw call, да, прозрачность - это дополнительная нагрузка на видеокарту, да, добавление плашек с декалями повышает количество вертексов на объекте. Да, вы видели статью/ролик, что в 2007 году такой херни геймдевелоперы себе не позволяли. И, все же, в реальной работе вам всегда приходится искать оптимальное решение для каждого ассета. Нет никаких точных директив, как поступать в том или ином случае. Поиск баланса - это ваша основная задача. Точка.


Закончив с лирикой, вернемся к основной теме и закончим с формообразующей картой нормалей. Следующим аспектом формообразования являются более сложные объекты. Давайте вспомним наш высокополигональный чеснок. Чеснок является довольно сложным объектом с точки зрения формы. При этом потратить на него много полигонов мы не можем. Значит, вывод прост: печём? Но, нет. Тут стоит вспомнить, по какой причине мы не выделяем на него много полигонов. Никто этот чеснок в отрыве от общих декораций не увидит. Никому нафиг не нужны его плавные формы, а значит, и тратить ресурсы на нормалку мы тоже не будем. Вообще, отличным примером подобных решений по отказу от использования всего и вся является Ведьмак 3. Серьезно. После прочтения статьи поиграйте в него, рассмотрите нюансы окружения. Нет нормалки на половине ассетов? Ага. Неприкрытые hard edges то тут то там? Ага) И чем дальше в лес, тем шире жопа) Однако. Вспомните свои первые впечатления от картинки Ведьмака. Не знаю как у вас, а у меня было что-то вроде:

Работа над ошибками в 3D. Часть 7. Запечка Лавочек. ч.1 3D, Gamedev, Длиннопост

А теперь вспомните, что бюджет на разработку Ведьмака 3 в два, а то и в три раза меньше, чем большинства ААА игр. Этим, кстати, многие любили тыкать в самых крутых издателей. Так вот, как мы видим, снова никакой магии. Время = деньги. И чем меньше денег, тем меньше времени. Времени на разработку движка, который смог бы лучше оптимизировать ресурсы игры, времени на создание контента, плюс необходимость повторно использовать все и вся. И мое почтение CD Projekt: свои силы они сконцентрировали в очень правильном направлении, не раскидываясь своими ресурсами на детализацию того, на что игрок вообще не посмотрит, при этом, усиливая общие эффекты, отвлекая игрока от того, что сделано посредственно.


Что-то меня снова унесло в сторону) Давайте же подытожим. Если говорить о формообразующей нормалке, то реальная необходимость ее использования появляется только на основных ассетах (персонажи, оружие и т.п.) и на более-менее крупных объектах со сложной формой. В остальных случаях лучше обойтись без нее и сконцентрироваться на фактуре. К ней и переходим.


Конечно же, вы можете сказать, что уж при создании фактуры нам никак не обойтись без нормалки. Но не торопитесь. Говоря о фактуре и рельефе, мы на радость олдфагам переберемся в старые добрые времена, когда о карте нормалей (да даже о примитивном bump) в игровой индустрии только мечтали. Зачем? Давайте по порядку.


Начнем с PBR. Уверен, что большинство знают, что это (если нет, то прям немедленно в гугл!!!), однако, нас интересует одно из основных отличий PBR от "классической" схемы рендеринга и текстуринга. Заключается оно в карте цвета. Фишка в том, что в отличие от классической карты цвета в PBR используется Diffuse (Albedo) или Base Color. Единственная информация, которую несут эти карты - это, как вы поняли, цвет. Никаких бликов, затенений и тому подобной шелухи. Все вышеперечисленное уже формирует шейдер на основании информации с нормалки, specular, roughness, AO и т.д. Классическая же карта цвета несет в себе всю информацию не только о цвете, но и о свете (речь не о тенях, но о некоем аналоге specular + AO). Т.е. то, что PBR решает с помощью кучи карт, "классика" решает одной. Конечно же, с помощью классики вы не получите фотореалистичный результат при динамическом освещении, но есть одна область, в которой классика до сих пор ощущает себя прекрасно и вольготно. Речь, конечно же, о мультяшной стилизации. Тут вступают в силу те же приемы, что и в живописи. Ведь увидеть рельеф и глубину на картине вы можете, несмотря на наличие одной лишь карты. Собственно, карты цвета. Так же и здесь. Знаменитая Blizzard, если мне не изменяет память, до Overwatch вообще не использовала карту нормалей. А многие современные игры начали использовать стилизацию (хотя многим это не нравится), несмотря на то, что PBR достиг невероятных высот. Почему же? Ответ у нас в кармане. С появлением смартфонов и первых 3D игр на них вопрос жесточайшей оптимизации стряхнул с себя пыль и с новой силой начал косить нервы разработчиков, которые хотели ворваться на этот молодой на тот момент рынок. Вес игры из второстепенного параметра превратился чуть ли не в основной. Ибо мало кому придет в голову скачивать игру весом 5-6 Гб на свой мобильник. Тут-то и пришлось вспомнить старые дедовские методы. И, как выяснилось, это было отличным решением. Одна карта вместо 4-5. Прекрасно. По ходу вскрылся еще один крайне интересный нюанс. Стилизация стареет гораздо медленнее, чем игры со сверхреалистичной графикой. Этот факт в дальнейшем сподвиг многих на сочетание стилизованной картинки и PBR шейдера.


Все это словоблудие, в общем-то, призвано для одной простой цели. Поселить в вас мысль о том, что порой оптимизация закладывается в игру на самых ранних стадиях. Выбор стилистики - это не просто вопрос восприятия картинки игроком, формирования атмосферы и т.д. Это еще и простой технический вопрос. Как сделать картинку лучше, используя меньше ресурсов.


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


Спасибо за внимание!

Показать полностью 3

Работа над ошибками в 3D. Часть 6. UV. Глава 2

Привет!


Часть 1

Часть 2

Часть 3

Часть 4

Часть 5.1

Интермеццо

Часть 5.2

Часть 6.1


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


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


1. Мы должны сохранить эталонную плотность текселя в заданных рамках. Тут пояснения, думаю, излишни.

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

3. Мы должны добиться минимального растяжения текселя по поверхности объекта. Тут все просто. С растянутым текселем неудобно работать, и он может давать неприятные артефакты при текстурировании.

4. Мы должны максимально заполнить выделенное для модели UV пространство. Незаполненное UV пространство - это вес текстурных карт, который занимает место в памяти просто так.

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


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


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


Но, прежде чем приступать к нарезке UV, нам стоит разбить наш объект на группы сглаживания. Так как нам стоит помнить: где на объекте hard edge, там должен быть разрез UV.


А как же поступить с теми объектами, на которых нет hard edge, как, например, цилиндры или органические объекты? Тут вступает в действие еще одно правило: шов UV должен быть спрятан от глаз игрока. Связано это с тем, что идеально положить текстуру на стык практически невозможно, особенно в случае со сложным материалом. Да, мы можем постараться замаскировать шов вручную, но это займет много времени, а значит, швы нужно прятать так, чтобы возиться с ними не приходилось. Ведь, если сам шов никто не увидит, то и не придется заморачиваться с подгонкой текстуры. То, куда вы спрячете шов, целиком и полностью зависит от объекта, с которым вы работаете. Если один объект частично перекрывает другой, то в месте перекрытия будет отличное место для шва. В случае с органикой - то же самое. Режем в тех местах, куда камера не доберется, а если и доберется, то будет это делать редко.


Еще хотелось бы сказать про места стыка. Но тут лучше показать. Предположим, у нас есть вот такой объект:

Работа над ошибками в 3D. Часть 6. UV. Глава 2 3D, Gamedev, Длиннопост

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

Работа над ошибками в 3D. Часть 6. UV. Глава 2 3D, Gamedev, Длиннопост

Следующим заслуживающим освещения моментом является растяжение.

Давайте возьмем сферу и пустим шов по экватору:

Работа над ошибками в 3D. Часть 6. UV. Глава 2 3D, Gamedev, Длиннопост

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

Работа над ошибками в 3D. Часть 6. UV. Глава 2 3D, Gamedev, Длиннопост

Как мы можем видеть, он растянут, и имеет уже не форму квадрата, как должен, а довольно сильно вытянутого ромба. Приведет это, очевидно, к тому, что наличие шва станет видно невооруженным взглядом. Да и замаскировать его станет еще сложнее. Работать с таким текселем сложно, муторно и долго. Не всегда у вас будет возможность полностью избавиться от растяжек, но старайтесь компенсировать данный момент. Сделать это можно, разрезав сферу на полюса и экватор:

Работа над ошибками в 3D. Часть 6. UV. Глава 2 3D, Gamedev, Длиннопост

Как можно заметить, проблема не ушла полностью, но стала менее очевидной. Можно поступить еще более радикально. Порезав сферу на ровные куски:

Работа над ошибками в 3D. Часть 6. UV. Глава 2 3D, Gamedev, Длиннопост

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


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

Работа над ошибками в 3D. Часть 6. UV. Глава 2 3D, Gamedev, Длиннопост

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

Работа над ошибками в 3D. Часть 6. UV. Глава 2 3D, Gamedev, Длиннопост

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


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


Теперь давайте перейдем к оверлапам. Пожалуй самая часто обсуждаемая тема, когда вопрос касается UV.


Для начала стоит разобраться с тем, стоит ли оверлапить и когда стоит это делать. С технической стороны вопроса оверлап обычно не доставляет никаких проблем. Если мы не можем уложиться в нужное разрешение текстуры без оверлапов, значит можно оверлапить. Если мы можем сократить разрешение текстуры, значит можно оверлапить, если остается свободное пространство, значит можно оверлапить (но вот конкретно о последнем случае чуть дальше). С визуальной же стороны оверлапнутая часть теряет индивидуальность. Она будет выглядеть как копия. Поэтому в идеале не стоит оверлапить части, расположенные слишком близко, и которые игрок сможет разглядеть в одном кадре. Так же не стоит оверлапить часто повторяющиеся объекты в один шелл. Лучшим решением станет разбить эти объекты на несколько групп. В этом случае мы сможем сэкономить пространство UV, но при этом добиться разнообразия этих объектов. Примером этого может стать деревянный забор, звенья цепи и т.д. Иногда проблема индивидуальности решается декалями или использованием дополнительной текстуры на втором UV канале.


Лично я бы разделил методы оверлапа на 3 категории:


1. Полный (зеркальный) оверлап. В этом случае мы просто оверлапим шеллы одинаковых объектов или их частей. Как, например, в случае со звеньями цепи или стенками деревянного ящика. Иногда для этого нужно отзеркалить (флипнуть) шелл, если в свою очередь отзеркалены элементы объекта, которые мы планируем оверлапить. Тут, надеюсь, все понятно и без скриншотов.


2. Частичный оверлап. Чуть менее очевидная категория. По сути, отличается от полного оверлапа тем, что мы можем уменьшить количество швов UV. Давайте посмотрим на следующий объект:

Работа над ошибками в 3D. Часть 6. UV. Глава 2 3D, Gamedev, Длиннопост

По идее, ничто не мешает нам оставить весь этот объект одним шеллом. Но, если вдруг нам нужен оверлап, то в данной ситуации можно поступить так:

Работа над ошибками в 3D. Часть 6. UV. Глава 2 3D, Gamedev, Длиннопост

Если по скриншоту не совсем понятно, что я сделал, объясню. Левый и правый уголок одинаковы по форме. Я отрезал на UV левый уголок, флипнул его и положил на правый. При этом правый уголок и центральная (уникальная часть) остались единым шеллом.


3. Оверлап разных объектов. Самая неочевидная категория, но, пожалуй, самая интересная. Для пояснения возьмем такой объект:

Работа над ошибками в 3D. Часть 6. UV. Глава 2 3D, Gamedev, Длиннопост

Между делом хочу обратит ваше внимание на нюанс, который я упоминал в предыдущем посте. У этого объекта есть дно, которое мы не видим. А теперь посмотрите на UV нашего объекта. Шелл дна выделен красным цветом (я специально его флипнул для наглядности). И он, как вы можете видеть, занимает меньше места, чем верхняя часть короба (большой квадрат). Т.е. я уменьшил тексель части объекта, которая не видна зрителю. Я не потерял качества итогового изображения, но сэкономил UV пространство.


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


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

Работа над ошибками в 3D. Часть 6. UV. Глава 2 3D, Gamedev, Длиннопост

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

Работа над ошибками в 3D. Часть 6. UV. Глава 2 3D, Gamedev, Длиннопост

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


Конечно, есть еще несколько видов укладки UV, но они чересчур "экзотичны", и используются они крайне редко, чтобы забивать ими сейчас ваши головы.


Ну, и последнее, что мне хотелось бы рассказать об укладке UV, так это то, что не стоит всегда стремиться уложить все в квадрат. Если звезды (тексель, плотность, оверлапы, форма объекта, количество швов - вся вот эта хрень) сошлись так, что все шеллы спокойно укладываются только в половину квадрата, то не стоит этого бояться. Работайте с половиной. Прямоугольные текстуры почти всегда допустимы к использованию (уточните эту информацию у вашего лечащего движка :) В работе будет использоваться полупустая квадратная текстура, а перед загрузкой в движок текстура обрезается, а UV растягивается так, чтобы получить квадрат. Это связано с тем, что движки в любом случае растянут текстуру в квадрат (к большему значению (т.е. 1к*2к движок преобразует в 2к*2к). И наша UV должна будет соответствовать растянутой текстуре).

Работа над ошибками в 3D. Часть 6. UV. Глава 2 3D, Gamedev, Длиннопост

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


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


Спасибо за внимание, всем удачи и до встречи)

Показать полностью 14

Работа над ошибками в 3D. Часть 6. UV. Глава 1

Привет!


Часть 1

Часть 2

Часть 3

Часть 4

Часть 5.1

Интермеццо

Часть 5.2


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


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


Для начала давайте разберемся с одним из основных понятий, которое нам пригодится.


Тексель. Большинство из вас о нем слышало. Я даже думаю, что многие знают, что это.

"Чем больше тексель, тем лучше текстура" - именно на этом утверждении, с которым я в общем и целом не могу не согласиться, большинство и останавливается, не углубляясь в область применения данного термина.


Давайте прежде всего дадим определение текселя. Тексель - это пиксель в текстуре трехмерного объекта. Чем он отличается от пикселя? Тем, что при выводе изображения один пиксель на текстуре может занимать несколько пикселей на мониторе, и, таким образом, тексель не равен пикселю итогового изображения. Но, если говорить о текстуре меша, то тексель - это пиксель в том понимании, в котором мы его знаем. Теперь разберемся еще с одной вещью. В индустрии 3D небрежным словом "тексель" привыкли называть не сам тексель, а плотность текселей на текстуре. А плотность текселя  - это, в свою очередь, количество текселей на единицу реального размера объекта. Для понимания смотрим на скриншот:

Работа над ошибками в 3D. Часть 6. UV. Глава 1 3D, Gamedev, Длиннопост

Если сторона квадрата равна 1 см, то плотность текселя будет равна 5 пикселям на 1 см. Думаю многие из вас (особенно те, кто работает в PS) встречали обозначение ppi. Так вот ppi - это ни что иное как pixel per inch, т.е. пискель на дюйм.


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


Прежде чем приступать к производству ассетов, любой разработчик определяет средний тексель объектов в игре. Чаще всего все ассеты разделяются на категории по принципу того, как с ними будет взаимодействовать игрок и как близко они смогут оказаться к камере. Каждой из этих категорий будет назначена эталонная плотность текселя. Например, в шутере от первого лица плотность текселя на оружии будет выше, чем, например, у врагов или окружения. А вот в RTS типа StarCraft тексель будет более-менее равномерным для всех объектов.


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


Стоит уделить внимание основному правилу, касающемуся плотности текселя:

На мониторе игрока плотность текселя должна быть равномерной.


Для понимания этого правила давайте разберем пример:

Работа над ошибками в 3D. Часть 6. UV. Глава 1 3D, Gamedev, Длиннопост
Работа над ошибками в 3D. Часть 6. UV. Глава 1 3D, Gamedev, Длиннопост

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


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


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


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


Теперь, после "краткого" знакомства с плотностью текселя, настало время понять, как он связан с UV.


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


Так вот, всё ваше непреодолимое желание сделать "4К текстуры на вон той коробке шоб все ах*ели от графона" можете выбросить. Ибо разрешение текстуры определяется именно текселем и ничем иным. Для примера давайте определили наш эталонный тексель как 1 пиксель на 1 юнит (см, м, дюйм - без разницы). После этого мы создаем объект. В нашем случае для очевидности объектом будет квадратная плоскость со стороной, равной 15 юнитам. А теперь давайте накинем на него текстуру 8*8 пикселей:

Работа над ошибками в 3D. Часть 6. UV. Глава 1 3D, Gamedev, Длиннопост

Как мы видим, наш объект попросту не помещается в основную UV область. А значит, нам придется уменьшать UV шелл, а значит, плотность текселя уменьшится и сильно отойдет от эталонной. В утиль. Пробуем текстуру 32*32:

Работа над ошибками в 3D. Часть 6. UV. Глава 1 3D, Gamedev, Длиннопост

Таааак. На сей раз на UV остается слишком много свободного места. Это, как мы понимаем, тоже плохо. Ибо карта текстур, оттого что мы ее займем лишь частично, весить меньше не станет. В утиль. Наверное, стоит взять что-то среднее? Как насчет 16*16:

Работа над ошибками в 3D. Часть 6. UV. Глава 1 3D, Gamedev, Длиннопост

Иииии, да! Это как раз то что нам нужно.


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


Но, разрешение - это разрешение, текстура - это текстура. UV то тут, блин, при чем? И, для того, чтобы связать всю эту информацию воедино, нам понадобится пригласить нашего следующего друга. Встречайте, padding.


В дословном переводе это слово обозначает набивку. Однако, в 3D софте этот термин обозначает простой и понятный "отступ".


Для объяснения данного термина в 3D позвольте напомнить вам об одном случае, которые мы разбирали в предыдущем посте:

Работа над ошибками в 3D. Часть 6. UV. Глава 1 3D, Gamedev, Длиннопост

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


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


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


И, наконец, с шеллами, лежащими вплотную друг к другу попросту неудобно работать.


Теперь перейдем к тому, как правильно определить необходимый паддинг.

Стандартным значением является отступ в 2-3 пикселя. Именно отступ от одного шелла. Т.е. между границей шелла и границей UV пространства должно быть 2-3 пикселя. Между границами двух шеллов 4-6 (по 2-3 от каждого из них). Это значение не меняется в зависимости от разрешения карты. Так, отступ в 2-3 пикселя в 1024*1024 останется таким же и в 2048*2048.


Однако, есть одно важное замечание. Если вы впоследствии планируете сжимать карту текстур (например, для лодов), то стоит отталкиваться именно от минимального разрешения. Так, если минимальная текстура объекта будет 128*128, а рабочая текстура 512*512, то отступ должен составлять 2-3 пикселя*4 = 8-12 пикселей.


Вот пример правильного отступа:

Работа над ошибками в 3D. Часть 6. UV. Глава 1 3D, Gamedev, Длиннопост

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


А пока всем удачи и спасибо за внимание!

Показать полностью 8

Работа над ошибками в 3D. Часть 5. Сгладь меня полностью. Часть 2.

И вновь доброго вам всем любого времени суток на ваш выбор!


Часть 1

Часть 2

Часть 3

Часть 4

Часть 5.1

Интермеццо


Сегодня, как я и обещал (и даже планирую сдержать свое обещание), мы займемся разбором Smooth groups. Для начала я очень быстренько исправлю свою ошибку по теории из предыдущей части, а потом сразу же погрузимся в мир практики. Никаких внезапных душеизлияний, никакого занудства. Только примеры, только картинки, только хардкор! Полетели!


*ага... полетели... опять теория*


В случае, когда у нас используется одна группа сглаживания, наш софт пытается отобразить его так, будто объект сглажен (здорово, правда?)


Так вот тангент - это плоскость, касающаяся кривой в одной точке. Касается эта плоскость именно кривой, которая определяется сглаженным объектом. Смотрим:

Работа над ошибками в 3D. Часть 5. Сгладь меня полностью. Часть 2. 3D, Gamedev, Длиннопост

На скриншоте отчетливо видно, что тангент на несглаженной модели соответсвует тангенту на слаженной. Однако, его местоположение по оси Y отличается. И именно относительно этого тангента сглаженной модели будет запекаться карта нормалей. Более отчетливо это станет видно в разборе примеров. И ими-то мы сейчас и займемся.


Первым делом мы возьмем один и тот же объект в четырех вариациях.


Вот этот объект:

Работа над ошибками в 3D. Часть 5. Сгладь меня полностью. Часть 2. 3D, Gamedev, Длиннопост

Мы поставим эксперимент со следующими его вариантами:


Вариант первый: объект разбит на 2 группы сглаживания (все ребра жесткие - hard), при этом UV также разделена по жестким граням:

Работа над ошибками в 3D. Часть 5. Сгладь меня полностью. Часть 2. 3D, Gamedev, Длиннопост

Вариант второй: объект по прежнему имеет жесткие грани, но на сей раз UV сшита в один шелл:

Работа над ошибками в 3D. Часть 5. Сгладь меня полностью. Часть 2. 3D, Gamedev, Длиннопост

Третий вариант имеет одну группу сглаживания (все ребра мягкие - soft). UV разделена:

Работа над ошибками в 3D. Часть 5. Сгладь меня полностью. Часть 2. 3D, Gamedev, Длиннопост

И, наконец, четвертый вариант. Это объект с одной группой сглаживания (все ребра мягкие) и единым шеллом UV:

Работа над ошибками в 3D. Часть 5. Сгладь меня полностью. Часть 2. 3D, Gamedev, Длиннопост

Теперь давайте попробуем запечь на каждый из этих объектов карту нормали, используя следующий объект (по сути, тот же, просто с фасками, отбитыми геометрией):

Работа над ошибками в 3D. Часть 5. Сгладь меня полностью. Часть 2. 3D, Gamedev, Длиннопост

В итоге мы имеем следующие результаты:

Работа над ошибками в 3D. Часть 5. Сгладь меня полностью. Часть 2. 3D, Gamedev, Длиннопост
Работа над ошибками в 3D. Часть 5. Сгладь меня полностью. Часть 2. 3D, Gamedev, Длиннопост
Работа над ошибками в 3D. Часть 5. Сгладь меня полностью. Часть 2. 3D, Gamedev, Длиннопост
Работа над ошибками в 3D. Часть 5. Сгладь меня полностью. Часть 2. 3D, Gamedev, Длиннопост

Как мы видим, неудачный результат нас ожидает только во втором варианте. Он, напомню, имеет жесткие грани и один шелл UV. Причину, по которой мы получили такой результат, мы сможем понять, посмотрев на нормалку, которую мы получили при запекании:

Работа над ошибками в 3D. Часть 5. Сгладь меня полностью. Часть 2. 3D, Gamedev, Длиннопост

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


Остальные три варианта запеклись с одинаково качественным результатом. Но прежде чем приступить к дальнейшему разбору, я предлагаю сразу исключить из гонки третий вариант. Тот, который имеет одну группу сглаживания, но UV разделена на три шелла. Поясню, почему мы это делаем. Мы имеем два объекта с одинаковым сглаживанием и одинаковым результатом бейка, но у третьего варианта 3 шелла, а у четвертого - один. В нашей конкретной ситуации мы получили на 4 координаты UV больше. Следовательно, модель при прочих равных будет тянуть за собой больше информации. А значит, будет больше весить, дольше просчитываться и вообще снижать оптимизацию нашей игры. А это прямая дорога в утиль.


До финала добрались два претендента. И чтобы определить победителя, нам нужно посмотреть на те нормали, которые мы имеем.


Итак, претендент номер раз. Грани жесткие, UV разбита:

Работа над ошибками в 3D. Часть 5. Сгладь меня полностью. Часть 2. 3D, Gamedev, Длиннопост

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


Но что же покажет нам второй претендент? Встречайте, грани мягкие, UV шелл один:

Работа над ошибками в 3D. Часть 5. Сгладь меня полностью. Часть 2. 3D, Gamedev, Длиннопост

Тут мы видим менее приятную картину. Почему так получилось? Вспомним следующую картинку:

Работа над ошибками в 3D. Часть 5. Сгладь меня полностью. Часть 2. 3D, Gamedev, Длиннопост

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


Ну заполонил, ну и фиг с ним, скажете вы. Не на нормаль же мы будем смотреть в игре, а на модель. И в целом будете правы. Итоговое качество отличное, UV шелл один вместо трех. Заморочек при разбитии на smooth groups никаких. Кинул одну на всю модель и счастлив. Сплошные плюсы... казалось бы, но есть один неприятный минус.


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

Работа над ошибками в 3D. Часть 5. Сгладь меня полностью. Часть 2. 3D, Gamedev, Длиннопост

В случае с чистой нормалкой "жесткого" объекта мы это делаем без особых проблем:

Работа над ошибками в 3D. Часть 5. Сгладь меня полностью. Часть 2. 3D, Gamedev, Длиннопост

Но вот в случае со сглаженным объектом нас ждет неприятный сюрприз:

Работа над ошибками в 3D. Часть 5. Сгладь меня полностью. Часть 2. 3D, Gamedev, Длиннопост

Как мы можем видеть, добавленный нами элемент отражает свет совсем иначе нежели плоскость, на которой он находится. Он смотрится чужеродным. Причем, в динамике (я не умею делать гифки) дело становится еще хуже. Что и логично. У добавленной детали тангенты при запекании были выставлены правильно и не нуждались в компенсации, а вот наш объект вынужден компенсировать тангенты на всей своей поверхности.


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


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


Объект без карты нормалей должен в целом выглядеть так же как и с картой нормалей, просто в чуть более простом виде. Там, где на модели подразумевается гладкая, ровная поверхность, или поверхность с мягким (!) изгибом, там должен быть soft edge. Если на модели должен быть четкий, очевидный жесткий (!) угол, то там должен быть hard edge.


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


И еще одно правило, вытекающее из предыдущего: где hard edge, там разрез на UV (в обратном порядке необязательно)


Итак, еще раз в упрощенном виде:


Там, где угол меньше 120 градусов, там hard edge. Там, где hard edge, там разрез UV.


Только так. Никак иначе... пока что :)


А уже в следующем посте мы начнем разбирать правила и интересные фишечки при работе с UV.


Всем спасибо за внимание! До встречи)

Показать полностью 18

Работа над ошибками в 3D. Интермеццо

Здравствуйте!


Часть 1

Часть 2

Часть 3

Часть 4

Часть 5.1


Сегодня, как некоторые уже смогли догадаться, мы снова обойдем практические знания стороной. Я прошу прощения у всех, кто подписался на меня (а я был очень удивлен популярности темы) и обещаю вам уже завтра исправиться, выложив новый пост, продолжающий тему Smooth groups. В нем я наглядно покажу, как запекаются различные варианты групп сглаживания, как группы сглаживания тесно связаны с UV, а также исправлю ошибку, которую по неосторожности допустил в информации про тангенты, желая все максимально упростить.


Но сегодня о другом.


Начиная писать эту серию постов, я был искренне уверен, что начинающие 3D художники допускают ошибки в своих работах из-за недостатка опыта и знаний. Думал, что плохая оптимизация моделей связана с тем, что многие просто не знают, как приводить свои модели к тому виду, в котором их можно использовать в играх. Я ожидал разных вопросов, связанных с различными приемами оптимизации в том или ином случае. О, как я ошибался. И в том, что я ошибался, меня убедил один и тот же вопрос, который в различных вариациях попадался в комментариях к каждому посту. И он-то и привел меня к выводу, что немалое число моделеров не оптимизируют свои работы потому что считают, что это... не нужно...


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


Итак, начнем по порядку:


1. После такой оптимизации модель станет выглядеть хуже.


И да, и нет. Во-первых, оптимизация стремится в первую очередь не ухудшить качество, а избавиться от лишнего. Если вертекс/эдж/полигон не привносят ничего в форму, не нужны для упрощения бейка или опоры для адекватной триангуляции (возможно этот вопрос мы затронем), то спрашивается, что он вообще делает на модели? Убрать лишнее - это первостепенная задача любого художника. С давних пор существует правило: идеально - это когда нет ничего лишнего.


Однако, довольно часто приходится именно что "ухудшать" модель.


- Как часто игрок будет видеть в игре этот объект? Два раза? Как часто этот объект будет находиться прямо перед камерой? Никогда? В таком случае выделить на него 10к треугольников - офигенный вариант! - Именно так сказал... ни один арт директор или тим лид, находящийся в своем уме.


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


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


2. Современное железо может потянуть овердохералион полигонов в кадре, так зачем тогда что-то оптимизировать?


По последним данным, собранным с форумов CS:GO, Warface и популярного паблика ВК "Дивайсы настоясчих поцонтрэ", PC среднестатистического пользователя на сегодняшний день представляет из себя машинку, собранную на базе последнего поколения i7, две GF 1080Ti, сдобренный 64 ГБ оперативы и приправленный SSD на терабайтничек. Это, конечно, только в том случае, если вы не нищеброд, который вынужден превозмогать, имея в комплекте всего одну 1080Ti (искренне жаль этих людей).


А теперь серьезно. Даже самый мощный PC в состоянии потянуть работу с 20-40 млн полигонов. Заметьте - работу. Самый простой шейдинг, никаких текстур, никакого сглаживания, никаких анимаций. Просто возможность хоть как-то взаимодействовать с объектом. И назвать эту работу комфортной язык уж точно не повернется. Можно и больше. Но это будет уже просто вывод на экран статичной картинки, а любая попытка взаимодействовать с данным объектом может привести в лучшем случае к необходимости прибегнуть к кнопке Reset.


Целевыми платформами, под которые обычно выделяют технические бюджеты, являются консоли текущего или будущего поколения. Никто не будет делать игру, которую потянет только самый мощный ПК (если вы конечно не Crytek, пусть земля им будет пухом). И заметьте, консоли на порядок слабее топовых ПК, да и большинство игр на них идут всего лишь в 30 кадрах в секунду.


Еще одним важным замечанием будет то, что разработка игр - это командный вид спорта. Игра не состоит из одних только полигонов. Это код, анимации, текстуры, материалы, интерфейс, ИИ, звук и многое-многое другое. И абсолютно все это жрет ресурсы консоли или ПК. И если вы делаете модель для игры, то вы всегда должны помнить о том, что кроме вашей модели в игре будет еще огромное множество всего, что очень бы не хотело, чтобы все мощности ушли на ваш "детализированный чеснок". Идеальной должна стать игра, а не ваша модель. И вам каждый день работы над игрой придется жертвовать чем-то. Большая часть команды - это не Кодзимы, это не Ньюэлы или Вавры. Это люди, чьих имен никто не знает, это люди которые делают чеснок или кружки. Велика вероятность того, что конкретно их модели игрок вообще не увидит.


Железо сделало огромный шаг. Это так. Но давайте взглянем на то, на что реально уходят мощности:

Работа над ошибками в 3D. Интермеццо 3D, Gamedev, Длиннопост
Работа над ошибками в 3D. Интермеццо 3D, Gamedev, Длиннопост

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


3. Зачем запариваться? Сэкономить 2 полигона, но потратить кучу времени.


Запариваться затем, что в этом и заключается ваша работа. По поводу времени. Во-первых, время, потраченное на оптимизацию, изначально учитывается при составлении графиков и бюджетов. Во-вторых, опытный художник отличается тем, что он делает все гораздо быстрее начинающего. В-третьих, подумайте. ААА игры разрабатываются командами, состоящими из 500, а порой и 1000+ человек. И разрабатываются они по несколько лет. И стоят сотни миллионов долларов. Если вы думаете, что все это время они катаются верхом на проститутках по двойным сплошным из кокаина, а за месяц до релиза сидят и "не запариваются", то вы, мягко говоря, заблуждаетесь. Даже на самый небольшой ассет для игры у опытного художника может уйти несколько рабочих дней, а то и недель. Говоря "небольшой", я имею в виду именно что небольшой. Клумбу, лестницу, фонарь. И, уверяю вас, что занимаются они именно тем, что запариваются. И стараются выдать не просто качественный результат, а результат, который позволит игре стать такой, какой ее задумали. Красивой, атмосферной, детализированной.


Если вы придете на собеседование (если!) в Naughty Dog, Ubisoft, EA и скажете им, что запариваться не надо, ведь современное железо - огонь, да и полигонаж не вызывает серьезных просадок ФПС (честно, вы тестили не на самом топовом железе), то в лучшем случае с вами вежливо попрощаются.


Знаете кто не запаривается?

Работа над ошибками в 3D. Интермеццо 3D, Gamedev, Длиннопост

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


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


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


Удачи вам всем. До новых встреч.

Показать полностью 3

Работа над ошибками в 3D. Часть 5. Сгладь меня полностью. Глава 1

И снова привет-привет!


Часть 1

Часть 2

Часть 3

Часть 4


Чтобы сгладить (зацените каламбур) привкус неопределенности после предыдущей темы, нужно срочно пройтись катком по фундаментальным понятиям. А гость сегодняшнего поста - Smooth Groups. Они же группы сглаживания, они же Hard'ы/Soft'ы.


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


Эта часть, кстати, будет разбита на две, так как во время написания стало понятно, что в один пост все не уместить. Прошу понять и простить.


И первым делом узнаем, что такое нормаль. В этом нам поможет старик Гугл:

"Нормаль - это вектор ортогональный касательному пространству" © Википедия


Теперь, после того, как все мы на шаг приблизились к Нобелевской премии по геометрии за 7 класс, нам стоит адаптировать это определение для понимания его работы в 3D софте.

Вообще нормаль в 3D никоим образом не противоречит нормали из курса геометрии. Это по-прежнему вектор. И он по прежнему перпендикулярен касательной поверхности (пространству). Вопрос заключается лишь в том, где начало этого вектора, и где расположена та самая "касательная поверхность".


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

Работа над ошибками в 3D. Часть 5. Сгладь меня полностью. Глава 1 3D, Gamedev, Длиннопост

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

Работа над ошибками в 3D. Часть 5. Сгладь меня полностью. Глава 1 3D, Gamedev, Длиннопост

Как мы видим, сейчас уголок отражает свет и затеняется совсем иначе, хотя геометрия никак не изменилась. Я думаю, что все мы прекрасно знаем, что именно так работают hard/soft edge или smooth groups. Но остается вопрос. Если все точки остались на месте, грани не изменили своего положения, а поверхности ответственно держат форму, то что в таком случае заставило GPU поменять итоговую картинку? Ответ очевиден: где-то спрятан еще один параметр. И имя ему - Vertex normal. И выглядит от следующим образом:

Работа над ошибками в 3D. Часть 5. Сгладь меня полностью. Глава 1 3D, Gamedev, Длиннопост

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

Работа над ошибками в 3D. Часть 5. Сгладь меня полностью. Глава 1 3D, Gamedev, Длиннопост

Внезапно две нормали превратились в одну, направленную куда-то вдаль от грани. По факту, их по прежнему 2, но обе они заняли среднее положение. Но это по прежнему нормали. А мы помним, что нормаль - это перпендикуляр к касательной поверхности. Но касаться данных точек может бесконечное количество поверхностей. Как же наши вертексы определили ТУ САМУЮ поверхность? А вот как:

Работа над ошибками в 3D. Часть 5. Сгладь меня полностью. Глава 1 3D, Gamedev, Длиннопост

Именно эта плоскость и определяет нормали наших точек. Если переместить ее и сделать касательной, то это становится очевидным:

Работа над ошибками в 3D. Часть 5. Сгладь меня полностью. Глава 1 3D, Gamedev, Длиннопост

По этому принципу работают, кстати, опорные лупы. Если мы хотим изменить нормаль, нам нужно изменить плоскость:

Работа над ошибками в 3D. Часть 5. Сгладь меня полностью. Глава 1 3D, Gamedev, Длиннопост

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

Работа над ошибками в 3D. Часть 5. Сгладь меня полностью. Глава 1 3D, Gamedev, Длиннопост

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


Ииииии... Че дальше? - спросите вы. - Ну, образовывают, ну, ок. Чем это нам поможет?

А раз спросите, то наверное настало время рассказать о том, что же из себя представляет карта нормалей. Но нет. Не настало :) Ибо в нашем учебнике по геометрии не хватает еще одного понятия. И имя ему - тангент.


Я не хочу больше мучать вики и постараюсь вкратце пояснить только ту часть, которая нас интересует. Так вот. Плоскость, на которую опирается нормаль, является своего рода системой координат. И нормаль всегда расположена вдоль оси Y в этой системе. Но система координат имеет также X и Z. Ох... простите меня математики... Я правда стараюсь. Давайте включим отображение тангент у нашего объекта:

Работа над ошибками в 3D. Часть 5. Сгладь меня полностью. Глава 1 3D, Gamedev, Длиннопост

Я очень надеюсь, что в общем и целом смысл стал понятен. По сути, любой вертекс кроме своего положения в системе координат вьюпорта лежит еще и в системе координат касательной плоскости. И вот теперь-то можно переходить к карте нормали. Кроме офигительного цвета (серьезно, я прусь от него) карта нормали содержит в себе очень важную информацию. А именно, информацию о том, как тангенты целевого объекта (high poly) отклонены относительно тангент low poly. Собственно, интересный цвет карты нормалей не означает ничего. Гораздо важнее то, что хранится отдельно в каждом канале карты. Каждый канал - это черно-белая карта, где каждый пиксель хранит информацию от 0 до 255 (или от 0 до 1, как удобнее). Собственно, если вы посмотрите на скриншот с тангентами еще раз, то смысл станет понятен. Красный канал отвечает за отклонение по X, зеленый - по Y, синий по Z.


В дальнейшем движок обрабатывает информацию с тангент low poly, сравнивает их с информацией в карте нормалей и только тогда выводит итоговое изображение с "как будто бы высокополигональным" объектом.


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

Показать полностью 9

Работа над ошибками в 3D. Часть 4. И все-таки, она вертится!

Привет!

Новый день, новая тема!


Часть 1

Часть 2

Часть 3


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


Итак, посыл сегодняшней темы: сфера - не всегда то, чем кажется.


Перед нами 3 сферы. На одной пики то... На первый взгляд они мало чем отличаются.

Работа над ошибками в 3D. Часть 4. И все-таки, она вертится! 3D, Gamedev, Длиннопост

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

Работа над ошибками в 3D. Часть 4. И все-таки, она вертится! 3D, Gamedev, Длиннопост

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


Второе отличие - это полигонаж:

Работа над ошибками в 3D. Часть 4. И все-таки, она вертится! 3D, Gamedev, Длиннопост

Как мы видим, куб на голову выше своих соперников с точки зрения бюджета на полигоны. Еще одним его преимуществом является более равномерная сетка. Да, это скорее преимущество для хайполи, но и в лоуполи играет не последнюю роль. В конце концов, ровная сетка позволяет избегать переизбытка полигонов там, где они не нужны. Так же стоит заметить, что бывший куб имеет по экватору 32 грани, в то же самое время сферы имеют лишь 24. Если подогнать сферы под 32 грани, то по полигонажу мы получим еще большую разницу не в пользу сфер.


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

Работа над ошибками в 3D. Часть 4. И все-таки, она вертится! 3D, Gamedev, Длиннопост

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


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


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


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


Оставайтесь на связи, не раcходитесь :)

Показать полностью 4
Отличная работа, все прочитано!