Лицевой риггинг для профессиональной анимации. Часть 1

Всем привет. Меня зовут Жасурбек Бутаев. Я живу в Ташкенте, работаю в компании iLogos, занимаюсь анимацией и риггингом почти 8 лет.



Прошло уже 5 лет с того момента как написал мой первый урок по риггингу. За эти годы появилось желание сделать так же урок по лицевому риггингу. Вам предоставляю этот урок. Надеюсь, что он будет полезен для всех нас. Чуть не забыл, урок будет в Autodesk Maya 2016.

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



План урока:

  1. Голова и шея
  2. Челюсть и рот
  3. Язык и зубы
  4. Глаза и веки
  5. Брови
  6. Нос
  7. Шеки и остальные части
  8. Corrective shape
  9. Squash и stretch
1. Голова и шея

Прежде чем зариггать и заскиннить, почистим нашу модель. (01.mb) (01.mov) Для этого выделим всю геометрию в Outliner, и нажмём на Edit>Delete by type>History и Modify>Freeze Transformation. После этого создадим иерархию из групп и circle как на рисунке ниже:



Теперь удалим не нужные нам атрибуты из этих групп. Выделив Visibility атрибут контроллера Ctrl_root, сделаем Channel>Lock And Hide Selected в Channel Box. Удалим атрибуты Translate, Rotate и Scale всех остальных групп. Теперь добавим атрибуты mesh, controllers, joints, other boolean типа в основную группу. С помощью этих атрибутов мы сможем спрятать объекты которые не должны трогать. То есть аниматор случайно не сломает риг.



Теперь соединим эти атрибуты с помощью Windows>General Editors>Connection Editor.



Теперь создадим кости шеи и головы. И переименуем их ниже следующим образом. (02.mb)



После этого начнем скиннить. Выделив neck, head и head, откроем меню Skin>Interactive Bind Skin Options. И изменим этот атрибут.



Этот атрибут может скиннить только выделенные кости. Потом анимируем кости для проверки. (02.mov) Сначала поправим капсулы максимально. Это даст гладкий результат.


Потом нормализуем весы скина с помощью Skin>Normalize Weights>Enable Weight Normalization и Skin>Normalize Weights>Normalize Weights. Это поможет при рисовании весов. Теперь работаем с весами тщательно, с помощью Skin>Paint Skin Weights Tool и Windows>Component Editor. Особое внимание уделяем местам, где голова и шея соединяются. Проверяем в анимации.



В худшем случае может быть, как этот рисунок.



Теперь сделаем контроллеры для костей шеи и головы. Создадим 2 nurbs curve. С помощью ниже написанного скрипта создадим группы иерархии с правильными названиями.

// Выделить с начала curve, потом joint

string $sel[] = `ls -sl`;

$controller = $sel[0];

select $controller;

$suyak = $sel[1];

rename $controller ("ctrl_" + $sel[1]);

group -n ("ctrl_" + $sel[1] + "_SDK");

$onaGRP = `group -n ("ctrl_" + $sel[1] + "_0")`;

parent $onaGRP $suyak;

setAttr -e ($onaGRP + ".tx") 0;

setAttr -e ($onaGRP + ".ty") 0;

setAttr -e ($onaGRP + ".tz") 0;

setAttr -e ($onaGRP + ".rx") 0;

setAttr -e ($onaGRP + ".ry") 0;

setAttr -e ($onaGRP + ".rz") 0;

parent -w $onaGRP;

Сделаем все, как показано ниже.



Теперь сделаем Parent Constrain каждой кости к соответствующему контроллеру. После этого раскрасим контроллеры для красоты. Обратите внимание, что раскрасим только shape ноды. Тогда цвет поменяет только этот контроллер. Если раскрасить transform нод, тогда изменится цвет всех контроллеров стоящих ниже по иерархии.



Чтобы очистить Outliner, сделаем Parent всех костей в группу joints, а контроллеры в группу controllers. (03.mb) (03.mov)



2. Челюсть и рот

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







Теперь изменим ориентацию кости jaw как показано ниже.



После того как сделаем его Parent к кости головы, создадим контроллер для него. Для этого используем ранее упомянутый скрипт. Потом сделаем челюсти Parent Constrain к ctrl_jaw.



