Возможно вы искали: 'Dream Team Challenge 3...'

May 12 2025 01:24:29
  • Как сделать 8Gamers.Ru домашней страницей?
  • Игры
    • База данных по играх
    • Игровые новости
    • Игровая индустрия
    • Обзоры на игры
    • Прохождения игр
    • Гайды к играм
    • Превью о играх
    • Игровые тизеры
    • Игровые арты
    • Игровые обои
    • Игровые скриншоты
    • Игровые обложки
    • Игровые трейлеры
    • Игровое видео
    • Вышедшие игры
    • Ближайшие релизы игр
  • Кино и ТВ
    • База данных по кино
    • Статьи о кино
    • Постеры
    • Кадры из кино
    • Кино трейлеры
    • Сегодня в кино
    • Скоро в кино
  • Комиксы и манга
    • Манга по алфавиту
    • База данных по комиксах
    • Читать онлайн комиксы
    • Читать онлайн манга
    • База персонажей
  • Читы и коды
    • Чит-коды для PC игр
    • Чит-коды для консольных игр
    • Трейнеры
    • Коды Game Genie
  • Моддинг
    • Модификации
    • Карты к играм
    • Программы для моддинга
    • Статьи о моддинге
  • Геймдев
    • Всё о создании игр
    • Список движков
    • Утилиты в помощь игроделу
    • Конструкторы игр
    • Игровые движки
    • Библиотеки разработки
    • 3D-модели
    • Спрайты и тайлы
    • Музыка и звуки
    • Текстуры и фоны
  • Рецензии
    • Игры
    • Кино
    • Аниме
    • Комиксы
    • Мангу
    • Саундтреки
  • Саундтреки
    • Лирика
  • Файлы
    • Патчи к играм
    • Русификаторы к играм
    • Сохранения к играм
    • Субтитры к кино
  • Медиа
    • Видео
    • Фото
    • Аудио
    • Фан-арты
    • Косплей
    • Фото с виставок
    • Девушки из игр
    • Рисунки
    • Рисуем онлайн
    • Фотохостинг
  • Юмор
    • Анекдоты
    • Афоризмы
    • Истории
    • Стишки и эпиграммы
    • Тосты
    • Цитаты
  • Флеш
    • Азартные
    • Аркады
    • Бродилки
    • Гонки
    • Для девочек
    • Для мальчиков
    • Драки
    • Квесты
    • Леталки
    • Логические
    • Мультфильмы
    • Открытки
    • Приколы
    • Разное
    • Спорт
    • Стратегии
    • Стрелялки
Статистика

Статей: 87772
Просмотров: 96030355
Игры
Injustice:  Gods Among Us
Injustice: Gods Among Us
...
Dark Souls 2
Dark Souls 2
Dark Souls II - вторая часть самой хардкорной ролевой игры 2011-2012 года, с новым героем, сюжето...
Battlefield 4
Battlefield 4
Battlefield 4 - продолжение венценосного мультиплеер-ориентированного шутера от первого ли...
Кино
Steins;Gate
Steins;Gate
Любители японской анимации уже давно поняли ,что аниме сериалы могут дать порой гораздо больше пи...
Ку! Кин-дза-дза
Ку! Кин-дза-дза
Начинающий диджей Толик и всемирно известный виолончелист Владимир Чижов встречают на шумной моск...
Обзоры на игры
• Обзор Ibara [PCB/PS2] 18346
• Обзор The Walking ... 18789
• Обзор DMC: Devil M... 19864
• Обзор на игру Valk... 15867
• Обзор на игру Stars! 17754
• Обзор на Far Cry 3 17935
• Обзор на Resident ... 16012
• Обзор на Chivalry:... 17495
• Обзор на игру Kerb... 17970
• Обзор игры 007: Fr... 16604
Превью о играх
• Превью к игре Comp... 17946
• Превью о игре Mage... 14451
• Превью Incredible ... 14706
• Превью Firefall 13462
• Превью Dead Space 3 16325
• Превью о игре SimC... 14717
• Превью к игре Fuse 15432
• Превью Red Orche... 15532
• Превью Gothic 3 16334
• Превью Black & W... 17345
Главная » Статьи » Всё о XNA » Анимация, эффекты

