на тему: Скелетная анимация с использованием шейдеров. Информационные Системы и технологии. 230201. 65 Работу

Государственное образовательное учреждение

высшего профессионального образования

Ульяновский Государственный Университет







Факультет Математики и Информационных технологий



Кафедра     Телекоммуникационных технологий и сетей.









Реферат на тему:

Скелетная анимация с использованием шейдеров.











Информационные Системы и технологии.  -   230201.65

--------------------------------------------------------------------------------------











Работу выполнил студент      _ИС-31____       ________        _Царапкин  А.М.____

                                               группа                  подпись, дата                     Ф.И.О.



                   Преподаватель                   __________        _________        ____Мальцев Д.А.__

                                         должность              подпись, дата                     Ф.И.О.





                                                                                                   _________________

                                                                                                                                                       оценка

















У Л Ь Я Н О В С К

2011 г.

Содержание

Введение. Анимация в играх.………………….………………………………….3

Скелет, как иерархия трансформаций…………………………………………..3

Скелетный расчёт……………………….………………………………………….4

Управление структурой объектов, при помощи скелета.…………………….5 

Вершинная деформация объектов……………………………………………….6

Skinning. Деформация полигональной модели скелетом…………….……….6

Анимация персонажей.…………………………………………………………….7

Преимущества скелетной анимации…………………………………………….8

Эффективное использование скелетной анимации……………………………9

Шейдеры………………………………………………………………………….….9

Использование вершинных шейдеров для ускорения расчётов……………10 

Совместное использование VBO и шейдеров…………………………............11

Вершинный шейдер………….………………………………………………..….12

Заключение……………………………………………………………………..….14

Список литературы..………………………………………………………….…..15





























Введение. Анимация в играх.

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

Игровой движок может реализовать различные типы анимации, от простой, где происходит обычное перемещение объекта из одного места в другое, до более сложной, где реализуется анимированная деформация объектов. Конечно, некоторые деформации можно очень просто сделать, например, легко реализовать сжатие объекта по какой-нибудь оси, используя матрицу масштабирования. Однако существуют более сложные деформации, в которых методы задания нуждаются в управлении отдельно взятыми вершинами. К примеру, лицевая анимация, где мимика персонажа реализуется через изменение взаимного расположение некоторых вершин, а не всего объекта. [1]



Скелет, как иерархия трансформаций.

Иерархией объектов, можно назвать систему объектов, в которой одни объекты своим расположением в пространстве влияют на расположение других объектов. Вводится понятие родительских и дочерних объектов и взаимосвязей между ними. Нас интересуют именно взаимодействие трансформаций этих объектов. То есть, когда мы говорим о скелете, мы говорим об иерархии трансформаций; сами объекты называют костями. Другими словами, скелет можно определить как совокупность костей. Именно поэтому скелетную анимацию также называют костевой. 

Абсолютная трансформация родительской кости порождает некую координатную систему. Эта координатная система является локальной для дочерней кости. Дочерняя кость задаётся локальной трансформацией в этой системе. Поэтому изменение трансформации родительской кости влечёт влияние на абсолютную трансформацию дочерней. 

Дочерняя кость, в свою очередь, может иметь свою дочернюю кость, причем не одну, относительно которой она уже является родительской. Ясно, что и родительская кость, тоже может иметь своего родителя. Родитель, который не имеет родителя, является корневым (root), а его локальная система координат является абсолютной. Например, условно в скелете двуногого за корневую кость выбрана тазовая кость. 

Оторопев от такого поворота, многие скелеты, просто рассыпаются в тряске, потеряв всю целостность своих иерархий. 

Ясно, что движение родительской кости порождает движение дочерней кости. Например, если вы даёте вращение шее, то голова тоже поворачивается. В этом примере родителем для головы является шея. В свою очередь спина является родителем для шеи, то есть если мы согнём спину, то шея и голова поменяют своё положение. [1]



Скелетный расчёт.

