MayaMorfing
Сегментный морфинг в анимации физиономии
Пил с вашего лица, но только водку…
Эпиграф.
По мере производства рекламного ролика возникла задача - проанимировать физиономию утенка, поюзав возможности сегментного морфинга для артикуляции.
Строится модель утенка. Исходные Loft объекты режутся по изопармам на патчи, патчи подгоняются, возможно даже неоднократным сшиванием-резкой по швам для точности. Поскольку клюв обрамляет просто «дыру» в голове и во избежание «зашивания» рта, применяется не Global Stitch, а сшивание по ребрам Stitch Edges Tool с включенными галочками Position и Tangent и сшивание по точкам Stitch Surface Point. Ни для кого, конечно, не секрет, что при сшивании ТОЧЕК нужно выделить точки ВСЕХ сходящихся поверхностей, невзирая на то, что они (точки) могут совпадать пространственно, так что внимательнее к «углам». Все патчи (см. сцену Head.mb) сгруппированы в группу HEAD\HL (левая сторона) + HR (правая сторона).
По окончании работ над моделью возникает вопрос – какой тип морфинга наиболее приемлем. Богатая мимика утенку ни к чему, произносимая фраза коротка, и количество фонем невелико. Использование взвешенного морфинга вполне логично – модифицируем «енту харю» в соответствие с каждой фонемой, получаем необходимый ряд целей, завязываем их в цепочку с помощью Blend Shape и получаем возможность ручного (с помощью ползунков Window\Animation Editors\Blend Shape) или программного (с помощью скрипта) управления фонемами артикуляции. Можно даже использовать смешивание фонем, соответственно добавляя или убирая от 0 до 1 степень приближения морфируемого объекта к определенной фонеме. Неплохо!
Но… Хочется богатства! В том числе и богатства возможностей. Чем утешить этот зуд? Что насчет сегментного морфинга? Преимущество его перед взвешенным очевидно - увеличение количества морфинг-целей засчет смешивания морфируемых вариантов сегментов поверхности. Недостаток – увеличение объема работ при написании и отладке скрипта анимации, ведь описывается каждый морфируемый сегмент.
Прикинем, какими могут быть эти сегменты в рожице утенка. Допустим так: 1 – верхняя часть клюва, или верхняя губа, 2 – нижняя часть клюва, или нижняя губа, 3 – щеки. Таким образом, верхняя губа может проговаривать звук «Х», нижняя губа – звук «У», а щеки при этом улыбаться. При таком раскладе просто идеально подходит деформатор Wire:
- контур верхней губы – управляющая кривая деформации верхней губы WireUp и фиксирующая кривая для нижней губы WireDn;
- контур нижней губы – управляющая кривая деформации нижней губы WireDn и фиксирующая кривая для верхней губы WireUp;
- контур щек – фиксирующая кривая для обеих управляющих кривых WireHold.
Как эти кривые сделать? Выделяем в патче нужную изопарму и применяем Modeling\Edit Curves\Duplicate Surface Curves, получая отрезок нужной кривой.
Переходим к следующему патчу – еще кусок кривой, и так далее. Полученные отрезки кривых, конечно же будут пересекаться. Применяем Modeling\Edit Curves\Cut Curve, лишние кусочки удаляем, а оставшиеся объединяем в одну кривую командой Modeling\Edit Curves\Attach Curves. Удаляем историю построения Edit\Delete by Type\History и переименовываем полученный объект в WireHold. Подобным образом получаем три кривые и для удобства группируем их в CurvesMorph\WireUp+ WireDn+ WireHold.
Вернемся к деформатору Wire. Выбираем Animation\Deform\Wire Tool (в Wire Settings устанавливаем галочку Holders) и после появления Wire указателя в виде перекрестья с точкой действуем последовательно (следите за строкой сообщений):
1. На запрос Select shape(s) to deform выделяем патчи верхней части головы и клюва (в Outliner HeadAll\HEAD\HL\HTAL+ HTRL+ KTL+ HTAR+ HTRR+ KTR) и нажимаем ввод;
2. На запрос Select Wire curve выделяем управляющую кривую деформации верхней губы HeadAll\CurvesMorph\WireUp и нажимаем ввод;
3. На запрос Select holder shape выделяем управляющую кривую деформации нижней губы HeadAll\CurvesMorph\WireDn, но (!) в качестве фиксатора, чтобы модификации кривой верхней губы не тянула за собой и деформацию нижней части клюва (ограничение влияния деформации).
Press Enter;
4. На следующий запрос Select Wire curve
снова
выделяем ту же управляющую кривую деформации верхней губы (HeadAll\CurvesMorph\WireUp) и нажимаем ввод. Press Enter;
5. А на запрос Select holder shape уже выделяем в качестве фиксатора контур щек WireHold (ограничиваем влияние деформации областью щек). Press Enter.
6. Снимаем все выделения и нажимаем последний раз ввод, заканчивая работу с деформатором Wire.
7. Получаем объекты деформации WireUpBaseWire и WireUpBaseWire1. Каркас объекта подцвечивается.
8. Аналогично поступаем с кривой управления нижней губы (патчи HeadAll\HEAD\HL\HBAL+ HBRL+ KBL+ HBAR+ HBRR+ KBR, кривые WireDn и WireHold) и получаем объекты деформации WireDnBaseWire и WireDnBaseWire1.
И вот фишка - морфировать достаточно только управляющие и фиксирующие кривые деформатора WireUp, WireDn и WireHold, а не сам объект. Интересненько получается, скажете Вы - модифицируются кривые, деформируется и исходный объект, а его ведь нужно оставить нетронутым? Ответ: модифицируйте новые кривые, оставляя исходный объект без деформации. А Вы опять логично спрашиваете, а как же модифицировать кривые, если связи нет и при этом интерактивно не видно деформациии объекта? Для этого:
- создаете копии всех Wire кривых с помощью Control-D или Edit\Duplicate (обзываете их как-нибудь в соответствии с фонемой, например для фонемы «А» верхней губы - WireUpAh) и восстанавливаете OUTPUT как у исходных кривых (я это делал вручную так же как и для исходных кривых, просто не знаю как по другому);
- модифицируете кривые, наблюдая за деформацией объекта до получения формы необходимой фонемы;
- и, наконец, убиваете OUTPUT, влияющий на деформацию объекта, выделив крив-ую (-ые) и выполнив Animation\Deform\Edit Wire\Remove. При этом объект возвращается в свое исходное состояние, что визуально подтверждается, как обычно, по изменению цвета каркаса объекта, а кривые остаются сдеформировынными необходимым образом;
- выполнить процедуру для каждой фонемы или ключевого выражения… морды, или у утят лица ?, короче – его face.
В итоге имеем три последовательности кривых – 1) для верхней губы, 2) для нижней губы, 3) для щек.
Морфинг кривых создаем через их выделение и применение Animation\Deform\Create Blend Shape или набором в окне Script Edit соответствующих MEL директив. Или лучше сразу начнем писать скрипт. Итак:
Производим выделение морфинг-целей для верхней губы
select -r WireUpSm WireUpSh WireUpV WireUpP WireUpEe WireUpEh WireUpOh WireUpAh ;
в последнюю очередь выделяем исходник
select -add WireUp ;
создаем и именуем Blend Shape
blendShape -n "FacePhonemsUp";
Аналогично поступаем для кривых нижней губы и щек.
select -r WireDnSm WireDnSh WireDnV WireDnP WireDnEe WireDnEh WireDnOh WireDnAh ;
select -add WireDn ;
blendShape -n "FacePhonemsDn";
select -r WireHoldSm WireHoldSh WireHoldV WireHoldP WireHoldEe WireHoldEh WireHoldOh WireHoldAh ;
select -add WireHold ;
blendShape -n "FacePhonemsHold";
Запускаем скрипт – Execute. В результате все Blend Shape сформированы.
Условимся, что фонем и ключевых выражений «лица» будет одиннадцать:
0 – улыбка 1 – Ш, Г, К, Д, Т
2 – В, Ф 3 – Б, П
4 – И 5 – Е
6 – О 7 – А
8 – Ц 9 – Ы
10 – Ч 11 – исходное положение.
Немного отвлечемся от скрипта. Для локализации фонем по времени импортируем звук.
Затем, прослушивая и анализируя фонограмму, локализуем фонемы по номеру кадра и фиксируем их на бумаге карандашиком, то есть записываем Тайм-код, номер кадра, имя фонемы и номер фонемы.
Теперь можно вернуться к скрипту.
Пишем процедуру выбора фонемы
global proc prFPH (int $Phonem)
{
определяем передаваемую переменную, отвечающую за номер выбираемой фонемы
int $Phonem;
принудительно обнуляем ползунки всех Blend Shape
setAttr "FacePhonemsUp.WireUpSm" 0;
setKeyframe FacePhonemsUp.WireUpSm;\
setAttr "FacePhonemsUp.WireUpSh" 0;
setKeyframe FacePhonemsUp.WireUpSh;
…
setAttr "FacePhonemsHold.WireHoldAh" 0;
setKeyframe FacePhonemsHold.WireHoldAh;
используем переключатель для определения соответствия фонемы ее номеру
switch ($Phonem)
{
case 0://Sm
setAttr "FacePhonemsUp.WireUpSm" 1; autoKeyframe;
setAttr "FacePhonemsDn.WireDnSm" 1; autoKeyframe;
setAttr "FacePhonemsHold.WireHoldSm" 1; autoKeyframe;
break;
case 1://Sh, D, T
setAttr "FacePhonemsUp.WireUpSh" 1; autoKeyframe;
setAttr "FacePhonemsDn.WireDnSh" 1; autoKeyframe;
setAttr "FacePhonemsHold.WireHoldSh" 1; autoKeyframe;
break;
…
case 7://Ah
setAttr "FacePhonemsUp.WireUpAh" 1; autoKeyframe;
setAttr "FacePhonemsDn.WireDnAh" 1; autoKeyframe;
setAttr "FacePhonemsHold.WireHoldAh" 1; autoKeyframe;
break;
case 8://Ts
А вот, собственно, и небольшое применение сегментного морфинга. Сначала деформируем первый сегмент – верхнюю губу, пользуясь необходимым значением коэффициентов составляющих Blend Shape. Определить веса коэффициентов можно интерактивно, открыв окно Blend Shape и двигая ползунки до получения необходимого результата.
Так и запишем в скрипт.
setAttr "FacePhonemsUp.WireUpSm" 0.197; autoKeyframe;
setAttr "FacePhonemsUp.WireUpEe" 0.634; autoKeyframe;
setAttr "FacePhonemsDn.WireDnSm" 1; autoKeyframe;
setAttr "FacePhonemsDn.WireDnP" 1; autoKeyframe;
setAttr "FacePhonemsDn.WireDnEe" 1; autoKeyframe;
setAttr "FacePhonemsHold.WireHoldEe" 1; autoKeyframe;
setAttr "FacePhonemsHold.WireHoldOh" 0.455; autoKeyframe;
break;
case 9://Eeh
setAttr "FacePhonemsUp.WireUpEh" 1; autoKeyframe;
setAttr "FacePhonemsDn.WireDnEh" 1; autoKeyframe;
setAttr "FacePhonemsHold.WireHoldEh" 1; autoKeyframe;
setAttr "FacePhonemsUp.WireUpSm" 1; autoKeyframe;
setAttr "FacePhonemsHold.WireHoldSm" 1; autoKeyframe;
break;
case 10://Ch
setAttr "FacePhonemsUp.WireUpSm" 0.204; autoKeyframe;
setAttr "FacePhonemsUp.WireUpSh" 0.441; autoKeyframe;
setAttr "FacePhonemsUp.WireUpEh" 0.409; autoKeyframe;
setAttr "FacePhonemsUp.WireUpOh" 0.140; autoKeyframe;
setAttr "FacePhonemsDn.WireDnOh" 0.452; autoKeyframe;
break;
case 11://
break;
}
}
Теперь добавляем в скрипт несколько строк, отвечающих за вызов процедуры и размещение фонемы в нужном кадре. Пишем это выше процедуры.
…
//Шо цып цып
currentTime 100 ; prFPH (11) ;
currentTime 102 ; prFPH (1) ;
currentTime 106 ; prFPH (6) ;
currentTime 109 ; prFPH (8) ;
currentTime 111 ; prFPH (9) ;
currentTime 113 ; prFPH (3) ;
currentTime 116 ; prFPH (8) ;
currentTime 118 ; prFPH (9) ;
currentTime 120 ; prFPH (3) ;
currentTime 123 ; prFPH (11) ;
…
Сохраняем скрипт под каким-нибудь именем. Откатываемся назад вплоть до отмены создания всех Blend Shape, или для исключения ошибок открываем файл HeadAni.mb, импортируем звук Duck.wav из каталога Sound, включаем режим Auto keyframe, загружаем скрипт HeadAni.mel, выполняем его и смотрим анимацию.
Содержание раздела