Анимация, эффекты

Лабораторная работа №18. Анимация, эффекты


В этой лабораторной работе мы поговорим о применении графических эффектов в играх и об анимации персонажей.

Цель работы
  • Научиться применять графические эффекты и приемы анимации
Задачи работы
  • Рассмотреть основы анимации трехмерных персонажей
  • Рассмотреть применение графических эффектов в компьютерных играх, созданных на базе XNA
Анимация персонажей

Компьютерные игры наполнены анимированными персонажами. XNA содержит встроенные средства, поддерживающие базовые операции по анимации трехмерных персонажей. В частности, это средства для работы с так называемым скелетом персонажа. Скелет состоит из взаимосвязанных костей, управляя которыми можно анимировать модель. Создание анимированных моделей – это отдельная, достаточно трудоемкая задача, которая требует серьезных познаний в области 3D-моделирования. Для подготовки анимированных трехмерных моделей вы можете использовать практически любой 3D-редактор.

XNA содержит лишь базовые средства для управления скелетами объектов. Так, мы можем получить коллекцию костей объекта и проводить с ними какие-либо преобразования, вызывающие движение модели. Однако, такой подход ограничен – с его использованием весьма сложно создать реалистичное движение для сложных моделей. На основе базовых средств XNA разработаны библиотеки кода, которые содержат компоненты, позволяющие анимировать персонажи на более высоком уровне. В частности, одну из таких библиотек – XNAAnimation – можно найти на сайте http://www.codeplex.com/xnanimation.

Здесь мы рассмотрим базовый подход к анимации модели. Он заключается в следующем. Можно менять параметры отдельных костей модели и выводить ее на экран с учетом этих изменений. Мы использовали бесплатную модель Ballpen.fbx, взятую с сайта http://www.turbosquid.com.

Создадим новый проект P18_1. Загрузим в него модель Ballpen.fbx. На рис. 18.1. представлено окно Solution Explorer нашего нового проекта.


Рис. 18.1. Окно Project Explorer

Код проекта сосредоточен в классе Game1.cs, его код вы можете найти в листинге 18.1.

Листинг 18.1. Код класса Game1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
 