Все кости в скелете задаются своими локальными трансформациями. Но для конечного использования нам необходимо вычислить все абсолютные трансформации. Это и есть просчёт скелета. 

Трансформации в 3-х мерной графике принято задавать матрицами. Обычно это матрицы размерности 4x4 или 4x3. 



На примере руки, рассмотрим простейшую иерархию, состоящую из двух костей. На рисунке кость A является родителем кости B. Допустим, у нас уже вычислена абсолютная трансформация для кости A, матрицу этой трансформации обозначим через МА абс. Чтобы найти абсолютную трансформацию для кости B, необходимо подействовать на локальную матрицу трансформации MB лок кости В матрицей MA абс. Другими словами — просто умножить: 

MB абс = MB лок x MA абс

Поскольку у корневой кости абсолютная матрица совпадает с локальной, просчёт абсолютных матриц костей всего скелета происходит, начиная от корневой кости, по цепочкам от родительской к дочерним костям, и так до самых последних в иерархии костей. 

Если какая-то кость поменяла своё расположение в пространстве, то есть изменилась её абсолютная матрица трансформации, то требуется заново сделать пересчёт всех дочерних костей. Во время анимации просчёт скелета нужно делать в каждый момент времени. 

Сама анимация может либо браться из готовых просчитанных заранее положений каждой кости, либо вычисляться процедурно, например, при использовании инверсной кинематики. [1]



Управление структурой объектов, при помощи скелета. 

При создании модели какого-нибудь механизма, очень часто бывает удобно использовать иерархию объектов. Такая структура объектов, собственно, является неким скелетом. То есть каждая кость представляет собой локальную трансформацию каждого объекта из этой структуры. Управляя этим скелетом, например, назначив ему анимацию, можно реализовать анимированное поведение механизма. К примеру, имеем дело с револьвером. Корпус является корневым объектом. Барабан револьвера - дочерним, может получить локальное вращение вокруг своей оси. Затвор, тоже дочерний - может иметь локальное перемещение. Пружина - масштабирование. Перемещая корпус револьвера, мы не заботимся о перемещении его отдельных частей, об этом беспокоится иерархия. Для вращения барабана - мы просто вращаем локальную матрицу трансформации для этого барабана. Абсолютная же матрица, то есть положение объекта в мировом пространстве, вычисляется иерархией. 

Механизмы могут быть более сложными. Например, таким образом можно выстроить систему управления сложными роботами. [1]



Вершинная деформация объектов. 

Кроме анимации механизмов, часто встречаются более сложные анимации, требующие не простого перемещения объектов, а их деформацию. Речь идёт об изменение формы цельного полигонального объекта. Анимация такой деформации достигается движением вершин полигонального объекта. Как это реализовать? Например, можно хранить положение каждой вершины полигональной модели в каждом кадре анимации. 



Допустим, рассматривается движение руки персонажа. У нас есть два положения - начальное и конечное. Каждая вершина имеет своё начальное и конечное положение в пространстве. Для тех вершин, которые имеют некоторое перемещение, мы задаём траекторию движения этих вершин. Часто используемым методом задания анимации персонажей является построение промежуточных отображений (tweening) между изменениями объекта. То есть, к примеру, можно для каждого кадра анимации хранить копии одного и того же объекта с небольшими изменениями, а во время проигрывания анимации интерполировать каждую вершину между этими копиями. Однако такой способ задания анимации для персонажей не является эффективным и требует больших накладных расходов. 

Но в подобных случаях такую анимированную деформацию можно решить при помощи скелетной анимации. [1]



Skinning. Деформация полигональной модели скелетом.

Анимация вершин заменяется невидимой иерархией анимированных костей, которые перемещают вершины. 

