Пятница, 27.12.2024, 18:44
Приветствую Вас Гость | RSS

Za1cev.ucoz.net

..::МЕНЮ::..

..::КАТЕГОРИИ::..

-Случайные статьи-

..::ОПРОСНИК::..

Кто вы?
Всего ответов: 6

..::Мини-Чат::..

Подборка статей и уроков

Главная » Статьи » Создание игр

Game Maker Studio: Шейдеры (Часть 3)
http://za1cev.ucoz.net/publick/97060615.jpg

В двух предыдущих частях мы довольно неплохо освоили владение цветом, а так же научились влиять на шейдер извне, что позволило нам создать шейдер с постепенным изменением цветов текстуры. Однако, помимо цвета пикселя, у него есть еще одна важная для нас информация – координаты. Получив место расположения пикселя и манипулируя с ним, мы можем менять не только цвета, но и саму структуру изображения.
В шейдере точка представлена 2-компонентным вектором. В первой части мы уже сталкивались с этими координатами, когда разбирали структура стандартного шейдера, который создает GMS.

На вкладке Fragment эти координаты представлены строкой:

Код
varying vec2 v_vTexcoord;


Так же, как и у 4-компонентного вектора цвета, мы может обращаться к каждому из компонентов, мы может обратиться и к координатам. Не сложно догадаться, что два компонента, который имеет вектор v_vTexcoord – это координаты x и y. Для примера, давайте обратимся к этим координатам и перепишем их в переменные:

Код
float x1 = v_vTexcoord.x;
float y1 = v_vTexcoord.y;


Теперь x1 и y1 содержат в себе координаты текущего пикселя текстуры, что равносильно координатам v_vTexcoord.x и v_vTexcoord.y, все просто.
Следует отметить, что подобно цветам, координаты лежат в диапазоне от 0 до 1, следовательно точки на вершинах имеют координаты 0:0, 0:1, 1:0 и 1:1.

Пришло время посмотреть, как это все работает на практике. Начнем мы с малого – попробуем вывести на экран лишь часть изображения, обрезав его слева и справа.

Делается подобное элементарно. На словах это выглядит так: если координата пикселя по x больше определенного значения или координата пикселя по x меньше определенного значения, то рисуем этот пиксель. На деле же мы имеем всего две строчки:

Код
if (v_vTexcoord.x > 0.4 && v_vTexcoord.x < 0.6)
gl_FragColor = texture2D(gm_BaseTexture, v_vTexcoord);


Таким образом, будут выводиться только пиксели, попадающие в диапазон от 0.4 до 0.6.
Как видите, в координатах тоже нет ничего особо сложного, главное придумать, как их применить. И придумал я следующее: как насчет того, чтобы сделать прозрачной часть текстуры определенного радиуса в месте, куда указывает курсор!?

Прозрачная область.


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

Код
vec3 Color = texture2D(gm_BaseTexture, v_vTexcoord).rgb;


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

Вместо того, чтобы перебирать каждый отдельный компонент через texture2D(gm_BaseTexture, v_vTexcoord).r, texture2D(gm_BaseTexture, v_vTexcoord).g и texture2D(gm_BaseTexture, v_vTexcoord).b, мы просто взяли все их сразу texture2D(gm_BaseTexture, v_vTexcoord).rgb.
Аналогично, можно поступить и с координатами. Выше, мы брали каждую координату по отдельности, а теперь давайте просто перепишем обе координаты в 2-компонетный вектор:

Код
vec2 coords = v_vTexcoord.xy;


В данной ситуации, действие это, как вы понимаете, особого смысла не имеет. Мы просто переписали один 2-компонентный вектор в другой. Но в дальнейшем, подобная операция может пригодиться, потому усвоим ее.

Так как положение прозрачной области будет зависеть от координат мыши, нам необходимо принимать эти координаты извне, чтобы работать с ними в шейдере. С подобным мы уже сталкивались в прошлой части, тут все делаем аналогично. Перед функцией main() задаем две переменные, в которые будем передавать координаты положения курсора:

Код
uniform float xMouse;
uniform float yMouse;


Эти координаты мы так же можем представить, как 2-компонентный вектор.

Код
vec2 mouse_coords = vec2(xMouse,yMouse);


