Продублированные вершины, лишние вершины, разрывы и разрезы в 3D моделях и артефакты на картах нормалей

В данной статье рассматривается проблема появления продублированных вершин — вершин-паразитов, в частности, образующих дополнительные ребра и/или разрывы в мешах 3D моделей, и способы их устранения.
Для начала – маленькое лирическое отступление.

После импорта модели в игровой движок, например, Unity 3D или Unreal Engine, многие замечали, что количество вершин, указанных в Инспекторе в окне просмотра импортированной 3D модели не соответствует количеству вершин, указанных в 3D редакторе (или по сравнению с заявленным автором 3D модели в одном из магазинов 3D моделей). Почему же так получается?

Все дело в том, что количество вершин модели в игровых редакторах/движках, в частности, в Unity3D, количество нормалей для несглаженных поверхностей (hard-normals) и несоприкасающиеся острова uv развертки  отображают больше вершин, чем есть на самом деле, о чем сказано в статье Меши (Meshes) на сайте Unity3D.

flatcubeblenderunity

На рисунке показан несглаженный куб с uv разверткой в Blender’е (вверху) и импортированный в Unity 3D (внизу). В окне просмотра импортированной 3D модели видно, что импортированный несглаженный куб имеет 24 вершины.

smoothcubeblenderunity

На рисунке показан сглаженный куб в Blender’е (вверху) и импортированный в Unity 3D (внизу). В окне просмотра импортированной 3D модели в Unity (внизу-справа) можно видеть, что общее количество вершин сглаженного куба отличается от общего количества вершин несглаженного куба и равно 14 вершинам, то есть равна количеству вершин на uv развертке.

Таким образом, для сглаженной модели посредством затенения методом Гуро (плавное затенение, Gouraud Shading, Smooth shading) количество отображаемых в Unity 3D вершин (и треугольников) будет зависеть от количества швов uv развертки, так что не стоит добавлять лишних швов на модели, если без этого не обойтись или не является дизайнерской задумкой или способом облегчения текстурирования модели, как в случае, описанном в статье Простое и быстрое раскрашивание рёбер 3D модели в стиле hand painted texturing и мультяшного текстурирования.

3dwithseamsblenderunity

На рисунке показана 3D модель персонажа с uv разверткой созданной в соответствии со швами модели в Blender’е (вверху) и импортированная в Unity 3D (внизу). В окне просмотра 3D модели в Unity можно видеть, что 3D модель имеет 1992 вершины, против 1703 – в Blender’е.

3dnoseamsblenderunity

На рисунке показана 3D модель персонажа с uv разверткой созданной для той же, что и выше 3D модели, но без швов в Blender’е (вверху) и импортированная в Unity 3D (внизу). В окне просмотра 3D модели в Unity можно видеть, что 3D модель имеет 1703 вершины, как и в Blender’е.

Как можно заметить из последних двух рисунков, на количество вершин влияет не только сглаженность и несглаженность 3D модели, но и количество швов развертки, а значит, чем меньше ихх будет, тем лучше.

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

3dflatnoseamsvsseamsunity

На рисунке показаны импортированные несглаженные 3D модели в Unity3D с uv разверткой (вверху) и без uv развертки (внизу): у 3D модели с разверткой – 6483 вершины, а у 3D модели без развертки – 6480 вершин.

Как видно из рисунка, отличие в количестве вершин у несглаженной 3D модели и у сглаженной 3D модели – крайне незначительно. В оригинале (в Blender’е), напомню, 3D модель насчитывает 1703 вершины.

 

Откуда берутся вершины-дубли.

Вернемся непосредственно к теме статьи. Вершины-паразиты, упомянутые в заголовке статьи, и образуемые ими ребра могут появиться в результате использования на 3D модели модификаторов, делящих меш на составные части, как, например, это делает модификатор Edge split. Данный модификатор делает «острыми» ребра, отмеченные соответствующим образом (Ctrl+E ->Mark sharp). По сути, результатом применения модификатора является создание клонов вершин отмеченных ребер с разрывом модели по ребрам, отмеченным как острые, то есть разрываются связи между скопированными вершинами и оригиналами.