namespace P18_1
{
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        //Матрицы
        Matrix viewMatrix;
        Matrix projMatrix;
        //Модель
        Model pen;
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }
 
        protected override void Initialize()
        {
            base.Initialize();
        }
 
        protected override void LoadContent()
        {
            //Загрузка модели
            pen = Content.Load<Model>("ballpen");
            //Соотношение сторон
            float aspectRatio = (float)graphics.GraphicsDevice.Viewport.Width /
               (float)graphics.GraphicsDevice.Viewport.Height;
            //Устанавливаем камеру
            viewMatrix = Matrix.CreateLookAt(new Vector3(0, 30, 80), new Vector3(-32, 0, 0), new Vector3(0, 1, 0));
            //Устанавливаем проекционную матрицу
            projMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f), aspectRatio, 1.0f, 1000.0f);
        }
 
        protected override void Update(GameTime gameTime)
        {
            //Перемещение частей ручки
            PenMove();
            base.Update(gameTime);
        }
        //Процедура для перемещения частей ручки
        void PenMove()
        {
            //Получить состояние клавиатуры
            KeyboardState keyboardState = Keyboard.GetState();
            //Поворот зажима - он представлен родительской костью сети №3
            //Умножим его матрицу трансформации на матрицу поворота по оси X
            pen.Meshes[3].ParentBone.Transform = pen.Meshes[3].ParentBone.Transform * Matrix.CreateRotationX(MathHelper.ToRadians(-1.0f));
            //Кнопка ручки перемещается по клавиатурным командам
            //При нажатии кнопки "Влево"
            //Она выходит из ручки
            if (keyboardState.IsKeyDown(Keys.Left))
            {
                //Умножим матрицу трансформации родительской костью сети №1
                //На матрицу трансляции, перемещающей ее на 2 позиции влево по оси Х
                pen.Meshes[1].ParentBone.Transform = pen.Meshes[1].ParentBone.Transform * Matrix.CreateTranslation(new Vector3(-2, 0, 0));
            }
            //При нажатии кнопки "Вправо"
            //Кнопка входит в ручку
            if (keyboardState.IsKeyDown(Keys.Right))
            {
                //Умножим матрицу трансформации родительской кости сети №1
                //На матрицу трансляции, перемещающую ее на 2 позиции по оси X вправо
                pen.Meshes[1].ParentBone.Transform = pen.Meshes[1].ParentBone.Transform * Matrix.CreateTranslation(new Vector3(2, 0, 0));
            }
 
        }
        protected override void Draw(GameTime gameTime)
        {
            graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
            //Новый массив матриц размером, соответствующим количеству
            //костей в скелете модели
            Matrix[] absoluteTransformations = new Matrix[pen.Bones.Count];
            //Скопировать матрицы трансформации костей в массив матриц
            pen.CopyAbsoluteBoneTransformsTo(absoluteTransformations);
 
            foreach (ModelMesh mesh in pen.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.LightingEnabled = true;
                    effect.EnableDefaultLighting();
                    effect.Projection = projMatrix;
                    effect.View = viewMatrix;
                    //Установим новую мировую матрицу для родительской кости текущей сети
                    //это приводит к перемещению кнопки и к перемещению зажима
                    //Так же здесь мы уменьшаем модель, применяя коэффициент масштабирования 0,13
                    effect.World = absoluteTransformations[mesh.ParentBone.Index] * Matrix.CreateScale(0.13f);
                }
                //Выводим подготовленную сеть
                mesh.Draw();
            }
            base.Draw(gameTime);
        }
    }
}

 


На рис. 18.2. вы можете видеть игровой экран проекта P18_1.


Рис. 18.2. Игровой экран проекта P18_1

Эффекты

Простые графические эффекты в XNA можно реализовать при выводе изображений стандартными средствами. Но стандартные эффекты не способны удовлетворить потребности разработчиков. В одной из предыдущих лекций мы уже упоминали о том, что XNA поддерживает использование шейдерных программ, которые позволяют управлять графическими эффектами.
Шейдерные программы или просто шейдеры представлены в виде файлов с расширением FX. Эти файлы можно создавать как с помощью специального ПО для разработки и отладки шейдеров, так и вручную, в редакторе кода Visual Studio. Для описания шейдерных программ существует специальный язык – HLSL – High Level Shader Language – Высокоуровневый язык описания шейдеров.

Шейдерные программы исполняются графическим процессором видеокарты, с их помощью можно создать множество графических эффектов, которыми наполнены современные игры.

Шейдеры принято делить на вершинные (Vertex Shader) и пиксельные (Pixel Shader).
Вершинные работают с вершинами объектов. С их помощью можно осуществить такие операции, как деформацию объектов, анимацию, перемещение и т.д. После того, как вершинный шейдер завершит работу по модификации модели, за дело принимается пиксельный шейдер.

Пиксельные шейдеры применяются к отдельным пикселям изображения. В частности, они отвечают за цвет пикселей, позволяют применять к изображению различные эффекты.