После того как просчитан скелет, трансформируется геометрия, на которую влияет скелет. Здесь геометрия - это полигональная модель вашего объекта или персонажа. Модель представляется одной цельной полигональной моделью, которая деформируется под действием костей. Происходит деформация геометрии на уровне вершин под влиянием костей. Влияние может распространять как одна кость, так и несколько. Иногда ограничиваются только использованием влияния на любую вершину какой-то одной кости. Это меньше занимает расчетного времени и памяти для хранения анимации. Однако такой метод является не очень эффективным. Появляются артефакты, заметные на глаз, при неправильном «захлёсте» геометрии. С некоторыми такими артефактами удаётся бороться добавлением дополнительных промежуточных небольших костей. Однако, при использовании возможности влияния на одну вершину несколькими костями, достигается большая эффективность и реалистичность. В этом случае каждая вершина модели должна знать какие именно кости влияют на её положение и какова степень влияния каждой кости. Степень влияния задаётся коэффициентом, который называется весом (weight). Ясно, что сумма всех таких коэффициентов для одной вершины должна быть равна 1. При помощи этих коэффициентов происходит смешивание вычисленных координат вершин (vertex blending). [1]



Анимация персонажей.

Для анимации персонажей наиболее часто используется скелетная анимация. Для представления движения живых существ, таких как человека, животного или насекомого, удобно хранить взаимосвязи между подвижными частями данного персонажа, например, голова крепится к шее, ступня к ноге и т.д. Движение любой части можно задать как движение отдельной кости. В большинстве случаев скелетную анимацию для персонажей можно оптимизировать. [1]





Преимущества скелетной анимации.

В чем преимущества подхода реализации деформации в виде скелетной анимации? Во-первых, это относительно малое количество данных, требуемое для хранения анимации, например, если сравнивать с морфингом. Выигрыш из иерархии также в том, что для задания какой-то анимации нет необходимости задавать и хранить анимацию для каждой кости. То есть, например, если мы сгибаем руку в локте, не нужно описывать движение кисти руки. Кроме того, использование скелета делает более очевидной задачу использования ключей для анимации и последующую интерполяцию между ними, либо линейную, либо сплайновую. При этом, частоту появления ключевых кадров можно значительно уменьшить: в линейном случае можно провести оптимизацию на незначительных изгибах кривой движения, а в сплайновом - задаётся аниматором. 

Во-вторых, поскольку скелет представляет собой некую иерархию костей, то имеется возможность использовать инверсную кинематику. 

Иногда предоставляется возможность применять одну и ту же анимацию для похожих моделей с одинаковой структурой. Например, ясно, что если у нас есть анимация ходьбы для какого-нибудь мальчика, то мы не можем применить эту анимацию к животному, например, к собаке, однако модель девочки может использовать ту же самую анимацию для своей ходьбы. То же самое можно распространить и на "уровни детализации" и на замещение некоторой части полигональной модели, например, если у вас есть некий герой, который меняет одежду, то не нужно для каждого обмундирования иметь свою отдельную анимацию, достаточно аниматорам создать соответствующую привязку вершин к нужным костям скелета. 

Кроме того, к преимуществам можно отнести эффективное использование скелетной анимации, описанное ниже. [1]







Эффективное использование скелетной анимации.

Здесь мы рассмотрим один из типов соединений между костями, также называемые связями или суставами, которые часто можно использовать в построении скелета. Называются такие связи шарнирами (revolute joint). В шарнирных соединениях конечная точка одной кости вращается вокруг какой-то статической точки, обычно конечной точки родительской кости. Приятной особенностью такой связи является то, что для перемещения каждой кости в новую позицию задаётся только вращение. Отсюда следует, что для анимации необходимо хранить только информацию о вращении. 

Итак, можно предоставить простой способ представления скелета. Имеется иерархия костей. Каждая кость имеет локальный набор информации - длину и вращение. Вращение обычно задаётся кватернионом.

По договорённости, каждая кость выровнена по оси X. Конечная точка кости находится на оси X и смещена по ней на длину кости. Относительная матрица вращения вычисляется из локального значения вращения текущей кости, а перемещение является сдвигом на длину родительской кости по X-координате в локальной системе координат родителя. 