beforeandafteredgesplit

На рисунке показана 3D модель сферы до применения модификатора EdgeSplit (вторая слева), состоящей из 482 вершин, и та же самая 3D модель сферы, но уже после применения модификатора (вторая справа), которая теперь насчитывает 546 вершин и состоит из трех мешей.

При экспорте модели даже с непримененными модификаторами, но с выбранным параметром «применить модификаторы» (Apply Modifiers) в меню экспорта, экспортированная 3D модель, будет иметь увеличенное количество вершин (по сравнению с количеством вершин модели до применения модификатора) после ее импорта в 3D-редактор. Если же не ставить флажок напротив применения модификаторов, то дополнительные вершины образованы не будут, но и ожидаемых крутых переходов между поверхностями, разделенным «острыми» ребрами также не будет (как показано на рисунках выше: сфера справа).

sphereunity

На рисунке показана 3D модель сферы без применения модификатора EdgeSplit (слева), 3D модель сферы после применения модификатора EdgeSplit (в центре) и она же с примененным модификаторам, но с разнесенными по вертикали составными частями (мешами).

spherecountblender

На рисунке показана 3D сфера в трех своих ипостасях (слева направо): до применения модификатора, после применения модификатора и после применения модификатора, но меши которой перемещены так, чтобы было лучше видно, что 3D модель “разрезана” после применения модификатора.

spherecountunity

На рисунке показаны те же 3D модели, что и на предыдущем рисунке в Unity3D.

А чем же плохи эти дополнительные вершины и ребра? Во-первых, они нагружают видеокарту. Во-вторых, увеличивают количество островов uv развертки, нагружая видеокарту и центральный процессор при обработке объектов подобного рода. В-третьих, увеличение количества островов uv развертки, в некоторых случаях, усложняет текстурирование 3D моделей в графических редакторах. В-четвертых, при неверном выставлении весов при риггинге продублированным вершинам (для разных костей или одной и той же кости арматуры/скелета одной вершине может быть назначен больший или меньший вес, чем вершине-клону), так что швы 3D модели могут “разойтись” при воспроизведении анимации 3D модели, хоть средствами анимации 3D редактора, хоть средствами Unity3D.

Для полноты эксперимента рассмотрим a) сглаженную сферу, со швом проходящим по экватору сферы; b) несглаженную сферу, со швом проходящим по экватору сферы, как и в предыдущем случае; c) несглаженную сферу, но с двумя разрезами: одним, проходящим по экватору сферы и вторым — чуть выше него; и d) сферу из предыдущего пункта, но сглаженную.

spheresblender

На рисунке показаны сферы a, b ,c и d в Blender’е с uv развертками.

Вот так они выглядят в Unity:

spheresunity

На рисунке показаны сферы a, b ,c и d в Unity3D.

А теперь давайте посчитаем количество вершин в каждой из них после импорта в Unity 3D:

spherescountunity

На рисунке отображены результаты подсчета вершин для каждой из сфер: сфера a – 1876 вершин, сфера b – 514 вершин (514 – 482 = 32 вершины; 32 вершины – разница между количеством вершин у 3D модели и на uv развертке), сфера c – 1876 вершин, сфера d -546 вершин (соответствует количеству вершин 3D модели).

Еще одним аргументом против разрезов в low poly 3D моделях, использующихся в проектах игровых движков, являются возможные артефакты, появляющиеся в месте стыковки «разрезанной» модели. Такие артефакты могут быть связаны с некорректным созданием и использованием карт нормалей, что может привести к образованию затемненных или “засвеченных” областей, светлых/белых полос и «углублений» или «выпираний» в месте разреза.

beforeafteredgesplitandsculpt

На рисунке показаны 3D модели в редакторе 3D редакторе Blender: слева модель персонажа без вершин-дубликатов и дополнительного разреза посередине туловища, в центре – модель с разрезом и примененной старой картой нормалей, справа – высокополигональная 3D модель персонажа, с которой запекалась карта нормалей.

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