Для того, чтобы создать новый FX-файл в XNA-проект, достаточно выполнить щелчок левой кнопкой мыши по папке Content, выбрать пункт Add(New Item и в появившемся окне выбрать в качестве типа добавляемого файла Effect File. После того, как файл эффектов будет добавлен в проект, он будет содержать некоторые стандартные части, которые представляют собой объявление переменных, необходимых для работы шейдера, объявление точки входа в шейдер и, собственно, шаблоны двух шейдеров – вершинного и пиксельного.

Для того, чтобы разрабатывать шейдеры самостоятельно с помощью XNA-редактора FX-файлов, вам нужно ознакомиться с языком HLSL. Вы можете сделать это, воспользовавшись справочной службой MSDN, в частности, этим разделом: http://msdn2.microsoft.com/en-us/library/bb509561.aspx.

На практике лучше всего пользоваться специализированным ПО для разработки и отладки шейдеров.

Рассмотрим пример работы с шейдерными эффектами – он создан с использованием примера применения шейдеров, приведенного в документации к XNA.

Создадим новый проект P18_2. На рис. 18.3. вы можете видеть его окно Solution Explorer.


Рис. 18.3. Окно Solution Explorer для проекта P18_2

Файл shader.fx содержит код шейдера, файл tex.png используется в качестве текстуры для наложения на модель, созданную программными средствами. Код программы реализован в классе Game1. Рассмотрим его (листинг. 18.2.).

Листинг 18.2. Код класса Game1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
 
namespace P18_2
{
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        //Матрицы
        Matrix WorldMAtrix, ViewMatrix, ProjectionMatrix;
        //Объект для применения эффектов
        Effect effect;
        //Вершины куба
        VertexDeclaration cubeVertexDeclaration;
        //Координаты для наложения текстур
        VertexPositionTexture[] cubeVertices;
        //Вершинный буфер
        VertexBuffer vertexBuffer;
        //Индексный буфер
        IndexBuffer indexBuffer;
        //Массив индексов
        short[] cubeIndices;
        //Номер эффекта в шейдере
        int CurPass;
        //Множитель для текстуры
        float Multiplier;
        //Текстура
        Texture2D texture;
 
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }
 
        protected override void LoadContent()
        {
            //Мировая матрица
            WorldMAtrix = Matrix.Identity;
            //Матрица вида
            ViewMatrix  = Matrix.CreateLookAt(new Vector3(0, 0, 5), Vector3.Zero,
                Vector3.Up);
            //Матрица проекции
            ProjectionMatrix = Matrix.CreatePerspectiveFieldOfView(
                MathHelper .ToRadians (45.0f),
                (float)graphics.GraphicsDevice.Viewport.Width /
                (float)graphics.GraphicsDevice.Viewport.Height,
                1.0f, 10.0f);
            //Текущий эффект имеет номер 0
            CurPass = 0;
            //Текущий множитель - 1
            Multiplier = 1;
            //Загрузим текстуру
            texture = Content.Load<Texture2D>("tex");
            //Загрузим шейдер shader в переменную типа Effect
            effect = Content.Load<Effect>("shader");
            //Передадим в переменную шейдера UserTexture текстуру
            effect.Parameters["UserTexture"].SetValue(texture);
            //Установим переменную шейдера Multiplier в значение
            //соответствующей игровой переменной
            effect.Parameters["Multiplier"].SetValue(Multiplier);
            //Создадим куб
            InitializeModel();
        }
 
        /// 
        /// Создаем 3D-модель
        /// 
        public void InitializeModel()
        {
            // Переменная типа VertexDeclaration
            cubeVertexDeclaration = new VertexDeclaration(
                graphics.GraphicsDevice, VertexPositionTexture.VertexElements);
 
            //Установка параметров точек, которые будут использованы для рисования фигуры
            Vector3 topLeftFront = new Vector3(-1.0f, 1.0f, 1.0f);
            Vector3 bottomLeftFront = new Vector3(-1.0f, -1.0f, 1.0f);
            Vector3 topRightFront = new Vector3(1.0f, 1.0f, 1.0f);
            Vector3 bottomRightFront = new Vector3(1.0f, -1.0f, 1.0f);
            Vector3 topLeftBack = new Vector3(-1.0f, 1.0f, -1.0f);
            Vector3 topRightBack = new Vector3(1.0f, 1.0f, -1.0f);
            Vector3 bottomLeftBack = new Vector3(-1.0f, -1.0f, -1.0f);
            Vector3 bottomRightBack = new Vector3(1.0f, -1.0f, -1.0f);
 
            // Координаты текстуры
            Vector2 textureTopLeft = new Vector2(0.0f, 0.0f);
            Vector2 textureTopRight = new Vector2(1.0f, 0.0f);
            Vector2 textureBottomLeft = new Vector2(0.0f, 1.0f);
            Vector2 textureBottomRight = new Vector2(1.0f, 1.0f);
 
            // Массив для хранения списка вершин
            // Он используется для передачи данных в вершинный буфер
            cubeVertices = new VertexPositionTexture[36];
 
            // Передняя часть фигуры
            cubeVertices[0] =
                new VertexPositionTexture(
                topLeftFront, textureTopLeft); // 0
            cubeVertices[1] =
                new VertexPositionTexture(
                bottomLeftFront, textureBottomLeft); // 1
            cubeVertices[2] =
                new VertexPositionTexture(
                topRightFront, textureTopRight); // 2
            cubeVertices[3] =
                new VertexPositionTexture(
                bottomRightFront, textureBottomRight); // 3
 
            // Задняя часть фигуры
            cubeVertices[4] =
                new VertexPositionTexture(
                topLeftBack, textureTopRight); // 4
            cubeVertices[5] =
                new VertexPositionTexture(
                topRightBack, textureTopLeft); // 5
            cubeVertices[6] =
                new VertexPositionTexture(
                bottomLeftBack, textureBottomRight); //6
            cubeVertices[7] =
                new VertexPositionTexture(
                bottomRightBack, textureBottomLeft); // 7
 
            // Верхняя часть фигуры
            cubeVertices[8] =
                new VertexPositionTexture(
                topLeftFront, textureBottomLeft); // 8
            cubeVertices[9] =
                new VertexPositionTexture(
                topRightBack, textureTopRight); // 9
            cubeVertices[10] =
                new VertexPositionTexture(
                topLeftBack, textureTopLeft); // 10
            cubeVertices[11] =
                new VertexPositionTexture(
                topRightFront, textureBottomRight); // 11
 
            // Нижняя часть фигуры
            cubeVertices[12] =
                new VertexPositionTexture(
                bottomLeftFront, textureTopLeft); // 12
            cubeVertices[13] =
                new VertexPositionTexture(
                bottomLeftBack, textureBottomLeft); // 13
            cubeVertices[14] =
                new VertexPositionTexture(
                bottomRightBack, textureBottomRight); // 14
            cubeVertices[15] =
                new VertexPositionTexture(
                bottomRightFront, textureTopRight); // 15
 
            // Левая часть фигуры
            cubeVertices[16] =
                new VertexPositionTexture(
                topLeftFront, textureTopRight); // 16
            cubeVertices[17] =
                new VertexPositionTexture(
                bottomLeftFront, textureBottomRight); // 17
            cubeVertices[18] =
                new VertexPositionTexture(
                topRightFront, textureTopLeft); // 18
            cubeVertices[19] =
                new VertexPositionTexture(
                bottomRightFront, textureBottomLeft); // 19
 
            //Создаем вершинный буфер для хранения информации о вершинах
            vertexBuffer = new VertexBuffer(graphics.GraphicsDevice,
                VertexPositionTexture.SizeInBytes * cubeVertices.Length,
                BufferUsage.None
                );
 
            //Добавляем данные в вершинный буфер
            vertexBuffer.SetData<VertexPositionTexture>(cubeVertices);
 
            // С помощью этого массива определяем, к каким частям фигуры
            //Относятся те или иные компоненты массива cubeVertices
            cubeIndices = new short[] {
                                     0,  1,  2,  // Передняя плоскость
                                     1,  3,  2,
                                     4,  5,  6,  // Задняя плоскость
                                     6,  5,  7,
                                     8,  9, 10,  // Верхняя плоскость
                                     8, 11,  9,
                                    12, 13, 14,  // Нижняя плоскость
                                    12, 14, 15,
                                    16, 13, 17,  // Левая плоскость
                                    10, 13, 16,
                                    18, 19, 14,  // Правая плоскость
                                     9, 18, 14 };
 
            //Индексный буфер
            indexBuffer = new IndexBuffer(graphics.GraphicsDevice,
                sizeof(short) * cubeIndices.Length,
                BufferUsage.None,
                IndexElementSize.SixteenBits
                );
 
            //Добавляем данные в индексный буфер
            indexBuffer.SetData<short>(cubeIndices);
        }
 
        protected override void Update(GameTime gameTime)
        {
            //Получим состояние клавиатуры
            KeyboardState Key = Keyboard.GetState();
            //Если нажата клавиша 1 - установить
            //номер прохода эффекта в 0
            if (Key.IsKeyDown (Keys.D1))
            {
                CurPass = 0;
            }
            //Если нажата клавиша 2 - 
            //установить номер прохода в 1
            if (Key.IsKeyDown(Keys.D2))
            {
                CurPass = 1;
            }
            //Если нажата клавиша 3 
            //установить номер прохода в 2
            if (Key.IsKeyDown(Keys.D3))
            {
                CurPass = 2;
            }
            //По нажатию клавиш QWERT
            //Устанавливать различные множители
            //они влияют на размеры текстуры, размещенных
            //на гранях куба
            //Например, если Multiplier=1 - лишь один экземпляр
            //изображения текстуры располагается на грани
            //Если Multiplier=2 - на грани размещается уже
            //4 текстуры и т.д.
            if (Key.IsKeyDown(Keys.Q))
            {
                Multiplier = 10.0f;
            }
            if (Key.IsKeyDown(Keys.W))
            {
                Multiplier = 5.0f;
            }
            if (Key.IsKeyDown(Keys.E))
            {
                Multiplier = 2.0f;
            }
            if (Key.IsKeyDown(Keys.R))
            {
                Multiplier = 1.0f;
            }
            if (Key.IsKeyDown(Keys.T))
            {
                Multiplier = 0.5f;
            }
            //Модифицируем мировую матрицу таким образом, чтобы модель
            //поворачивалась в пространстве с небольшой скоростью
            WorldMAtrix = WorldMAtrix * Matrix.CreateRotationX(0.011f) * 
                Matrix.CreateRotationY(0.012f)*
                Matrix.CreateRotationZ (0.013f);
            //Установить матрицу, которая является результатом умножения мировой, видовой и 
            //проекционной матриц в эффекте
            effect.Parameters["WorldViewProj"].SetValue(WorldMAtrix *ViewMatrix *ProjectionMatrix);
            //Установить переменную Multiplier в эффекте
            effect.Parameters["Multiplier"].SetValue(Multiplier);
            base.Update(gameTime);
        }
 
 
        protected override void Draw(GameTime gameTime)
        {
            //Очистить экран
            graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
            //Выключить режим удаления задних частей треугольников
          graphics.GraphicsDevice.RenderState.CullMode =
                CullMode.None;
            //Установить матрицу вершин
            graphics.GraphicsDevice.VertexDeclaration = cubeVertexDeclaration;
            //Установить матрицу индексов
            graphics.GraphicsDevice.Indices = indexBuffer;
            //Установить вершинный буфер
            graphics.GraphicsDevice.Vertices[0].SetSource(
                vertexBuffer,
                0,
                VertexPositionTexture.SizeInBytes);
 
            //Начало работы эффекта, используемого для вывода изображения
            effect.Begin();
                //Использовать проход шейдера, заданный переменной CurPass
                effect.CurrentTechnique.Passes[CurPass].Begin();
                    //Вывести изображение как набор индексированных 
                    //примитивов, используя настройки буферов, сделанные ранее
                    graphics.GraphicsDevice.DrawIndexedPrimitives(
                        PrimitiveType.TriangleList, 
                        0, 0, cubeVertices.Length, 0, 12);
                //Завершить текущий проход шейдера
                effect.CurrentTechnique.Passes[CurPass].End();
             //Завершить вывод изображений
             effect.End();
            base.Draw(gameTime);
        }
    }
}

 