Использование шарнирных соединений ведёт к более низким затратам на хранение анимации. [1]



Шейдеры

Нынешнее графическое железо предоставляет пользователю возможность замены некоторых частей графического конвейера шейдером. Шейдер — это специальная программа, которая использует определенные программируемые регистры видеокарты для создания различных графических эффектов. Более новые видео-карты обеспечивают расширенные возможности программируемости шейдеров: огромное количество инструкций, динамическое ветвление и т.д. [2]

Шейдер - это программа для процессора графической карты (GPU), выполняющая специфические задачи, заменяя соответствующие блоки FFP.Есть два типа таких программ (шейдеров):

Вершинный шейдер (в OpenGL - вершинная программа) - это программа для вершинного процессора, обрабатывающая вершинные данные. 

Пиксельный шейдер (в OpenGL - фрагментная программа) - это программа для фрагментного процессора, обрабатывающая данные фрагмента, такие как: степень затуманивания, текстурные координаты, глубина и прочее. 

Программы можно писать на асм-подобных языках или на шейдерных языках высокого уровня, например: HLSL, GLSL или Cg. Синтаксис шейдерной программы очень похож на синтаксис языка C. [4]

Шейдер (англ. Shader) — это программа для одной из ступеней графического конвейера, используемая в трёхмерной графике для определения окончательных параметров объекта или изображения. Она может включать в себя произвольной сложности описание поглощения и рассеяния света, наложения текстуры, отражение и преломление, затенение, смещение поверхности и эффекты пост-обработки.

Есть два вида видеокарт - с индексом MX и FX, так вот МХ шейдеры не поддерживает, а FX да. Образно говоря, в играх, особенно с быстро меняющимся сюжетом, например, автогонки, без шейдеров задний план постоянно как бы прорисовывается, с шейдерами задний план висит постоянно, увеличивается как бы глубина изображения. И чем больше шейдеров поддерживает видеокарта, тем приятнее глубина резкости изображения дальнего плана. Некоторые навороченные игрушки с движком такого плана, где надо поддерживать дальний план местности, вообще не запускаются или запускаются с ужасно искаженной графикой без поддержки шейдеров. [3]



Использование вершинных шейдеров для ускорения расчётов 

Некоторые функции выполняются на процессоре видеокарты (GPU) особенно быстро. Например, к таким функциям относится умножение вектора на матрицу. Практически все расчёты, связанные со скелетной анимацией, можно перенести с CPU на GPU. Но здесь важно учитывать следующий эффект: если переусердствовать нагружением видеокарты различными шейдерами, то может возникнуть ситуация, при которой CPU простаивает в ожидании перегруженного шейдерными задачами GPU. 

Современные видеокарты могут хранить 3D модели прямо в своей памяти. Отрисовка модели из памяти видеокарты происходит существенно быстрее, так как не тратится время на вызовы glTexCoord2f, glVertex3f и подобных функций, требующих времени на копирование данных из одной памяти (CPU) в другую (GPU). Осуществить ускоренную работу видеокарты позволяют Vertex Buffer Objects (VBOs). 

В данной версии имеет место многократная трансформация повторяющихся вершин. Работа над устранением этой проблемы может дать ощутимый прирост скорости. [5]



Совместное использование VBO и шейдеров 

Максимальный прирост производительности дают VBO с полностью статическими моделями: модели один раз загружаются в память видеокарты сразу после запуска программы. Под воздействием шейдеров статическая модель "оживает" непосредственно внутри видеокарты. В таком случае у нас есть два источника прироста производительности: VBO в режиме вывода статических моделей и быстрое перемножение вершин на матрицы трансформации костей внутри шейдера. [5]



Вершинный шейдер.

//

// GLSL vertex shader for skeletal animation

//

#define N     100

#define EPS   0.001

uniform vec4 boneQuat [N];

uniform vec4 bonePos  [N];



//

// Quaternion multiplication

//



vec4 quatMul ( in vec4 q1, in vec4 q2 )