После того как анимируем Ctrl_jaw как контроллер головы, начнем делать скин. Выделив его кость и меш головы, откроем Skin>Edit Influences>Add Influence Option Box. На параметрах ставим ноль на вес, потому что мы будем рисовать вес челюсти с нуля.



В инструменте Paint Skin Weights Tool сделаем Lock кости neck. Потому что он не входит в область влияния кости челюсти. А Lock не позволяет нечаянно изменить вес кости neck. Так при отрисовке веса челюсти участвует только jaw и head.



Сначала рисуем внешнюю часть челюсти, потом область рта, потом внутреннюю часть рта. После этого у нас должен быть результат как ниже. (04.mb) (04.mov)



Теперь начнем риггить рот. Сначала нам нужно понять в какой последовательности работает рот. Он работает как в диаграмме ниже.



Создадим кости для губ и переименуем их как на рисунки ниже.



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



Теперь сделаем Parent кости губы к кости головы. И создадим контроллеры для каждого. Для создания и переименования их используем ранее упомянутый скрипт. Группируем все контроллеры левой стороны и дублируем. Вставим -1 на scaleX. Это даст нам контроллеры правой стороны. И переименуем их соответственно. Потом сделаем Parent Constrain каждой кости к своему контроллеру. (05.mb)



Теперь мы выделим пару edge на каждом полигоне lipHolderMesh и создадим локаторы с помощью скрипта rivet.mel. Для каждого контроллера сделаем Parent Constrain к соответствующему ривет локатору.



Теперь сделаем скин head и jaw к геометрии lipHolderMesh. А вес сделаем как на рисунке ниже с помощью Paint Skin Tool.



После этого добавим кости губ к скину головы. Сначала дадим этим костям 100 % вес. Вертексы между костями получат по 50 %. А потом постепенно уменьшаем вес, до того как получиться следующее. Чтобы губы работали гладко и красиво. (06.mb) (06.mov)



Почистим Outliner. Перемести группу Grp_rvt_lips в группу otherNonTransform, а Grp_ctrl_lips в ctrl_head. Теперь очередь за основными контроллерами рта. Они состоят из 5 штук. Создадим их как на рисунке ниже. Здесь 1 и 2 контролирует углы рта, а 3 и 4 верхние и нижние губы. 5 контроллер управляет всем ртом.



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





Теперь начнем риггать контроллер ctrl_lip_master. Сначала дублируем lipHolderMesh дважды. И переименуем их на lipHolderMesh_Default и lipHolderMesh_lip_master. lipHolderMesh_lip_master будет блендшейпом для ctrl_lip_master. А lipHolderMesh_Default будет неизменный меш для остальных блендшейпов. Теперь выделим lipHolderMesh_lip_master и lipHolderMesh по порядку, откроем Deform>Blend Shape, создадим блендшейп под названием blnd_lipHolder. Обратите внимание на атрибут Deformation Order. Это позволяет вставить новую ноду в начале инпута.



Выделив все вертексы lipHolderMesh_lip_master создадим cluster. Переименуем его на cluster_lip_master. Потом создадим locator под названием loc_lip_master и сгруппируем его. Его поставим в место, как показано ниже. Обратите внимание группа локатора находиться на пивоте контроллера ctrl_lip_master. Сделаем Parent кластера к локатору.



Теперь с помощью Connection Editor соединим атрибуты translate и rotate контроллера ctrl_lip_master к loc_lip_master. Проверим контроллер. (08.mb) (08.mov)



Теперь все это повторим для 4 контроллеров lip_master. Сперва дублируем lipHolderMesh_lip_master_up. Создадим кластер для него под названием cluster_lip_master_up как показано ниже. Весы тоже изменим с помощью Windows>General Editors>Component Editor. На месте пивота Ctrl_lip_master_up создадим локатор с группой. Не забудем добавить lipHolderMesh_lip_master_up в блендшейп lipHolderMesh. Используйте Deform>Blend Shape>Add.



Сделаем Parent Constrainкластера Cluster_lip_master_up к локатору loc_lip_master_up. Соединим атрибуты translate и rotate контроллера Ctrl_lip_master_up к атрибутам локатора loc_lip_master_up. Теперь готова верхняя губа. Тоже самое повторяем для нижней.