newclothesnm

На рисунке: слева показана карта нормалей запеченная для модели персонажа без разреза, справа — “перезапеченная” карта нормалей для 3D модели с разрезом. На карте нормалей справа видно “искажение” нормалей в середине торса персонажа.

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

combinedmodels

На рисунке показаны 3D модели, импортированные в игровой движок Unity 3D: слева -модель персонажа без вершин-дубликатов и дополнительного разреза посередине туловища, в центре – модель с разрезом и примененной старой картой нормалей, справа – модель с разрезом и новой, “перезапеченной”, картой нормалей.

Как видно на приведенном выше рисунке, использовать “старую” карту нормалей на “разрезанной” модели не стоит, если не хотите видеть на своей 3D модели артефакты.

Если различным частям разделенной модели назначены разные материалы (например, один материал — для кожи персонажа, второй – для одежды), то на их стыке могут также появится артефакты (подобные тем, что отображены на рисунке свержу у персонажа, находящегося в центре), даже если карта нормалей была обновлена, разрезы на модели следует создавать в местах, где переход от одной части модели к другой будет не так явно бросаться в глаза. Про назначение и использование разных материалов отдельным мешам 3D модели, также называемое мультиматериалами, а также про плюсы и минусы создания 3D моделей отдельными мешами и использование отдельных 3D моделей для различных частей персонажа, описано в статье Модульные персонажи или как переодеть своего героя. Мультиматериалы в Blender и Unity 3D. Мультитекстуры и как перенести сцену целиком из Blender’а в Unity3D.

Также артефакты (белые и черные точки и линии) появляются в том случае, если края текстуры и/или карты нормалей, наложенной на остров, не выходят за его пределы или выступают на самую малость, чего оказывается недостаточно, например, при выставлении больших значений для «силы» карты нормалей или карты высот/карты смещения. За расширение запеченной карты нормалей за края развертки в Blender’е отвечает параметр “Margin”, который можно найти во вкладке запекания/Bake.

margin

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

3D художники/моделлеры всегда стараются создавать швы моделей в таких местах 3D модели, чтобы спрятать их подальше от глаз игрока (например, на внутренней поверхности ног и рук персонажа там, куда не попадает «взгляд» камеры), поскольку полностью избежать подобных артефактов удается далеко не всегда. Швы 3D моделей стараются всячески завуалировать, например, создавая их с контрастными белыми рёбрами, иногда имитирующими отражение света или потертости на ребрах предмета, появившиеся в ходе его эксплуатации (или как в World of Warcraft, где свет на ребрах моделей имитируется белыми линиями, тем самым выделяя ребра модели). Также для выделения ребер зачастую используют черный цвет, например, для придания персонажам и объектам на сцене мультяшности, в дополнение к использованию Toon шейдера. Один из способов быстрого раскрашивания ребер чёрным или белым цветом описан в упомянутой выше статье.
Помимо случаев с использованием модификаторов, дополнительные вершины могут появиться и в процессе импорта 3D моделей, как в игровой движок, так и в 3D редактор, тот же Blender, 3DS MAX, Maya и другие.

 

Избавляемся от продублированных вершин и разбиения 3D модели на составные меши.

Как же от них избавиться, от этих вершин-паразитов? Рассмотрим вариант, когда персонаж представлен одной 3D моделью, но несколькими мешами. Более подробно про 3D модели и меши вы можете прочитать в статье Артефакты при импорте 3D моделей в игровые движки из 3D редакторов на примере Unity и Blender’а.

В Blender’е войдите в режим редактирования меша, для чего выберите 3D модель Правой Кнопкой Мыши и нажмите клавишу ‘Tab’. Теперь необходимо выбрать вершины-близнецы (оригиналы и клоны) или целиком меши, которым они принадлежат (поместив курсор мыши поверх требуемого меша и нажав клавишу ‘L’). После того, как вы выберете вершины дубликаты и оригинальные вершины, нажмите комбинацию клавиш Ctrl+V, чтобы открыть меню вершин (Vertices), в котором выберите вкладку Remove Doubles.