По аналогии с координатами пикселя, к координатам мыши теперь можно обращаться через mouse_coords.x и mouse_coords.y. На самом деле, для наших текущих целей, для этого нет особой необходимости, ведь мы может с таким же успехом обращаться к координатам не через вектор, а напрямую, т.к. mouse_coords.x = xMouse, а mouse_coords.y = yMouse, но для закрепления материала, поработаем с вектором.
И так, координаты мыши у нас имеются, координаты пикселей тоже, осталось лишь задать радиус прозрачной области. Для удобства, запишем его в виде переменной.

Код
float radius = 0.2;


Следует учитывать, что раз координаты на текстуре находятся в диапазоне от 0 до 1, то и радиус должен быть в том же диапазоне.
Осталось лишь определить, входит ли текущая точка на текстуре в заданный радиус вокруг указателя мыши. Проще говоря – принадлежит ли точка окружности. Если принадлежит, то делаем текущий пиксель прозрачным, если нет, то выводим его с изначальной альфой.

Открываем учебник по геометрии и смотрим, как проверить принадлежность точки к окружности. Для этого существует следующее условие: (x-x0)^2 + (y-y0)^2 <= R^2, где (х0,у0) - центр окружности, R - её радиус, а (х,у) – проверяемая точка.
Все необходимые данные у нас имеются, остается только составить понятное для системы условие.

Код
if ((pow((coords.x - mouse_coords.x),2.0) + pow((coords.y - mouse_coords.y),2.0)) < pow(radius,2.0))


Думаю, объяснять тут ничего не нужно. Единственное, что следует уточнить, это функция pow(), которая возводит число в указанную степень, в нашем случае 2.0.

Дело за малым, указать, что произойдет, если условие истинно, и что будет, если оно ложно.

Код
if ((pow((coords.x - mouse_coords.x),2.0) + pow((coords.y - mouse_coords.y),2.0)) < pow(radius,2.0))
gl_FragColor = vec4(Color, 0.5);
else
gl_FragColor = texture2D(gm_BaseTexture, coords);


Как видите, если условие выполняется, то мы выводим текущий пиксель с исходными цветами, то изменяем его прозрачность на 0.5. В противном случае, мы просто выводим текстуру, как она есть.

Остается применить наш шейдер на практике. Создадим новый спрайт, часть которого будем делать прозрачной. При работе с координатами нужно учитывать один момент: спрайт должен быть представлен текстурой, а текстура должна иметь размер, кратный двум. Т.е. ширина и высота спрайта должны соответствовать 32х32, 64х64, 128х128 и т.д. При этом, при создании спрайта, следует установить галочку used for 3D (опция эта будет доступна, только если размер спрайта проставлен в соответствии с вышеизложенным правилом).

Создадим новый объект, установим для него наш спрайт и поместим объект в комнату. Для наглядности, можно установить в комнате какую-нибудь фоновую картинку.

В событии Draw нашего объекта прописываем следующее:

Код
var xMouse = shader_get_uniform(shader0,"xMouse");
var yMouse = shader_get_uniform(shader0,"yMouse");

shader_set(shader0);
shader_set_uniform_f(xMouse,mouse_x/sprite_width);
shader_set_uniform_f(yMouse,mouse_y/sprite_height);
draw_sprite(sprite0,0,0,0);
shader_reset();


Тут вам все уже знакомо по прошлым частям. Мы создаем переменную, которая хранит изменяемое значение в шейдере и задаем этому значению координаты мыши. Заметьте, что координаты мыши мы делим на размеры спрайта. Вспоминаем, как у нас представлены координаты текстуры в шейдере и все становится понятно, координаты мыши должны быть так же в диапазоне от 0 до 1.

Теперь можно запустить приложение и насладиться результатом. Вот такую интересную штучку сделал я, благодаря данному шейдеру, как видите, получился своеобразный "эффект рентгена":
http://za1cev.ucoz.net/publick/43527497.jpg

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

На этом все. Дальше - больше. Спасибо за внимание.

Категория: Создание игр | Добавил: Martin (09.09.2013)
Просмотров: 2006 | Теги: Game Maker Studio, GameMaker Studio, шейдеры, Уроки, GM, Графика, статьи, GMS, Shader, GameMaker | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]

.::РЕГИСТРАЦИЯ::.

....::ПОИСК::....

..::Статистика:..

Статистика материалов:


Пользователи он-лайн:


Онлайн всего: 1
Гостей: 1
Пользователей: 0

.::Сегодня были::.

..::Кнопки::..