Среда, 24 Апреля 2024, 03:15

Приветствую Вас Гость

Меню сайта
Категории каталога
Создание игр [355]
Статьи об общих понятиях связанных с созданием игр.
Программирование [82]
Гайды по программированию на разных ЯП.
Движки и Гейммейкеры [145]
Статьи о программах для создания игр, уроки и описания.
Софт [43]
Различные программы, в том числе в помощь игроделам.
2D-графика [14]
Уроки по рисованию, растр, пиксель-арт, создание спрайтов и пр.
3D-графика [16]
Уроки по моделированию, ландшафт, модели, текстурирование и пр.
Моддинг игр [5]
Модификация компьютерных игр, создание дополнений, перевод, хакинг.
Игры [161]
Статьи об играх, в том числе и сделанных на гейммейкерах.
Разное [129]
Статьи, которые не вошли в определённые разделы.
Наш опрос
На какую платформу/систему создаёте игры?
Всего ответов: 10677
Главная » Статьи » Создание игр

Game Maker Studio: Шейдеры (Часть 3)


В двух предыдущих частях мы довольно неплохо освоили владение цветом, а так же научились влиять на шейдер извне, что позволило нам создать шейдер с постепенным изменением цветов текстуры. Однако, помимо цвета пикселя, у него есть еще одна важная для нас информация – координаты. Получив место расположения пикселя и манипулируя с ним, мы можем менять не только цвета, но и саму структуру изображения.
В шейдере точка представлена 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.

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

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

Делается подобное элементарно. На словах это выглядит так: если координата пикселя по 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. В противном случае, мы просто выводим текстуру, как она есть.

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

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

В событии 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.

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



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

На этом все. Дальше - больше. Спасибо за внимание.
Категория: Создание игр | Добавил: LunarPixel (06 Сентября 2013)
Просмотров: 8570 | Комментарии: 8 | Рейтинг: 4.3/9 |
Теги: Game Maker Studio, GameMaker Studio, шейдеры, уроки, GM, графика, Статьи, GMS, gamemaker, Shader
Дополнительные опции:
Также если вы считаете, что данный материал мог быть интересен и полезен кому-то из ваших друзей, то вы бы могли посоветовать его, отправив сообщение на e-mail друга:

Игровые объявления и предложения:
Если вас заинтересовал материал «Game Maker Studio: Шейдеры (Часть 3)», и вы бы хотели прочесть что-то на эту же тему, то вы можете воспользоваться списком схожих материалов ниже. Данный список сформирован автоматически по тематическим меткам раздела. Предлагаются такие схожие материалы: Если вы ведёте свой блог, микроблог, либо участвуете в какой-то популярной социальной сети, то вы можете быстро поделиться данной заметкой со своими друзьями и посетителями.

Всего комментариев: 8
+0-
8 Dva_Kota   (09 Февраля 2014 01:53) [Материал]
Dva_KotaЕсли заменить
Код
gl_FragColor = vec4(Color, 0.5);

на
Код
gl_FragColor = vec4(color, (1.0/pow(radius,2.0))*(pow((v_vTexcoord.x - xMouse),2.0) + pow((v_vTexcoord.y - yMouse),2.0)));

То получим прозрачную окружность, прозрачность которой на краях равна 1.

+1-
5 First   (21 Октября 2013 23:10) [Материал]
FirstЭто под картинку девушки еще спрайт скелета нужно всовывать, а делать прозрачность самой девченки, что бы скелет было видно?

+1-
6 LunarPixel   (03 Ноября 2013 13:52) [Материал]
LunarPixelДа smile

+2-
4 LunarPixel   (14 Сентября 2013 17:04) [Материал]
LunarPixelЗавтра постараюсь выложить четвертую часть. Всего их будет 5 или 6.

+2-
3 GameLoper   (13 Сентября 2013 11:04) [Материал]
GameLoperжду новых уроков ....

+3-
1 Eshford   (09 Сентября 2013 13:03) [Материал]
EshfordСпасибо. Вчера ночью попробовал первое, получилось. Теперь можно хоть хелтбары нормальные делать, с альфа обрезанием.
Со вторым почему-то возникла проблемы, которая мне пока не понятно, но я сегодня ещё поковыряюсь.

+4-
2 LunarPixel   (09 Сентября 2013 17:37) [Материал]
LunarPixelСпрашивай, если что, отвечу на вопросы. Может я чего упустил и не дописал, поправлю тогда.

+2-
7 idVORON   (01 Января 2014 20:47) [Материал]
idVORONМожна исходник? smile

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Поиск по сайту
10 случ. движков
  • TDG
  • WindMill
  • GamePlay
  • Ultra Engine
  • Free Heroes
  • Arcade Game Studio
  • vbGORE
  • Dahlia
  • Murl
  • Gideros Studio
  • Друзья сайта
    Игровой форум GFAQ.ru Перевод консольных игр
    Все права сохранены. GcUp.ru © 2008-2024 Рейтинг