Теперь рассмотрим код шейдера – в листинге 18.3. вы можете найти код файла shader.fx.

Листинг 18.3. Код файла shader.fx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
//Переменные, устанавливаемые при настройке шейдера
//Матрица - результат перемножений мировой, видовой, проекционной матриц
uniform extern float4x4 WorldViewProj : WORLDVIEWPROJECTION;
//Текстура
uniform extern texture UserTexture;
//Множитель
uniform extern float Multiplier;
 
struct VS_OUTPUT
{
    float4 position  : POSITION;
    float4 textureCoordinate : TEXCOORD0;
};
 
sampler textureSampler = sampler_state
{
	Texture = <UserTexture>;
	mipfilter = LINEAR; 
};
//Вывод вершин текстуры
//Вершинный шейдер, который используется
//во всех вариантах эффекта
VS_OUTPUT Transform(
    float4 Position  : POSITION, 
    float4 TextureCoordinate : TEXCOORD0 )
{
    VS_OUTPUT Out = (VS_OUTPUT)0;
    Out.position = mul(Position, WorldViewProj);
    Out.textureCoordinate = TextureCoordinate*Multiplier;
    return Out;
}
 
//Вывод текстуры без изменений для P0, пиксельный шейдер
//Возврат того же цвета, который был передан
//шейдеру
float4 ApplyTexture(VS_OUTPUT vsout) : COLOR
{
	return tex2D(textureSampler, vsout.textureCoordinate).rgba;
}
 
 
//Вывод размытой текстуры для P1, пиксельный шейдер
//Цвет устанавливается исходя из цвета
//соседних пикселей
//Полученная цветовая информация делится на 5
//для сохранения исходной яркости
float4 ApplyTextureBlur(VS_OUTPUT vsout) : COLOR
{
	float4 Col;
    Col =  tex2D(textureSampler, vsout.textureCoordinate);
	Col += tex2D(textureSampler, vsout.textureCoordinate + (0.01));
	Col += tex2D(textureSampler, vsout.textureCoordinate + (0.02));
	Col += tex2D(textureSampler, vsout.textureCoordinate + (0.03));
	Col += tex2D(textureSampler, vsout.textureCoordinate + (0.04));
	Col = Col / 5;
	//Возвращаем найденный цвет пикселя
	return Col;
}
//Вывод текстуры в оттенках серого для P2 - пиксельный шейдер
//Интенсивность света всех каналов изображения складывается и 
//делится на количество каналов
//Альфа-канал устанавливается равным 1
float4 ApplyTextureGray(VS_OUTPUT vsout) : COLOR
{
	float4 Col;
    Col =  tex2D(textureSampler, vsout.textureCoordinate);
    Col.a=1.0f;
    Col.rgb=(Col.r+Col.g+Col.b)/3;
    return Col;
}
 