{

    vec3  im = q1.w * q2.xyz + q1.xyz * q2.w + cross ( q1.xyz, q2.xyz );

    vec4  dt = q1 * q2;

    float re = dot ( dt, vec4 ( -1.0, -1.0, -1.0, 1.0 ) );



    return vec4 ( im, re );

}



//

// vector rotation via quaternion

//



vec4 quatRotate ( in vec3 p, in vec4 q )

{

    vec4 temp = quatMul ( q, vec4 ( p, 0.0 ) );

	

    return quatMul ( temp, vec4 ( -q.x, -q.y, -q.z, q.w ) );

}



vec3 boneTransf ( int index, vec3 pos )

{

    return bonePos [index].xyz + quatRotate ( pos, boneQuat [index] ).xyz;

}



void	main ()

{

    vec4    weights = gl_MultiTexCoord3;        // weights for 4 bones

    vec3    pos     = vec3 ( 0.0 );

    int     index;



    if ( weights.x > EPS )                      // process 1st bone

    {                                           // get 1st bone index

        index = int ( gl_MultiTexCoord4.w );

        pos  += weights.x * boneTransf ( index, gl_MultiTexCoord4.xyz );

    }



    if ( weights.y > EPS )                      // process 2nd bone

    {                                           // get 2nd bone index

        index = int ( gl_MultiTexCoord5.w );

        pos  += weights.y * boneTransf ( index, gl_MultiTexCoord5.xyz );

    }



    if ( weights.z > EPS )                      // process 3rd bone

    {                                           // get 3rd bone index

        index = int ( gl_MultiTexCoord6.w );

        pos  += weights.z * boneTransf ( index, gl_MultiTexCoord6.xyz );

    }



    if ( weights.w > EPS )                      // process 4th bone

    {                                           // get 4th bone index

        index = int ( gl_MultiTexCoord7.w );

        pos  += weights.w * boneTransf ( index, gl_MultiTexCoord7.xyz );

    }

    gl_Position     = gl_ModelViewProjectionMatrix * vec4 ( pos, 1.0 );

    gl_TexCoord [0] = gl_MultiTexCoord0;

} [7]



Заключение.

Совместное использование VBO и шейдеров позволяет увеличить FPS в несколько раз. Возможные источники прироста производительности таковы: 

Благодаря функции glInterleavedArrays и выбору текстуры внутри шейдера отрисовка модели осуществляется за один вызов glDrawArrays. 

Данные о вершинах и креплении к скелету 3D модели загружаются в память видеокарты только один раз после старта программы. 

Высокая скорость GPU при перемножении вершин модели на матрицы костей. 

При использовании VBO все необходимые шейдеру данные уже находятся в памяти видеокарты и отсутствует потеря времени на ожидание передачи данных от CPU. [5]

Шейдеры предоставляют программисту мощное средство для реализации сложных трехмерных эффектов, postprocessing-эффектов и увеличения общего быстродействия. Хотя качественное использование шейдеров – сложная задача, требующая наличия у программиста множества дополнительных знаний, преимущества использования шейдеров заметно превышают недостатки. [6, c 13]



















    Список литературы.

 С.Ваткин – «Скелетная анимация: Введение» http://wat.gamedev.ru/articles/SkelAnim1

Иннокентий, Paronator –  «Программирование шейдеров на HLSL» http://www.gamedev.ru/code/articles/HLSL

А. Кутеминский – «Что такое шейдеры?»

     http://webotvet.ru/articles/opredelenie-sheyderi.html

Ю.Кремечуг –  «Уроки для программистов – Шейдеры» 

http://www.elite-games.ru/art/program/jurlesson8.shtml

«Оптимизация скелетной анимации (vbo+шейдеры)»

http://gcreat.ucoz.ru/forum/49-132-1

А. Сморкалов –  «OpenGL. Шейдеры»

А.В. Борешоф – «Основы скелетной анимации»

http://steps3d.narod.ru/tutorials/skeletal-animation-tutorial.html























15