Как создать анимацию процедурно?
Анимируем танцующего персонажа процедурно - легко!
Создание привлекательной анимации персонажей вручную требует определённых знаний и навыков на получение которых нужно затратить некоторое время. А используя процедурный подход, другими словами - простые формулы, каждый независимо от имеющегося опыта, сможет создать анимацию персонажа. Именно этим мы и займёмся в данном уроке используя MAYA - самую популярную программу для создания анимации и персонажа Рэй от онлайн школы CGTarian.
Теория, не пугайтесь - всего одна простая формула с пояснениями!
Коротко - если взять любую из функций Синус или Косинус (мы берём Синус) эта функция выдаёт волну, вверх и вниз, и вверх и вниз и т.д. Смотрите рисунок 1, красная линия.
Вот эти “вверх и вниз“ мы будем использовать чтобы анимировать персонажа, двигая его тело, ноги и руки, вверх и вниз.
Вот и всё. Всё просто!
Рисунок 1
Подробнее о Синусе (sin)
Передаём синусу постепенно изменяющиеся значения (например время в секундах) и на выходе получаем волну со значениями от -1 до 1. Полный цикл вверх, вниз и вниз, вверх, волна проходит за два Пи значения.Посмотрите на пять салатовых точек на красной кривой, рисунок 1:
- Первая точка: Синус получил 0, выдал 0
sin(0) = 0; - Вторая точка: Синус получил 1.57 (или половину Пи) и выдал 1
sin(1.57) = 1; - Третья точка: Синус получил 3.14 (или Пи) и выдал 0
sin(3.14) = 0; - Четвёртая точка: Синус получил 4.71 (или полтора Пи) и выдал 1
sin(4.71) = -1; - Пятая точка: Синус получил 6.28 (или два Пи) и выдал 0
sin(6.28) = 0;
Функция синус в MAYA
sin(n)
где n меняющаяся переменная.
В скобках управляем частотой, за скобками, амплитудой.
Умножая значения в скобках, мы увеличиваем частоту, умножая значения за скобками, увеличиваем амплитуду.
Прибавляя к значениям в скобках, мы сдвигаем частоту по времени, прибавляя к значениям за скобками, мы сдвигаем амплитуду.
Например если мы хотим увеличить амплитуду и получать больше чем от -1 до +1. Увеличиваем значение за скобками:
- sin(time) = волна от -1 до +1
- sin(time) * 25 = волна от -25 до +25
- sin(time) * 25 + 20 = волна от -5 до +45
- sin(time) * 25 + 25 = волна от 0 до +50
- и т.д.
Приступаем к созданию анимации
Находим музыку
Скачиваем понравившеюся нам музыку. В этом уроке мы будем использовать музыку в стиле регги.
Регги музыку в WAV формате можно скачать тут: https://goo.gl/vVGXJa
Темп данной музыки 88 ударов в минуту (или 88 bpm - Beats Per Minute)
Другую музыку вы можете найти и скачать в MP3 формате тут: https://goo.gl/wGXdZf
Для скачивания музыки нажмите кнопку на плеере “DOWNLOAD PREVIEW”. Темп данной музыки указан на этой странице справа.
(Вы можете использовать любую другую музыку, в таком случае далее в формулах используйте значение темпа (bpm) вашей музыки, а не то что указано в уроке.)
Конвертируем скачанный mp3 файл в wav формат.
(это можно сделать онлайн, тут: https://goo.gl/s9wAoC)
Подготавливаем MAYA сцену
Идём в меню Windows > Settings/Preferences > Preferences
В появившемся окне идём в раздел Settings и устанавливаем Time: NTSC (30 fps)
Далее идём в раздел Time slider и вводим:
- Playback start/end: 1 - 600
- Animation start/end: 1 - 600
- Height: 4x
- Playback speed: Real-time [30 fps]
Далее через меню File > Import, импортируем wav файл в программу MAYA.
Кликаем правой кнопкой на зелёной, звуковой волне на таймлайне и идём в Sound > reggae_by_redlionproduction_preview и нажимаем на квадратик опций. После чего в открывшемся Attribute Editor’e в поле Source Start вписываем 695, чтобы сдвинуть начало музыки на 695 кадров, тем самым пропустив её вступление и передвинув её сразу к куплету.
Анимируем персонажа
Скачиваем персонажа Рэй тут: http://www.cgtarian.ru/ray
и открываем его в программе MAYA, через меню File > Open
(Вы можете использовать любого другого персонажа, в таком случае далее в формулах используйте названия контроллеров вашего персонажа, а не те что указаны в уроке.)
Открывшейся персонаж будет находится в стандартной Т позе.
Используя инструменты вращения (Rotate) и перемещения (Move) ставим персонажа в первоначальную позу танца. Для этого берём один из инструментов Move или Rotate, отмечаем любой из контрольных объектов персонажа (тонкие проволочки вокруг персонажа) и перемещаем либо вращаем его до получения нужной позы.
(подробно это показано тут: https://goo.gl/vmE4oh)
Выставить персонажа в первоначальную позу танца важно, так как именно из этой позы мы будем его анимировать, создавая формулами циклические движения частей его тела в пределах этой позы.
Например, циклическое вращение руки на 15 градусов вверх и вниз будучи в Т позе, ничего не означает,
а вот такое же вращение будучи в позе танца, похоже на движение в танце.
И так наш персонаж в позе и мы готовы написать нашу первую формулу, в MAYA они называются Expressions или по русски Выражения.
Выделяем контроллер правой стопы, который называется “ray_ac_rt_footIK” и идём в меню Windows > Animation Editors > Expression Editor
И в окно Expression вписываем такое выражение: ray_ac_rt_footIK.translateY = sin(time);
и нажимаем кнопку Create. Так мы создадим выражение и применим его к нашей сцене.
В этом выражении:
ray_ac_rt_footIK.translateY - это значение канала вертикального перемещения “translateY” у контроллера стопы “ray_ac_rt_footIK”
sin(time) - это функция Синус, в которую в качестве изменяющегося значения подставлено переменная time, которая из себя представляет время в секундах (прошедшее от начала анимации в MAYA сцене).
Из теории выше мы знаем что выдаёт функция sin - это плавающие значения от -1 до +1.
От 0 до 1 и обратно до нуля за 1 Пи. Потом от 0 до -1 и обратно до нуля тоже за 1 Пи.
Один целый цикл от 0 до +1, до 0, до -1, и обратно до 0 за 2 Пи.
Теперь давайте разберём что даёт переменная time.
Time это время в секундах, прошедшее от начала анимации в MAYA сцене. А при частоте анимации 30 кадров секунду это значит что, когда головка воспроизведения анимации находится в нулевом кадре, time передаёт 0 (ноль), а когда головка находится в 30-ом кадре, time передаёт 1 (так как при частоте 30 кадров в секунду, 30-ый кадр наступает при прохождении 1-ной секунды). Вот какие значение переменная time будет выдавать на разных кадрах:
Номер кадра | Значение time |
0 | 0 |
10 | 0.334 |
20 | 0.667 |
30 | 1 |
45 | 1.5 |
60 | 2 |
90 | 3 |
Значит наше выражение
ray_ac_rt_footIK.translateY = sin(time);
будет двигать стопу вверх и вниз от -1 до +1.
В нулевом кадре стопа никуда не поднимется и будет в 0 (в канале Translate Y)
При прохождении 3.14 секунд, одного Пи (это примерно в 94 кадре) стопа сделает подъём от 0 до +1 и опуститься обратно на 0. При прохождении следующих 3.14 секунд, одного Пи (это за ещё примерно 94 кадра) стопа опуститься до -1 и поднимется обратно к 0.
И этот цикл будет повторяться бесконечно до окончания анимации.
Полный цикл одного движения за 188 кадров это очень медленно и точно не в ритм нашей музыки. Давайте сделаем в ритм. Для этого нам нужно высчитать сколько кадров между каждым битом музыки (сколько кадров между ударами ритма)?
И это мы высчитаем легко. Берём скорость анимации (30 кадров в секунду), в минуте 60 секунд, значит умножаем 30 на 60 и получаем сколько кадров проходит за минуту, получается 1800. Теперь наши 1800 кадров в минуту делим на темп музыки 88 ударов в минуту и получаем число кадров между каждым ударом ритма, и это 22.454.
Теперь мы сделаем следующее:
Умножим time на 3.1415927 и получим один полуцикл 1 секунду:
ray_ac_rt_footIK.translateY = sin(time * 3.1415927);
Дополняем выражение и нажимаем кнопку Edit. Так мы обновим выражение и применим его к нашей сцене. Далее после каждого изменения выражения обязательно нажимайте Edit.
Умножим это всё на 30 (частоту кадров нашей анимации) и получим полуцикл за 1 кадр:
ray_ac_rt_footIK.translateY = sin(time * 3.1415927 * 30);
Разделим всё на 22.454 (количество кадров в одном бите музыки) и полуцикл за 1 бит музыки или в ритм, но в 2 раза медленнее:
ray_ac_rt_footIK.translateY = sin(time * 3.1415927 * 30 / 20.455);
Ну вот ритмичность (хоть и в пол скорости) мы получили. Но удары происходят не когда стопа достигает верха и низа амплитуды, а по её центру. И это мы можем просто сдвинуть добавляя небольшие значения к time.
Путём проб, добавляя 0.2, 0.5, 1.0 и далее я подобрал нужное нам число 2.
(Если у вас ритм музыки не 88, то ваше число будет другим. Просто вводите небольшие значения и смотрите как себя ведёт анимация. На данный момент нужно чтобы удары в ритм происходили внизу и вверху.)
Теперь наше выражение выглядит так:
ray_ac_rt_footIK.translateY = sin(time * 3.1415927 * 30 / 20.455 + 2);
Далее нам нужно чтобы удары в ритм происходили не вверху и внизу, а только внизу. Это просто в 2 раза быстрее. Умножаем всё на 2. Для этого заключаем всё выражение в скобки и умножаем его на 2:
ray_ac_rt_footIK.translateY = sin((time * 3.1415927 * 30 / 20.455 + 2 ) *2);
Ну вот, движение происходит точно в ритм, но нога проваливается ниже пола. Поправить это можно добавив сдвиг к амплитуде движения и добавляется он за скобками, путём добавления значений. Добавляем +1 и стопа начинает двигаться не от -1 до +1, а от 0 и до +2:
ray_ac_rt_footIK.translateY = sin( ( time * 3.1415927 * 30 / 20.455 + 2 ) *2 ) + 1;
Если мы хотим увеличить амплитуду движения, мы должны умножать значения за скобками, например мы хотим чтобы стопа двигалась от 0 до +3, тогда выражение будет таким:
ray_ac_rt_footIK.translateY = sin( ( time * 3.1415927 * 30 / 20.455 + 2 ) *2 ) * 1.5 + 1.5;
Мы умножили амплитуду на 1.5 и также сдвинули её уже на 1.5 а не на 1.
Ну вот, движение происходит в ритм и по такому же принципу нужно написать выражения для других необходимых для анимации частей тела. У некоторых частей тела, например у таза нужно анимировать и каналы перемещения (translate) и каналы вращения (rotate). А у некоторых частей тела, например плечи, локти, кисти, анимировать нужно только каналы вращения (rotate). Но структура нашего выражения остаётся той же.
Важно!
Обратите внимание что при перемещении, в нашем случае амплитуды в 2 единицы нам вполне достаточно. Но при амплитуде вращения 2 градуса, вращение будет едва ли заметным. Поэтому увеличивайте все амплитуды вращения, также для разных частей тела будут нужны слегка разные сдвиги частоты:
ray_ac_cn_pelvisIK.rotateZ = sin( ( time*3.1415927 * 30 / 20.455 + 0.75 ) *2 ) * 10 + 4.3;
Также мы начинали анимировать стопу с её нулевого значения в канале Translate Y. Анимируя другие части персонажа, обратите внимание есть ли в канале который собираетесь анимировать какие нибудь первичные значения. Если есть введите их в создаваемое выражение, после скобок, как сдвиг амплитуды!
Плавные амплитудные движения хорошо подойдут практически для всех частей тела, но вот именно для стопы, хочется резкого приземления, небольшой остановки и резкого подъёма. И если мы посмотрим на красную кривую синус волны и отрежем у низы, то как раз получим то что нам нужно - резкое приземление, небольшую остановку, резкий подъём и плавный разворот.
И резануть так волну мы можем используя условия “IF” и “ELSE” (“Если” и “В другом случае”). Мы просто отредактируем сдвиг амплитуды и разрешим стопе опускаться ниже пола, но тут же скажем что если высота синус волны меньше нуля (ниже пола), то высота стопы равна нулю (высоте пола). А в других случаях мы разрешим стопе двигаться за синус волной. Всё это делать мы будем используя новую, придуманную переменную “$RLegTY” (имя переменной может быть любым, но должно начинаться с символа “$”), она будет содержать не конкретное значение, а значение в зависимости от наших условий “IF” и “ELSE”. И наше выражение для стопы будет выглядеть так:
$RLegTY = sin( ( time * 3.1415927 * 30 / 20.455 + 2 ) *2 ) + 0.6;
ray_ac_rt_footIK.translateY = $RLegTY;
if ($RLegTY <= 0)
ray_ac_rt_footIK.translateY = 0;
else
ray_ac_rt_footIK.translateY = $RLegTY;
Обратите внимание что мы уменьшили сдвиг амплитуды с 1 до 0.6 чтобы разрешить синус волне опускаться меньше нуля (ниже пола).
Данное выражение будет двигать контроллер стопы (и стопу соответственно) в ритм нашей регги музыки. Каждое приземление будет происходить на каждый бит. И стопа будет повторять цикл: резкое приземление, небольшая остановка, резкий подъём, плавный разворот, и опять резкое приземление и т.д.
В случаях когда в движении не должно быть остановки, использовать “IF” и “ELSE” не надо и достаточно будет однострочного выражения:
ray_ac_rt_footIK.translateY = sin( ( time * 3.1415927 * 30 / 20.455 + 2 ) *2 ) + 1;
Полностью готовую анимацию танцующего персонажа, MAYA cцены с последовательным создание всей анимации, а так же полный, финальный код выражения, вы можете скачать тут: http://www.cgtarian.ru/proc
На этой же странице, данный урок также можно посмотреть как серию видео лекций.
Если вас заинтересовало более подробное изучение анимации - приглашаю вас на мой 9-ти месячный онлайн курс в школе CGTarian «Анимация персонажей», тут:
Хорошей и интересной учёбы!
Данная статья из раздела: Анимация
Для чтения других, похожих статей пожалуйста нажмите на один из хэштегов: #анимация #maya #mel