//Техника шейдера
technique TransformAndTexture
{
	//Проход P0, имеет индекс 0
    pass P0
    {
	//Вершинный шейдер для данного прохода
        vertexShader = compile vs_2_0 Transform();
        //Пиксельный шейдер для данного прохода
        pixelShader  = compile ps_2_0 ApplyTexture();
    }
    //Проход P1, имеет индекс 1
    pass P1
    {
		vertexShader = compile vs_2_0 Transform();
        pixelShader  = compile ps_2_0 ApplyTextureBlur();
    }
    //Проход P2, имеет индекс 2
    pass P2
    {
		vertexShader = compile vs_2_0 Transform();
        pixelShader  = compile ps_2_0 ApplyTextureGray();
    }
}

 


На рис. 18.4., 18.5., 18.6. вы можете видеть игровое окно проекта в различных режимах применения шейдера.


Рис. 18.4. Наложение текстуры без изменения цвета, с множителем 2


Рис. 18.5. Наложение текстуры с размытием, множитель 1


Рис. 18.6. Текстура в оттенках серого, множитель 1

Вопросы

1) Что такое скелетная анимация?
  • a. Анимация трехмерных персонажей с помощью модификации их видовой матрицы
  • b. Анимация трехмерных персонажей с помощью модификации отдельных частей их скелета с последующим отражением изменений в мировой матрице
  • c. Анимация трехмерных персонажей с помощью модификации параметров проекционной матрицы
