- •Введение
- •Глава 1. Подготовка к изучению книги
- •Установка DirectX SDK
- •Выбор отладочных или рабочих версий библиотек
- •Настройка вашего компилятора
- •Установка директорий DirectX SDK
- •Привязывание к библиотекам DirectX
- •Установка используемого по умолчанию состояния символа
- •Использование вспомогательного кода книги
- •Использование вспомогательных объектов
- •Проверка вспомогательных функций
- •Двигаясь дальше по книге
- •Глава 2. Синхронизация анимации и движения
- •Использование движения, синхронизированного по времени
- •Считывание времени в Windows
- •Анимирование с использованием временных меток
- •Перемещение, синхронизированное со временем
- •Движение вдоль траекторий
- •Создание анализатора маршрутов .X файла
- •Создание внутриигровых кинематографических последовательностей
- •Посмотрите демонстрационные программы
- •TimedAnim
- •TimedMovement
- •Route
- •Cinematic
- •Глава 3. Использование формата файла .X
- •Работа с .X шаблонами и объектами данных
- •Определение шаблонов
- •Работа со стандартными шаблонами DirectX
- •Открытие .X файла
- •Перечисление объектов данных
- •Получение данных объекта
- •Создание класса .X анализатора
- •Загрузка мешей с использованием D3DX
- •Загрузка мешей, используя анализатор .X
- •Загрузка скелетных мешей
- •Загрузка анимации из .X
- •Загрузка специализированных данных из .X
- •Посмотрите демонстрационные программы
- •ParseFrame
- •Глава 4. Работа со скелетной анимацией
- •Начало скелетной анимации
- •Использование структур скелетов и иерархий костей
- •Использование скелетной структуры и скелетного меша
- •Загрузка иерархий из .X
- •Изменение положения костей
- •Обновление иерархии
- •Работа со скелетными мешами
- •Загрузка скелетных мешей из .X
- •Создание контейнера вторичного меша
- •Сопоставление костей фреймам
- •Обновление скелетного меша
- •Визуализация скелетных мешей
- •Глава 5. Использование скелетной анимации, основанной на ключевых кадрах
- •Использование наборов скелетных анимаций, основанных на ключевых кадрах
- •Использование ключей при анимации
- •Работа с четырьмя типами ключей
- •Считывание данных анимации из .X файлов
- •Прикрепление анимации к костям
- •Обновление анимации
- •Посмотрите демонстрационные программы
- •Глава 6. Комбинирование скелетных анимаций
- •Комбинирование скелетных анимаций
- •Соединение преобразований
- •Улучшение объектов скелетной анимации
- •Посмотрите демонстрационные программы
- •Глава 7. Создание кукольной анимации
- •Работа с физикой твердого тела
- •Создание твердого тела
- •Расположение и ориентирование твердых тел
- •Обработка движения твердых тел
- •Использование сил для создания движения
- •Соединение твердых тел с помощью пружин
- •Обеспечение обнаружения столкновений и ответной реакции
- •Создание систем кукольной анимации
- •Определение состояния твердого тела
- •Хранение костей
- •Создание класса управления куклой
- •Создание данных костей
- •Вычисление ограничивающего параллелепипеда кости
- •Установка сил
- •Объединение костей
- •Обработка столкновений
- •Восстановление соединений костей
- •Перестроение иерархии
- •Посмотрите демонстрационные программы
- •Глава 8. Работа с морфирующей анимацией
- •Морфинг в действии
- •Определение исходного и целевого меша
- •Морфинг мешей
- •Создание морфированного меша при помощи обработки
- •Визуализация морфированных мешей
- •Расчленение наборов
- •Создание морфирующего вершинного шейдера
- •Посмотрите демонстрационные программы
- •Глава 9. Использование морфирующей анимации, основанной на ключевых кадрах
- •Использование наборов морфируемой анимации
- •Создание шаблонов .X для морфируемой анимации
- •Загрузка данных морфируемой анимации
- •Визуализации морфированного меша
- •Получение данных морфируемого меша из альтернативных источников
- •Посмотрите демонстрационные программы
- •Глава 10. Комбинирование морфированных анимаций
- •Комбинирование морфированных анимаций
- •Использование базового меша в комбинированных морфированных анимациях
- •Вычисление разностей
- •Комбинирование разностей
- •Создание вершинных шейдеров комбинированного морфирования
- •Использование вершинного шейдера морфируемого комбинирования
- •Посмотрите демонстрационные программы
- •Глава 11. Морфируемая лицевая анимация
- •Основы лицевой анимации
- •Использование комбинированного морфирования
- •Использования фонем для речи
- •Создание лицевых мешей
- •Создание базового меша
- •Создание выражений лица
- •Создание мешей визем
- •Создание анимационных последовательностей
- •Создание последовательностей фонем
- •Использование анализатора файлов .X для последовательностей
- •Проигрывание лицевых последовательностей со звуком
- •Использование DirectShow для звука
- •Синхронизация анимации со звуком
- •Зацикливание воспроизведения звуков
- •Посмотрите демонстрационные программы
- •Глава 12. Использование частиц в анимации
- •Работа с частицами
- •Основы
- •Рисование частиц с помощью квадратных полигонов
- •Работа с точечными спрайтами
- •Улучшения визуализации частиц при помощи вершинных шейдеров
- •Оживление частиц
- •Передвижение частиц при помощи скорости
- •Использование интеллекта при обработке
- •Создание и уничтожение частиц
- •Управление частицами с помощью класса
- •Использование излучателей в проектах
- •Создание движков частиц в вершинных шейдерах
- •Посмотрите демонстрационные программы
- •Глава 13. Имитирование одежды и анимация мешей мягких тел
- •Имитация одежды в ваших проектах
- •Получение данных одежды из мешей
- •Приложение сил для создания движения
- •Воссоздание и визуализация меша одежды
- •Восстановление исходного меша
- •Добавление дополнительных пружин
- •Загрузка данных масс и пружин из .X файла
- •Создание анализатора .X данных одежды
- •Работа с обнаружением столкновений и реакцией на них
- •Определение объектов столкновений
- •Обнаружение и реакция на столкновения
- •Создание класса меша одежды
- •Использование мешей мягких тел
- •Восстановление мешей мягких тел
- •Посмотрите демонстрационные программы
- •Глава 14. Использование анимированных текстур
- •Использование анимации текстур в ваших проектах
- •Работа с преобразованиями текстур
- •Создание преобразования текстур
- •Установка матриц преобразования текстуры
- •Использование преобразования текстур в проектах
- •Использование файлов видео в качестве текстур
- •Импорт видео при помощи DirectShow
- •Создание специализированного фильтра
- •Работа со специализированным фильтром
- •Создание менеджера анимированных текстур
- •Окончание современной анимации
- •Веб-сайты
- •Рекомендуемые книги
- •DirectX 9.0 SDK
- •GoldWave Demo
- •Paint Shop Pro Trial Version
- •TrueSpace Demo
- •Microsoft Agent and LISET
- •Предметный указатель
282 |
Глав |
Комбинирование разностей
На данный момент мы посчитали разности значений координат вершин и нормалей. Следующим шагом является масштабирование каждой из этих разностей на величину комбинирования, используемую для каждого меша. Например, если вы хотите, чтобы первая анимация (открытия рта) использовала только 50 процентов разности (означая, что рот откроется только на половину), вы умножаете значения на 0.5.
Совет. В дополнение к определению процента разностей для комбинирования вы можете использовать значения комбинирования в качестве коэффициентов при анимировании комбинированных мешей. Постепенно увеличивая значения комбинирования со временем, вы можете получить плавную анимацию.
Для упрощения, задавайте величину комбинирования в виде двух переменных - одну для величины смешивания первого меша, а вторую для второго меша.
float Blendl =1.0f;//Использовать 100% разностей float Blend2 =1.of;
Для комбинирования разностей вам просто необходимо умножить их на только что определенные значения комбинирования.
// Применить значения комбинирования vecPosDiff1 *=Blendl;vecNormalDiff1 *=Blend1; vecPosDiff2 *=Blend2;vecNormalDiff2 *=Blend2;
После того как вы получили разности, масштабированные на коэффициенты комбинирования, вы можете сложить их, тем самым получив комбинированные значения разностей.
// Получить соответствующие значения комбинированных разностей D3DXVECTOR3 vecBlendedPos =vecPosDiff1 +vecPosDiff2; D3DXVECTOR3vecBlendedNormal=vecNormalDiff1+vecNormalDiff2;
Последним шагом является прибавление комбинированных разностей к координатам вершин и нормалей базового меша и сохранение результата в буфере вершин комбинированного меша.
//Прибавить разности к значениям базового меша и сохранить результат pBlendedVertices->vecPos =vecBlendedPos + \
pBaseVertices->vecPos;
// Нормализовать нормали перед сохранением!
D3DXVECTOR3 vecNormals =BlendedNormal+pBaseVertices->vecNormal; D3DXVec3Normalize(&pBlendedVertices->vecNormal, &vecNormals);
Комбинирование морфированных анимаций
Все, что остается сделать, - это увеличить указатели буферов вершин для обработки следующей вершины в каждом меше, закрыть кодовый блок for...next для завершения обработки вершин и разблокировать буферы вершин.
// Перейти к следующим вершинам pBaseVertices++;pBlendedVertices++; pTarget1Vertices++;pTarget2Vertices++;
}//Следующая итерация цикла
//Разблокировать буферы вершин pBlendedMesh->UnlockVertexBuffer(); pTarget2Mesh->UnlockVertexBuffer(); pTarget1Mesh->UnlockVertexBuffer(); pBaseMesh->UnlockVertexBuffer();
Вот и все! Один полостью комбинированный меш готов к визуализации! Вы должны заметить, что комбинирование двух мешей эффектно и просто, на самом деле. А что вы скажете о комбинироЁании четырех или более мешей? Вы подумаете, что я сумасшедший, но если вы посмотрите исходный код демонстрационной программы комбинирования морфируемых мешей, содержащийся на компакт диске, вы увидите, что это выполнимо! Все правильно, полный код комбинирования четырех морфируемых анимаций находится на диске и ожидает, когда вы используете его в своем проекте.
Что это, скажите вы? Вы бы выбрали более быстрый способ комбинирования мешей? Хорошо, мой друг, боги программирования услышали ваши молитвы, и скоро вы увидите как можно использовать вершинные шейдеры для выполнения всей грязной работы комбинирования за вас!
Создание вершинных шейдеров комбинированного морфирования
Вершинные шейдеры являются вашими спасителями при работе с комбинированием морфированных анимаций. Ранее в этой главе, вы видели, что необходимо делать при комбинировании мешей - блокировать каждый буфер вершин, вычислять разности и наконец комбинировать значения, выполняя кадр за кадром этот медленный процесс.
Говоря об основных причинах медленной обработки, особенно если буферы вершин находятся в видео памяти. Использование вершинных шейдеров гарантирует увеличение скорости обработки комбинированных морфированных анимаций, потому что вы можете хранить все данные меша в быстрой видео памяти и позволить вершинному шейдеру обрабатывать все.
284 Глава 10
Комбинированный вершинный шейдер будет работать аналогично тому, как вы непосредственно комбинировали координаты вершин ранее в этой главе. Для каждого комбинируемого меша вам необходимо получить доступ к его буферу вершин. Используя вершинные шейдеры, необходимо будет ассоциировать каждый буфер вершин с потоком вершин. Вместо того чтобы для получения данных вершин блокировать буфер вершин, вы используете данные потока вершин (как ассоциировано в объявлении вершин) для получения координат и нормалей.
Единственно проблемой является то, что вершинные шейдеры не могут использовать так много потоков. В дополнение, каждый вершинный шейдер имеет доступ к ограниченному количеству вершинных регистров (таких как координаты, нормали и текстурные координаты). DirectX 8 и 9 ограничивает число вершинных регистров 16, так что приходится считать каждый кусочек информации.
Если структура вершин должна содержать по крайне мере координаты вершины, нормаль и текстуру (всего три регистра на один поток), то вы можете использовать только пять мешей, один из которых базовый. В вершинном шейдере вы можете установить до четырех комбинированных мешей. Первым шагом к созданию вершинного шейдера комбинированного морфирования является определение структур и объявлений вершин. Помните, что необходимо сохранять минимальное количество данных (максимум три используемых регистра), так что структура вершины может выглядеть так:
typedef struct {
D3DXVECTOR3 vecPos; //Координаты вершины D3DXVECTOR3 vecNormal; //Нормаль вершины float u,v; //Текстурные координаты
} sBlendVertex;
Комментарии внутри структуры sBlendVertex говорят сами за себя, так что я пропущу объяснения и перейду к объявлению вершин.
// Объявления и интерфейсы вершинного шейдера D3DVERTEXELEMENT9 g_MorphBlendMeshDecl [] ==
{
//Первый поток используется для базового меша
//задать положение, нормаль и текстурные координаты {0,0,D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT, \
D3DDECLUSAGE_POSITION,0 }, {0,12,D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,
D3DDECLUSAGE_NORMAL,0 }, {0,24,D3DDECLTYPE_FLOAT2,D3DDECLMETHOD_DEFAULT,
D3DDECLUSAGE_TEXCOORD,0 },
//Второй поток используется для первого меша {1,0,D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,
D3DDECLUSAGE_POSITION,1 },
Комбинированиеморфированныханимаций
{1,12,D3DDECLTYPE_FLOAT3,D3DDECLMETH0D_DEFAULT, D3DDECLUSAGE_NORMAL,1 },
{1,24,D3DDECLTYPE_FLOAT2,D3DDECLMETH0D_DEFAULT, D3DDECLUSAGE_TEXCOORD,1 },
// Третий поток используется для второго меша {2,0, D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,
D3DDECLUSAGE_POSITION,2 }, {2,12,D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,
D3DDECLUSAGE_NORMAL,2 }, {2,24,D3DDECLTYPE_FLOAT2,D3DDECLMETHOD_DEFAULT,
D3DDECLUSAGE_TEXCOORD,2 } ,
// Четвертый поток используется для третьего меша ' {3,0,D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,
D3DDECLUSAGE_POSITION,3 }, {3,12,D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,
D3DDECLUSAGE_NORMAL,3 }, {3,24,D3DDECLTYPE_FLOAT2,D3DDECLMETHOD_DEFAULT,
D3DDECLUSAGE_TEXCOORD,3 },
// Пятый поток используется для четвертого меша {4,0, D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,
D3DDECLUSAGE_POSITION,4 }, {4,12,D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,
D3DDECLUSAGE_NORMAL,4 }, {4,24,D3DDECLTYPE_FLOAT2,D3DDECLMETHOD_DEFAULT,
D3DDECLUSAGE_TEXCOORD,4 },
D3DDECL_END()
};
В g_BlendMorphDecl вы можете видеть объявление пяти потоков, содержащих трехмерное положение, нормаль и двухмерные текстурные координаты. Первый поток имеет индекс использования 0, второй поток имеет индекс использования 1 и т. д. Это означает, что у вершинного шейдера будет доступ к пяти используемым типам для каждой компоненты вершины (положения, нормали и текстурных координат). В таблице 10.1 показаны типы данных, хранимые в каждом вершинном регистре.
После того как вы создали структуру вершин и их объявление, вы можете переходить к созданию самого вершинного шейдера. Шейдер будет дублировать то, что вы делали ранее в этой главе. Для каждой комбинируемой вершины вы вычисляете разность координат целевого морфируемого и базового меша.
Замечание. Вы можете найти вершинный шейдер комбинированного морфирования (MorphBlend.vsh) на компакт диске. Посмотрите конец этой главы для получения дополнительной информации о демонстрационной программе комбинированного морфирования.
286 |
Глава10 |
|
|
Таблица 10.4. Назначение вершинных регистров комбинированной |
|
морфируемой анимации |
|
|
|
Вершинный регистр |
Назначение |
|
|
v0 |
Трехмерные координаты первого (базового) меша |
|
|
v1 |
Нормаль первого (базового) меша |
|
|
v2 |
Текстурные координаты первого (базового) меша |
|
|
v3 |
Трехмерные координаты второго меша |
|
|
v4 |
Нормаль второго меша |
|
|
v5 |
Текстурные координаты второго меша |
|
|
v6 |
Трехмерные координаты третьего меша |
|
|
v7 |
Нормаль третьего меша |
|
|
v8 |
Текстурные координаты третьего меша |
|
|
v9 |
Трехмерные координаты четвертого меша |
|
|
v10 |
Нормаль четвертого меша |
|
|
v11 |
Текстурные координаты четветого меша |
|
|
v12 |
Трехмерные координаты пятого меша |
|
|
v13 |
Нормаль пятого меша |
|
|
v14 |
Текстурные координаты пятого меша |
|
|
Эта разность масштабируется на заданное процентное соотношение (с помощью константы вершинного шейдера, находящейся в диапазоне от 0 до 1), и результат, полученный от каждого комбинируемого меша, добавляется к результирующему набору координат положения, нормали и текстурных координат выходной вершины. Просто, не правда ли?
Посмотрите на код вершин, чтобы увидеть что происходит.
;v0 =Положеyие (xyz) базового меша ;v1 =Нормаль (xyz) базового меша
;v2 =Текстурные координаты (ху) базового меша
;
;v3 комбинированное положение (xyz) первого меша ;v4 комбинированная нормаль (xyz) первого меша
;v5 =Комбинированные текстурные координаты (ху) первого меша
;v6 комбинированное положение (xyz) второго меша ;v7 комбинированная нормаль (xyz) второго меша
Комбинированиеморфированныханимаций
;v8 комбинированные текстурные координаты (ху) второго меша
;
;v9 =Комбинированное положение (xyz) третьего меша ;v10 =Комбинированная нормаль (xyz) третьего меша
;v11 =Комбинированные текстурные координаты (ху) третьего меша
;
;v12 =Комбинированное положение (xyz) четвертого меша ;v13 =Комбинированная нормаль (xyz) четвертого меша
;v14 =Комбинированные текстурные координаты (ху) четвертого меша
;
;с0-с3 =матрица мир+вид+проекция
;c4 комбинированные значения 0-1 (mesh1,mesh2,mesh3,mesh4) ;c5 =направление света
vs. 1.0
Сначала, вы увидите комментарии, помогающие определить назначение используемых регистров вершин и констант. Перед вызовом вершинного шейдера необходимо установить шесть констант вершин.
•От с0 до с3 должны содержать транспонированную матрицу преобразования мир*вид*проекция.
•с4 содержит значения комбинирования для каждого меша (с4.х для меша 1, с4.у для меша 2, c4.z для меша 3 и c4.w для меша 4).
•с5 содержит вектор направления света.
Явернусь к этим константам немного позже; а пока я продолжу код вершинного шейдера. После комментариев я добавил необходимую версию вершинного шейдера. Как вы можете видеть, вершинный шейдер комбинированного морфирования требует вершинного шейдера версии 1.0, который должен поддерживаться большинством карт, к тому времени, как вы будете читать эту книгу.
После комментариев и необходимой версии идет объявление ассоциации элементов вершин. Эти объявления используются для привязывания компонент вершин, определенных в массиве D3DVERTEXELEMENT9, к регистрам вершин шейдера. Эти ассоциации идентичны показанным в таблице 10.1, так что это должно быть понятно.
;объявить привязывание dcl_position v0 ;базовый меш dcl_normal v1
dcl_texcoord v2
dcl_position1 v3 ;первый меш dcl_normal1 v4
dcl_texcoord1 v5
dcl_position2 v6 ;второй меш dcl_normal2 v7
dcl_texcoord2 v8
288
dcl_position3 v9 ;третий меш dcl_normal3 v10 dcl_texcoord3 v11
dcl_position4 v12 ;четвертый меш dcl_normal4 v13
dcl_texcoord4 v14
После ассоциирования регистров вершин вы можете получить доступ к данным вершин, используя регистры от v0 до v14. Регистр v0 содержит координаты вершины базового меша; регистр v6 содержит координаты вершины второго меша и т. д.
В начале фактического кода вершинного шейдера координаты вершины базового меша и его нормаль помещаются в два временных регистра (r0 и r1).
; Поместить базовые координаты и нормаль в регистры r0 и r1 mov r0,v0 ;координаты (r0)
mov r1,v1 ;нормаль (r1)
Шейдер использует эти два регистра только в качестве ссылок, так что они не будут переписаны при вызове последующих функий (по крайне мере до завершения работы шейдера, как вы скоро увидите). Следующий кусочек кода вычисляет разность координат базового меша и меша, заданного в качестве первого комбинируемого, который использует регистры вершин начиная с v3 до v5. Разность масштабируется (умножается) на значение константы с4.х (значение от 0 до 1) и прибавляется к начальным координатам из r0, хранимым в регистре r4. На протяжении оставшейся работы вершинного шейдера r4 будет содержать результирующие координаты вершины комбинированного меша. Точно такой же процесс повторяется для нормалей, а результат хранится в r5. Посмотрите:
;Получить разности первого комбинируемого меша и добавить их ;к результату
sub r2,v3,r0 ;Получить разность координат mad r4,r2,c4.х,r0 ;Поместить результат в r4 sub r3,v4,r1 ;Получить разность нормалей
mad r5,r3,c4.х,r1 ; Поместить результат в r4
Тот же самый процесс повторяется еще три раза, по одному для каждого оставшегося комбинируемого меша. Однако начиная с этого момента, инструкции умножения и сложения находятся в соответствующих регистрах, так что разности координат и нормалей могут быть использованы позднее. Вот оставшийся код вычисления используемых значений разностей:
;Получить разности второго комбинированного меша и добавить их к ; результату
sub r2,v6,r0 ;Получить разность координат