Это норма: что такое карты нормалей и как они работают
На протяжении нескольких лет я пытался разобраться в картах нормалей и в проблемах, которые обычно возникают при работе с ними.
Большинство найденных объяснений было слишком техническим, неполным или чересчур сложным для моего понимания, поэтому я решил попробовать объяснить собранную мной информацию. Я понимаю, что эти объяснения могут быть неполными или не совсем точными, но всё равно попробую.
Первые созданные человеком 3D-модели выглядели примерно так:
Это замечательно, но у такой модели есть очевидное ограничение: она выглядит слишком полигональной.
Наиболее очевидное решение: добавить больше полигонов, сделав поверхность более равномерной и гладкой, вплоть до того, чтобы полигоны казались единой гладкой поверхностью. Но оказывается, для того, чтобы сделать поверхности наподобие сфер гладкими, нужно огромное количество полигонов (особенно сегодня).
Требовалось другое решение, и так были изобретены нормали. (Всё происходило не совсем так, но так проще объяснять и понимать.)
Давайте проследим за линией из центра полигона, перпендикулярной его поверхности. Мы дадим этой линии очень непривычное название: нормаль. Цель нормали — контролировать, куда указывает поверхность, чтобы когда свет отразиться от этой поверхности, она могла использовать нормаль для вычисления получившегося отражения. Когда свет падает на полигон, мы сравниваем угол луча света с нормалью полигона. Луч отражается под тем же углом относительно направления нормали:
Другими словами, отражение света будет симметрично относительно нормали полигона. Именно так работает большинство отражений в реальном мире. По умолчанию лучи света отражаются от всех полигонов совершенно перпендикулярно к их поверхности (как должны это делать в реальной жизни), потому что нормали полигона по умолчанию перпендикулярны к поверхности полигона. Если в нормалях будут пробелы, то мы увидим их как отдельные поверхности, поскольку свет отразится в одном или другом направлении.
Если две грани соединены, то мы можем попросить компьютер сгладить переход между нормалью одного полигона к другому, чтобы нормали постепенно выстраивались в соответствии с ближайшей нормалью полигона. Таким образом, когда свет попадёт ровно в центр одного полигона, то он отразится прямо, в соответствии с направлением нормали. Но между полигонами это направление нормали сглаживается, изменяя отражение света.
Мы будем воспринимать переход как единую поверхность, потому что свет будет отражаться между одним и другим полигоном плавным образом, и между ними не будет пробелов. По сути, свет отражается от этих полигонов плавно, как будто у нас имеется множество полигонов.
Именно этим мы управляем, задавая smoothing groups (3ds Max, Blender) или указывая рёбра как hard или smooth (Modo, Maya): мы сообщаем программе, какие переходы между гранями должны быть плавными, а какие — жёсткими.
Вот сравнение одной сферы из 288 полигонов с жёсткими и плавными переходами:
Потенциально мы можем задать нечто вроде параллелепипеда, чтобы все его вершины имели усреднённые нормали. 3D-редактор будет стремиться сгладить его поверхность, чтобы она выглядела как единая плавная поверхность. Для 3D-редактора это вполне логично, но выглядит очень странно, потому что у нас есть объект, который очевидно должен иметь несколько отдельных поверхностей (каждая грань параллелепипеда), однако программа пытается показать их как одну плавную поверхность.
Именно поэтому в 3D-редакторах обычно есть параметр углов сглаживания: если у нас есть два связанных полигона под углом, превышающем угол сглаживания, то их переход будет плавным, а соединение полигонов под углом меньше угла сглаживания будет жёстким. Благодаря этому крутые углы между поверхностями будут отображаться как разные поверхности, как это и бывает в реальном мире.
Итак, мы использовали нормали для контроля над переходами между гранями модели, но можно пойти ещё дальше.
Так как мы меняем способ отражения света от объекта, можно также сделать так, чтобы очень простой объект отражал свет, как сложный. Это называется картой нормалей. Мы используем текстуру для изменения направления света, отражающегося от 3D-объекта, заставляя его выглядеть сложнее, чем он есть на самом деле.
Примером из реального мира могут служить голограммы, которые раньше вручали в подарок при покупке картофельных чипсов (по крайней мере, у нас, в Испании). Они совершенно плоские, но отражают свет так, как бы это делал 3D-объект, благодаря чему становятся сложнее, чем на самом деле. В мире 3D-графики это работает даже лучше, но всё равно имеет свои ограничения (поскольку поверхность остаётся плоской).
Хоть мы и применяем нормали полигонов для реализации какой-то чёрной магии, на самом деле мы не контролируем сглаживание поверхности модели при помощи нормалей полигонов. Мы используем нормали вершин для контроля сглаживания нормалей. По сути, идея та же, но немного более сложная.
С каждой вершиной может быть связано одна или несколько нормалей. Если она имеет одну нормаль, то можно назвать её усреднённой нормалью вершины, а если несколько — то разделённой нормалью вершины.
Давайте возьмём два полигона, соединённых ребром. Если переход между двумя гранями плавный (если мы указали его как плавный в Maya/Modo, или обе имеют одинаковую smoothing group в Max/Blender), то каждая вершина имеет одну нормаль, которая является средней нормалей полигонов (поэтому она и называется усреднённой нормалью вершины). Важное примечание: до недавнего времени каждый 3D-редактор использовал собственный способ вычисления усреднённых нормалей вершин, то есть карты нормалей, вычисленные в одной программе, в другой могли выглядеть совершенно иначе. Подробнее об этом я расскажу во второй части туториала.
Если переход жёсткий (hard edge или разные smoothing groups), то каждая вершина имеет несколько нормалей: по одной для каждой соединённой вершины, выровненной по их нормалям. При этом между нормалями образуется пробел, который выглядит как две разные поверхности. Именно это называется разделённой нормалью вершины.
Как вы могли догадаться, контроль нормалей вершин очень важен, если мы хотим контролировать карты нормалей. К счастью, нам не обязательно изменять нормали напрямую или даже видеть их, но понимание того, как это работает, поможет вам понять, почему мы выполняем работу именно так и больше разбираться в проблемах, с которыми мы можем встретиться.
При запекании карты нормалей мы по сути говорим программе изменить направление, которому следуют нормали lowpoly-модели, так, чтобы они соответствовали направлению в highpoly-модели; поэтому lowpoly-модель будет отражать свет так же, как highpoly. Вся эта информация хранится в текстуре под названием «карта нормалей». Давайте рассмотрим пример.
Допустим, у нас есть вот такая низкополигональная модель (lowpoly). Плоская поверхность с четырьмя вершинами и настроенными UV, которые программа запекания будет использовать для создания карты нормалей.
И она должна получить информацию о нормалях от этой высокополигональной (highpoly) модели, нормали которой сложнее.
Помните, что мы переносим только информацию о нормалях, то есть UV, материал, топология, преобразования и т.п. к делу не относятся. Проверенное правило: если highpoly-модель выглядит хорошо, то её нормали тоже хороши и вполне должны подходить для запекания.
Программа запекания берёт lowpoly-модель и испускает лучи, следуя по направлениям нормалей lowpoly (именно поэтому нам нужно контролировать нормали lowpoly). Эти лучи имеют ограниченную длину чтобы не получать информацию нормалей от далёких граней (обычно это расстояние называется bake distance или cage distance). Когда эти лучи сталкиваются с highpoly, программа запекания вычисляет, как отразить эти лучи, чтобы они следовали по направлению нормалей highpoly, и сохраняет эту информацию в карту нормалей.
Вот результат запекания для нашего примера:
У нас есть текстура, которую движок использует для изменения нормалей lowpoly, чтобы свет отражался от этой lowpoly-модели так же, как он отражался бы от highpoly-версии. Не забывайте, что это только текстура, которая не влияет на силуэт lowpoly-модели (невозможно изменить способ отражения света от модели, если свет не падает на эту модель).
Хотя понятно, что можно «считать» внешний вид highpoly по внешнему виду карты нормалей, очевидно, что карты нормалей — это не обычные текстуры, потому что они хранят информацию не о цвете, а о нормалях. Также это значит, что карты нормалей нельзя рассматривать как обычные текстуры; к тому же, как мы увидим, они обладают особыми параметрами сжатия и гамма-коррекции.
Можно воспринимать карту нормалей как набор из трёх текстур в оттенках серого, хранящийся в одном изображении:
Первое изображение сообщает движку, как эта модель должна отражать свет, падающий справа; оно хранится в красном канале текстуры карты нормалей.
Второе изображение сообщает движку, как модель должна отражать свет, падающий снизу*; оно хранится в зелёном канале текстуры карты нормалей.
*В некоторых программах свет падает не снизу, а сверху, то есть могут быть «левосторонние» и «правосторонние» карты нормалей. Как мы увидим позже, это может вызывать некоторые проблемы.
Третье изображение сообщает движку, как модель должна отражать свет, падающий спереди; оно хранится в синем канале текстуры карты нормалей. Так как большинство объектов при освещении спереди выглядят белыми, карты нормалей обычно кажутся синеватыми.
Когда мы комбинируем все три изображения в одно, то получаем карту нормалей. Помните, что это объяснение не полностью корректно, но надеюсь, что оно позволит вам понять информацию, хранящуюся внутри карты нормалей, и лучше разобраться, что она делает.
Нормали — это векторы, которые используются для определения того, как свет отражается от поверхности. Их можно использовать для контроля над переходом между гранями (усреднением нормалей соединённых вершин для создания плавного перехода или разделением их для создания жёсткого перехода), но также их направление можно изменять, чтобы lowpoly-модель отражала свет так же, как более сложная модель.
Эта информация хранится в трёх отдельных каналах изображения, и 3D-редактор считывает её, чтобы понять, в каком направлении должна смотреть поверхность модели.
В следующей статье цикла мы поговорим о том, как можно запекать эти детали из highpoly-модели в lowpoly.
- карты нормалей
- запекание нормалей
- 3d-редакторы
- normal mapping
- Работа с 3D-графикой
- Разработка игр
Модификатор Edit Normals и управление нормалями. 3ds Max
Изучая полигональное моделирование, постоянно встречается упоминание о «нормалях». При этом увидеть их нигде не получается. Но благодаря модификатору Edit Normals эти скрытые элементы можно не только увидеть, но и редактировать.
1. Нормали и что они делают
Нормалями обладает каждая точка Vertex объекта. Точка может иметь одну или несколько нормалей. Количество нормалей зависит от числа полигонов, объединенных этой точкой. Нормали влияют на то, как поверхность объекта будет отражать свет.
Положение нормалей можно связать со сглаженностью объекта. Если точка имеет несколько нормалей, то каждая из них будет перпендикулярна одному из прилежащих полигонов. Когда у полигона все точки такие, то он получается жестким и несглаженным.
В случае, если точки имеют одну нормаль, то полигон будет сглаживаться. Причем, такая точка будет сглаживать все прилежащие полигоны, но не целиком.
Именно из-за правильного отражения света объект выглядит сглаженным или неровным даже при малом числе полигонов.
2. Edit Normals
Все указанные действия совершаются в модификаторе Edit Normals. Чтобы им пользоваться, нужно создать любой геометрический объект и перейти в Modify – Modifier List – Edit Normals. В зависимости от объекта и его сглаженности, нормали могут располагаться иначе.
Select By – режимы выбора нормалей.
Normal – выбор каждой отдельной нормали.
Vertex – выбор всех нормалей, принадлежащих одной точке.
Edge – выбор всех нормалей, принадлежащих одному ребру. Если у точки несколько нормалей, то выбираются не все.
Face – выбор всех нормалей, принадлежащих фейсам (Face). Если у точек несколько нормалей, то выбираются не все.
Ignore Backfacing – игнорирование задних нормалей при выделении.
Show Handles – отображение маркеров на вершинах нормалей.
Display Length – значение длины прямой, отображающей нормаль.
Unify – усредняет направление всех нормалей в точке. Общее направление задается относительно прилежащих полигонов. Включение функции Unify/Break to Average усредняет нормали по их среднему направлению. Полигоны в этом случае не влияют.
Break – разделяет одну нормаль на шесть. Все они будут направлены так, чтобы быть перпендикулярными своим полигонам. Включение функции Unify/Break to Average также разделяет нормали, но сохраняет их направление.
Average – инструмент усреднения нормалей.
Selected – устанавливает все выбранные нормали в одно, общее положение.
Use Threshold – установка дистанции. За пределами этой дистанции нормали не будут усредняться, даже если были выбраны. Эта функция полезна, чтобы не перенаправить случайно выделенную нормаль.
Target – усреднение двух нормалей с помощью целевого выбора. Включив функцию Target, нажмите сначала на одну нормаль, затем на вторую. Обе нормали усредняются по общему для них значению.
Pixels – дальность в пикселях между курсором и нормалью. Это значение регулирует точность наведения курсора на нормаль в режиме Target.
Copy Value – копирование направления выбранной нормали.
Paste Value – присвоение скопированного направления новой, выделенной нормали.
Specify – присваивает нормали тип Specified.
Нормали такого типа не учитывают группы сглаживания, присвоенные объекту.
Reset – восстанавливает изначальное положение нормали.
Make Explicit – присваивает нормали тип Explicit.
Нормали такого типа задаются для того, чтобы можно было их перемещать и вращать.
3. Передвижение и вращение нормалей
Нормали, как и другие подобъекты, можно перемещать и вращать. Для этого их нужно просто выделить и воспользоваться инструментом Select and Move/Rotate на панели Main Toolbar. Тип Explicit, необходимый для подобных изменений, будет назначен автоматически.
Редактирование нормалей – инструмент тонкой настройки объекта. Обычно им пользуются косвенно через функцию или модификатор Smooth, через Smoothing Groups. Тем не менее, нормали несут очень важную информацию – способ отображения поверхности объекта. Поэтому даже если не приходится их редактировать, обязательно нужно понимать принцип их работы.
Освойте профессию визуализатора
Научитесь создавать крутые рендеры, панорамы 360, виртуальные туры и анимационные ролики.
Какие бывают нормали, и зачем нужны. Часть первая (Normal map, группы сглаживания, введение в Vertex Normals)
Пикабушник @SuperMopsek в соседнем сообществе (Вот тут) поднял интересную тему — карты нормалей в 3D графике. И даже пошагово показал процесс запекания карты нормалей средствами Blender. Но как показывает практика, такая манера подачи ясна не всем 🙂
Попробую рассказать подробнее, а так же рассказать о некоторых хитростях в использовании нормалей. Используемое ПО — 3DS Max, но принципы общие, и могут использоваться при работе в любом 3D пакете.
-Для чего?
В большинстве случаев, проще использовать некую текстуру, вместо миллионов полигонов (допустим, складочки на футболке ГГ).
— Звучит круто! А как оно работает вообще?
Простыми словами, нормаль — это перпендикуляр к поверхности. По нему движок определяет, под каким углом отражать свет. В случае карт нормалей (normal map), эта информация ложная, текстура хранит информацию о рельефе, которого нет. И плоская поверхность отражает свет так, словно на ней есть неровности. Зачастую подобного «обмана» человеку хватает, чтобы принять низкополигональную модель за что-то более детализированное:
На данной картинке два простых квадрата, но карта нормалей на втором заставляет нас поверить, что это нечто детальное, ведь некоторые участки затенены, а другие бликуют. Аналогично она работает и на более сложной геометрии.
Для создания панелей, заклепок и т.д. (как в примере выше) достаточно простого графического редактора и пары плагинов, но для сложных форм необходим детализированный объект-источник, как в примере у @SuperMopsek со скульптурой.
Источником может служить 3D скан, цифровая скульптура, выполненная, например, в Zbrush и т.п.
— О, круто, печем нормали со всяких крутых штук на полтора полигона и получаем графон, да?
Не совсем. Контуры исходной модели и лоуполи-приемника не полностью совпадают, и на финальной модели возникают искажения. А насколько они будут значительны зависит от нескольких факторов:
1. Чем дальше конкретная точка хайполи находится от лоуполи, тем сильнее искажение. Потому чем плотнее сетка приемника, тем точнее она прилегает к источнику, и тем меньше будет искажений. Но и нагружать компьютер она будет сильнее. Чтобы найти идеальный вариант, проверяйте силуэт лоуполи — включите отображение без освещения (flat color в случае 3DS Max) и покрутите лоуполи и хайполи поочередно, осматривая со всех сторон. Детали, не влияющие на силуэт, полигонами моделировать не нужно, нормалями их можно перенести с минимальными потерями.
2. Не вся информация в нормалях одинаково полезна. Со скруглением на «цилиндрах» справляется разделение на группы сглаживания, и если хотите получить красивые фаски — добавьте на «хайполи» только их. В противном случае получим искажения из-за того, что местами цилиндр-источник отдален от приемника сильнее. С определенного угла выглядит неплохо, но с большинства точек обзора возникают косяки.
3. Вытекает из предыдущего пункта. А нужно ли для вашей задачи вообще возиться с созданием хайполи, или достаточно сгладить неровности с помощью групп сглаживания? Бывает и так.
— Минуууточку, опять упоминаешь группы сглаживания, а это что вообще такое?
А группы сглаживания — тоже результат работы нормалей. Только не текстур, а тех, что хранит сама модель. Дело в том, что каждая вершина хранит в себе информацию о том, куда отражать (vertex normals). А на участках между ними вычисляется среднее значение. Сравните:
На иллюстрации два одинаковых объекта. Но боковая поверхность первого обманывает глаз, т.к. свет отражается под усредненным углом, и в целом картина соответствует цилиндру. Правый же отражает свет вполне честно, и уже явно видно, что в основании лежит многоугольник, а не цилиндр. Такая разница тоже по причине нормалей, только теперь к вершине. Обратите внимание на то, что на левом «цилиндре» их как бы меньше. Просто значения накладывающихся вершин усредняются, если они в одной группе сглаживания, и результат сглаживается. Для работы вручную с группами сглаживания в 3DS Max в EditPoly/EditMesh выделите полигоны , которые должны быть сглажены, и назначьте им незанятую группу во вкладке Polygon Smoothing Group.
Для автоматического сглаживания примените модификатор Smooth, выберите Auto Smooth, затем в Treshold укажите угол между полигонами, начиная с которого поверхности перестают считаться сглаженными.
— А вручную эти нормали к вершинам как-нибудь крутить можно, без этого вашего «smooth»?
Можно, и даже нужно! Таким образом можно добиться поразительных результатов. Но об этом следующим постом, а то этот и так затянулся. А пока превью:
Следующий урок научит вас делать такие вот фаски без запекания, кучи полигонов и искажений от групп сглаживания. И не только этому, разумеется)
P.S. Я в курсе, что сетка неоптимальна, оно только для примера по быстрому накидано, смотрите только на фаски, и как с ними объект реагирует на свет 😉
Normal Map. Практическое руководство
Введение
Данное руководство создано для тех, кто стремится понять тему Normal Mapping. Оно написано как для новых людей в индустрии, так и для более опытных, которые хотят освежить знания по теме. Здесь я постараюсь рассмотреть каждую возможную проблему и предоставить простой и доступный ответ. Надеюсь, что это руководство даст вам все необходимое о Normal Mapping и о том, как его применять. Проблемы с Normal Mapping не должны стоять на пути вашего творчества!
Отдельное спасибо EarthQuake с Polycount за вдохновение на создание этого гайда.
Условия использования
Пожалуйста, уважайте работу автора и не копируйте текст руководства никуда, кроме Polycount, без моего разрешения (Superfranky). Если вы увидели ошибку или хотите что-то добавить, то, пожалуйста, напишите мне на Polycount или отправьте письмо на networkcat2@hotmail.com.
Примечание
Перевод подготовлен специально для школы компьютерной графики XYZ. Некоторые главы, после согласования с автором, были расширены или обновлены для большей актуальности. Следовательно, некоторые части текста могут отсутствовать в оригинальном руководстве. По вопросам перевода пишите на nocstrig@yandex.ru. (Леонид Садеков)
Источники
Помимо оригинального руководства были использованы дополнительные источники информации:
Техническая информация
В данной главе я постараюсь предоставить всю техническую информацию связанную c Normal Mapping , наиболее простым языком, без отвлечения на сторонние темы, которые напрямую не относятся к созданию игровых моделей.
Normal Mapping – это технология, используемая для имитации неровностей поверхности на объекте. Она применяется, чтобы сделать вашу финальную модель более похожей на ее HP (High Poly) версию. С ее помощью можно добить различные детали, которые нельзя передать через геометрию из-за ограничений полигонажа на вашем проекте, и заставить вашу модель выглядеть более скругленной для лучшей передачи освещенности и большей реалистичности.
Карты нормалей – это RGB изображения, где каждый из каналов (красный, зелёный, синий) интерпретируется в X, Y и Z координаты нормалей поверхности соответственно. Красный канал пространства касательных карты нормалей отвечает за ось X (нормали направленны влево или вправо), зелёный канал за ось Y (нормали направлены вверх или вниз) и синий канал за ось Z (нормали направлены прямо от поверхности).
Пространство касательных (Tangent Space)
Прежде чем мы перейдем к моделированию и запеканию, я должен рассказать вам о том, что такое пространство касательных (Tangent Space). Самый распространенный тип карты нормалей, залитый синим цветом и встречающиеся повсюду в интернете, называется картой нормалей пространства касательных (Tangent Space Normal Map).
В мире 3D существует множество координатных систем: мировое пространство, локальное пространство, пространство камеры и т.д. Пространство касательных – очередная координатная система со своим назначением. Она используется ради обозначения текстурных координат для поверхности полигона. Вы уже, вероятно, знакомы с UV координатами. Тогда представьте, что ось X сонаправлена с V, а ось Y с U. Теперь у нас есть координаты модели, представленные в 2D пространстве. Но координатной системе необходима третья ось для существования в 3D пространстве и для этого нам необходима нормаль поверхности (N). В координатах пространства касательных нормаль поверхности отвечает за ось Z в мировых координатах.
На этом изображении представлены мировые координаты внизу слева и координаты пространства касательных, привязанные к полигону, состоящему из двух треугольников
Это изображение позволяет представить координаты на самой распространенной форме – на кубе
Оси U, V и N обозначают направления, в которых их значения изменяются вдоль поверхности, так же как X, Y, Z представляют направления, в которых изменяются их значения в мировых координатах.
Это означает, что мы можем передавать координаты пространства касательных через RGB каналы карты нормалей. Красный канал ответственен за ось U, синий за N, а зелёный за V.
Говоря простым языком, красный канал обозначает лево и право; зеленый — верх и низ; синий – вертикаль от поверхности.
Если вы увидите, что модель с применённой картой нормалей освещается не правильно, притом что используется карта нормалей пространства касательных, то, возможно, шейдеру необходимо передать красный или зелёный канал (или оба) инвертированными. Для этого измените настройки шейдера или вручную инвертируйте соответствующий канал в Photoshop, чтобы темные пиксели стали светлыми или наоборот.
Дело в том, что разные приложения могут также по-разному работать с зеленным каналом и порой, когда возникают проблемы с отображением в определенном приложении, то стоит попробовать инвертировать зелёный канал или, говоря по-другому, сменить DirectX на OpenGL или наоборот. (OpenGL – Y+; DirectX – Y-)
Таблица с ориентацией каналов для разных приложений:
Пространство объекта (Object Space)
Карта пространства объекта используется гораздо реже в игровой индустрии, но, порой, ее использование позволяет решить некоторые проблемы. Дело в том, что она использует ориентацию объекта в мировом пространстве, а это значит, что после запекания карты, модель нельзя деформировать.
Достоинства:
•Легче генерировать карту кривизны
•Слегка улучшенная производительность
Недостатки:
•Нельзя повторно использовать. Разные формы требует разных карт.
•Тайлить или отзеркалить можно только с поддержкой шейдера.
•Трудно добавлять отдельно запеченные детали из-за сильной вариативности цвета.
•Плохо сжимается.
— Чувак, это сложно. Какое мне дело?
Карты нормалей пространства касательных используют особый вид вершинных данных, называемых базисом касательных (tangent basis). Если световые лучи существуют в мировом пространстве, то нормали, хранящиеся в карте нормалей, в пространстве касательных. Когда движок обрабатывает модель с примененной картой нормалей, световые лучи преобразуются из мирового пространства в пространство касательных, используя для этого базис касательных. К этому моменту падающие световые лучи сверяются с направлением нормалей с карты нормалей, что определяет освещенность каждого пикселя объекта. Однако вместо преобразования световых лучей, некоторые шейдеры преобразуют нормали из пространства касательных в мировое. Затем преобразованные нормали сверяются со световыми лучами для создания необходимой освещенности. Конечный способ определяется создателем шейдера, но результат в обоих случаях один и тот же.
Трудности могут возникнуть из-за существования множества разных способов расчета базиса касательных. Это значит, что карта нормалей, запеченная в одном приложении, может отображаться совершенно иначе в другом. Когда рендер (например, игровой движок) обрабатывает вашу модель, шейдер должен использовать тоже пространство касательных, что и приложение для запекания, иначе модель получит некорректное освещение, особенно вдоль UV швов.