2) Какой объект может описывать следующий код: pen.Meshes[3].ParentBone.Transform?
  • a. Кость №3 модели pen
  • b. Сеть №3 модели Pen
  • c. Матрицу трансформации родительской кости для сети №3 модели pen
  • d. Модель pen
3) Метод CopyAbsoluteBoneTransformsTo объекта типа Model предназначен для
  • a. Копирования объекта
  • b. Копирования отдельных сетей объекта
  • c. Копирования матриц трансформаций костей объекта в специально созданную матрицу
  • d. Копирования скелета объекта
4) Что такое HLSL?
  • a. Высокоуровневый язык описания шейдеров
  • b. Библиотека XNA для работы с шейдерами
  • c. Формат моделей, которые поддерживают шейдеры
  • d. Программа для разработки шейдеров
5) Какое расширение имеют файлы эффектов в XNA?
  • a. FBX
  • b. TXT
  • c. X
  • d. FX
6) Какова основная функция вершинных шейдеров?
  • a. Они позволяют копировать информацию о вершинах объекта в файлы
  • b. Они предназначены для модификации трехмерных объектов путем изменения параметров их вершин
  • c. Они позволяют обрабатывать отдельные пиксели объектов, применяя к ним различные графические эффекты
  • d. Они позволяют загружать в игру трехмерные модели