removedoubles

На рисунке показаны выбранные вершины двух частей 3D объекта и меню удаления/слияния вершин-дублей.

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

verticesremoved

На рисунке показано сообщение, содержащее количество удаленных вершин при слиянии вершин-дубликатов.

Однако будьте осторожны, поскольку данная команда сливает не только вершины, находящиеся в одинаковых координатах, но и вершины, расположенные в непосредственной близости друг от друга, так что существует вероятность «смержить» не только нужные вершины, но и «случайно» оказавшиеся рядом. Если количество полигонов изменилось после слияния вершин-дублей, то это является одним из признаков того, что вы объединили вершины, которые не нужно было объединять (для конкретного рассматриваемого примера), а они просто находились в непосредственной близости друг от друга и являются особенностью геометрии 3D модели. Ошибочно объединённые вершины (а зачастую и не ошибочно объединенные) могут привести к образованию ребер-паразитов и граней-паразитов (паразитных полигонов), о которых чуть ниже.
Какие вершины сольются, а какие нет, определяется близостью их расположения друг к другу и размером 3D модели. Представьте себе, что вы создаете 3D модель микроскопа (или фотоаппарата, или какой-нибудь ныне модной нанодетали) в масштабе 1:1, то вершины такой модели, как вы понимаете, могут располагаться очень близко друг к другу. Решением данной проблемы является создание 3D модели в масштабе, например, 1:10, 1:100 и даже 1:100000, с последующим ее масштабированием до реальных размеров, с использованием обычного инструмента масштабирования (клавиша ‘S’) или при помощи выставления масштаба (Scale) модели в окне свойств (Properties), а именно, в свойствах Объекта, во вкладке “Tansform”. Более подробно про то, за что отвечает параметр Scale и его минусах и плюсах для экспорта 3D моделей, вы можете прочитать в статье про создание водопада в Blender’е для Unity 3D и посмотреть процесс создания водопада в Blender, импорт и анимация в Unity 3D через смещение текстуры и карты нормалей. Включайте свою любимую музыку и смотрите. Для понимания того, как все это делается в Blender’е я включил визуализацию нажимаемых клавиш.

scaleandvertices

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

Помимо вершин паразитов в 3D модели могут присутствовать ребра и полигонные паразиты, которые зачастую появляются при зеркалировании моделей, выдавливании (extrude) полигонов, ребер и вершин, создании новых полигонов и ребер через клавишу ‘F’ и при слиянии вершин, в частности через упомянутое выше удаление вершин-дублей. В этом случае вам придётся вручную исправлять геометрию модели. Обнаружить один из типов ошибок в геометрии, а именно, наличие более двух плоскостей у одного ребра, вам может помочь программа для цифрового скульптинга Sculptris, обзор по которой, вы можете почитать в статье Обзор программы цифрового скульптинга (цифровой скульптуры) Sculptris.

Еще одним способом проверить ошибки в геометрии 3D модели поможет add-on для Blender’а MeshLint.

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

uvbeforeand afterremovedoubles

На рисунке показаны uv развертки одной и той же 3D модели до (слева) и после (справа) удаления вершин-дублей с предварительным фиксированием вершин uv развертки и последующим обновлением развертки.

Если развертка изменилась, то вам, скорее всего, придется перезапечь карту нормалей, затенений и так далее, а также подправить диффузную карту (текстуру) 3D модели или перезапечь ее с другой 3D модели, о чем рассказано в статье про запекание карт, включая диффузную и карту нормалей, с одной 3D модели на другую.

Если с разверткой все в порядке, то экспортируйте 3D модель, например, в формате FBX, для последующего ее импорта в один из игровых движков, предпочитаемых вами. Модель не обязательно экспортировать в один из понимаемых форматов игровым движком Unity 3SD, а импортировать сразу в формате вашего 3D редактора, если Unity понимает его. Поддерживаемые 3D форматы можно посмотреть в руководстве Unity 3D в статье 3D форматы.

 

Автор: Максим Голдобин
goldmaxval@gmail.com

Добавить комментарий