Теперь создадим lipHolderMesh_lip_master_left mesh, cluster_lip_master_left и loc_lip_master_left (с группой) для левой стороны. Весы кластера поставим как ниже.

Этот меш добавим lipHolderMesh как blendshape. Обратите внимание, что каждый раз добавляем одни и те же blendshape. После этого повторим это для правой стороны. Теперь займемся связкой их с контроллерами. Для этого откроем Key>Set Driven Key>Set. Выделим Ctrl_lip_master_left и ctrl_lip_master_right нажмем на Load Driver. Они являются управляющими. Потом выделим управляемые. Они loc_lip_master_left и loc_lip_master_right. Теперь нажимаем на Load Driven.



Начнем соединить атрибуты контроллеров. Соединим ctrl_lip_master_left.traslateX и loc_lip_master_left ning translateX, loc_lip_master_left ning translateZ с помощью Key.



Тоже самое повторяем для правого контроллера. Мы сейчас соединили начальные нулевые позы. Теперь поставим 1 на атрибутах translateX обоих контроллеров. Потом выделим оба локатора. Поставим 1 на translateX, -0,25 на translateZ. Вставим ключ с помощью кнопки Key.



Теперь поставим -1 на translateX контроллеров. А на локаторах -1 на translateX, 0.1 на translateZ. Нажмем на Key.



Теперь на очереди translateY. В нулевой позе ставим Key на translateY контроллеров и на атрибутах локаторов translateY, translateZ, rotateZ.



Ставим 1 на translateY контроллеров. В сторону управляемых вставим 1 на translateY, -0,25 на translateZ. И нажмем на Key.
Ставим -1 на translateY контроллеров. В сторону управляемых вставим -1 на translateY, -0,25 на translateZ, -35 на rotateZ . И нажмем на Key.
Проверим все. После этого выделим локаторы в Graph Editor и сделаем tangent всех ключей на Spline. Обратите внимание, что наши контроллеры влияют в интервале -1 и 1. Для того чтобы исправить включим бесконечность View>Infinity в Graph Editor. Потом, выделив все кривые, нажмем на Curves>Pre Infinity>Linear и Curves>Post Infinity>Linear.



Таким образом, соединим атрибуты translateZ и rotate контроллеров. После этого проверим скин. Выяснилось, что кости губ не влияет достаточно. Увеличим радиус и вес влияния на 10%. (09.mb) (09.mov)
Теперь почистим Outliner. Сделаем parent Grp_ctrl_master_lips к контроллеру ctrl_head. Переместим все блендшейпы начинающиеся с lipHolderMesh в группу blendshapes. Группируем все кластеры и переместим их в группу otherNonTransform. Остальные группы начинающиеся с null переместим в группу otherNonTransform. (10.mb)
Теперь будем делать липкость губ. Это очень полезная фишка и помогает аниматором сделать угол губ острыми формами. Для начала нам нужен этот атрибут. Выделив контроллеры ctrl_lip_master_right и ctrl_lip_master_left, добавим атрибут как показано ниже. Для этого используем функцию Channel Box> Edit>Add Attribute.



Если посмотреть на скин lipHolderMesh можно увидеть весы как показано ниже.



Мы хотим добиться того, атрибут sticky влияет на вес скина, начиная с уголка губ. Как показано ниже влияние должно увеличиться от угла рта к центру. То есть сначала будут веса 1 рисунка, потом 2 и 3. То есть, от угла веса будет приближаться к 0,5.






Дублируем lipHolderMesh_Default трижды. Их переименуем на lipHolderMesh_0_left, lipHolderMesh_50_left и lipHolderMesh_100_left. Каждую из этих геометрий прискинним к костям head и jaw. Потом копируем весы скина из lipHolderMesh на каждую геометрию с помощью Skin>Copy Skin Weights.



Сперва отключим skin Cluster node в lipHolderMesh. Для этого поставим 0 на атрибут envelope скина. Потом добавим lipHolderMesh_100_left как блендшейп в lipHolderMesh с помощью Deform>Blend Shape>Add.