7) Какова основная функция пиксельных шейдеров?
  • a. Они позволяют копировать информацию о вершинах объекта в файлы
  • b. Они предназначены для модификации трехмерных объектов путем изменения параметров их вершин
  • c. Они позволяют обрабатывать отдельные пиксели объектов, применяя к ним различные графические эффекты
  • d. Они позволяют загружать в игру трехмерные модели
8) Можно ли редактировать файлы шейдеров, написанных на HLSL-, используя встроенные средства XNA?
  • a. Да
  • b. Нет
9) Объект какого типа используется для загрузки шейдеров в игру?
  • a. Model
  • b. Texture2D
  • c. Effect
  • d. SpriteBatch
2209 Прочтений •  [Анимация, эффекты] [08.08.2012] [Комментариев: 0]
Добавил: Ukraine Vova
Ссылки
HTML: 
[BB Url]: 
Похожие статьи
Название Добавил Добавлено
• Анимация, эффекты Ukraine Vova 08.08.2012
Ни одного комментария? Будешь первым :).
Пожалуйста, авторизуйтесь для добавления комментария.

Проект входит в сеть сайтов «8Gamers Network»

Все права сохранены. 8Gamers.NET © 2011 - 2025

Статьи
Рецензия на Pressure
Рецензия на Pressure
Чтобы обратить на себя внимание, начинающие маленькие разработчики, как правило, уходят в жанры, ...
Рецензия на Lost Chronicles of Zerzura
Рецензия на Lost Chron...
Игры, сделанные без любви и старания, похожи на воздушный шар – оболочка есть, а внутри пусто. Lo...
Рецензия на The Bridge
Рецензия на The Bridge
«Верх» и «низ» в The Bridge — понятия относительные. Прогуливаясь под аркой, можно запросто перей...
Рецензия на SimCity
Рецензия на SimCity
Когда месяц назад состоялся релиз SimCity, по Сети прокатилось цунами народного гнева – глупые ош...
Рецензия на Strategy & Tactics: World War 2
Рецензия на Strategy &...
Название Strategy & Tactics: World War II вряд ли кому-то знакомо. Зато одного взгляда на ее скри...
Рецензия на игру Scribblenauts Unlimited
Рецензия на игру Scrib...
По сложившейся традиции в информационной карточке игры мы приводим в пример несколько похожих игр...
Рецензия на игру Walking Dead: Survival Instinct, The
Рецензия на игру Walki...
Зомби и продукция-по-лицензии — которые и сами по себе не лучшие представители игровой биосферы —...
Обратная связь | RSS | Донейт | Статистика | Команда | Техническая поддержка