Таким же образом добавим остальные два блендшейпа. Для этого выделим lipHolderMesh_50_left и lipHolderMesh. Откроем Deform>Blend Shape>Add Option Box. Заполняем, как показано ниже.

Это позволяет добавить несколько таргетов в один атрибут блендшейпа. Эту же процедуру повторим для lipHolderMesh_0_left.



И получим вот такой результат.







Правая сторона тоже будет сделана таким же образом. Закончив обе стороны, сделаем так, чтобы они не мешали друг другу. Чтобы не допустить этого, будем работать с картой блендшейпов. Для правой стороны раскрасим только правую сторону, для левой только левую сторону. Для этого откроем Paint Blend Shape Weight Tool как показано ниже.



Раскрасим весы блендшейпов.





После этого наши блендшейпы стали работать правильно. (11.mb) Теперь соединим атрибут sticky с атрибутом блендшейпов. Для этого откроем Set Driven Key.



Для нулевой позы поставим 0 на атрибут Sticky и 0.01 на blendshape. Нажнем Key. Поставим 1 на Sticky и на 1 блендшейпах и нажмем на Key. (12.mb) (12.mov)
Дублируем lipHolderMesh_Default и назовем его lipHolderMesh_sticky. Создадим 2 кластера как ниже. Это для отрицательной стороны атрибута Sticky, чтобы открылся угол рта.



Этот же меш добавим в основной блендшейп. Теперь соединим кластеры с контроллерами. Для этого используем Set Driven Key.





Теперь начнем подготавливать буквы U и M. Обычно они выглядеть как ниже.



Теперь дублируем lipHolderMesh_Default дважды. Переименуем их на lipHolderMesh_lipRollOut и lipHolderMesh_lipRollIn. Создадим по два кластера на верхнюю и нижнюю часть рта. Как показано ниже.



Пивоты их переместим как показано ниже.


Добавим атрибут roll контроллерам Ctrl_lip_master_up и ctrl_lip_master_down.



С помощью Set Driven Key соединим эти атрибуты с нашим кластером.

Теперь переместим все объекты, название которых начинается с lipHolderMesh в группы blendshapes. Все кластеры переместим в группу otherNonTransform. (13.mb) (13.mov)

Если поворачиваем Ctrl_jaw, видим что ctrl_lip_master не поварачивается. Чтобы исправить это создадим 3 локатора для ориентации в кость jaw. Один из них loc_jaw_100. Его сделаем Orient Constrain к кости jaw. Второй loc_jaw_0. Он не констрейнится ни к чему. То есть он будет следить за головой. Третий loc_jaw_50. Он сделан Orient Constrain к loc_jaw_0 и loc_jaw_100. То есть он будет следить за двумя локаторами 50 на 50. Сперва выделим loc_jaw_50 и потом grp_ctrl_master_lips. Сделаем Parent Constrain. Констрайним Ctrl_lip_master_up_0 к loc_jaw_0 с помошью Parent Constrain. Сделаем Parent Constrain Ctrl_lip_master_down_0 к loc_jaw_100. Сделаем Parent Constrain Grp_jaw_orient к ctrl_head. Сделаем Edit>Parent Grp_jaw_orient в группу otherTransform. (14.mb)

712 0 850 13
8
2016-11-02
Спасибо огромное за статью, материал невероятно ценный!
2016-11-04
Спасибо добрый человек за подробную статью!
2016-11-23
Материал хороший, но смесь английского и узбекского в названиях и скриптах - это не здорово. Немного усложняет изучение.
2016-11-29
не совсем понял момент "Таким образом, соединим атрибуты translateZ и rotate контроллеров"  после того как сделали Pre и Post Infinity.. К каким атрибутам их соединять?
2019-01-24
Понимаю, статья уже давняя. Но может файлы прилагаемые где то всё еще можно скачать ?
2019-01-24
Напишете в maverickmdgmdg@gmail.com. Отправлю все файлы.
2020-12-22
Жасурбек, добрый день! А можете мне тоже отправить файлы? Буду очень благодарна! Как это возможно сделать?
2020-12-22
Добрый день. Вы исходники сможете скачать тут. https://drive.google.com/folderview?id=1VmibzwFc0apnvm9xWEZDIFVpSOVbDa0P
RENDER.RU