Открыть Электронные книги
Категории
Открыть Аудиокниги
Категории
Открыть Журналы
Категории
Открыть Документы
Категории
Game Development
Shaders
Difficulty:IntermediateLength:LongLanguages:
ShadersGLSLShaderToyGPUGame Graphics
This post is part of a series called A Beginner's Guide to Coding Graphics Shaders.
Russian (Pусский) translation by Anton Voronin (you can also view the original English
article)
Это урок общего назначения, поэтому вы сможете применить свои знания на любой
платформе, поддерживающей шейдеры.
Итак, приступим!
Для данного урока мы будем использовать ShaderToy. Этот ресурс позволяет писать
шейдеры прямо в вашем браузере, не утруждая себя никакими дополнительными
настройками. (Однако для использования ShaderToy вам понадобится браузер с
поддержкой WebGL, поскольку именно он используется для рендеринга.) Регистрация
не обязательна, однако она позволит сохранить свой код на будущее в профиле.
Это все, что делает шейдер. Функция, которую вы видите в редакторе, выполняется для
каждого пикселя на экране. Она возвращает 4 цветовых значения, которые
присваиваются текущему пикселю на экране. Это то, что называют пиксельным
шейдером (иногда его еще называют фрагментным шейдером).
fragColor = vec4(1.0,0.0,0.0,1.0);
}
Поздравляю! Вот вы и написали свой первый работающий шейдер!
vec4 - это тип данных (четырехмерный вектор), поэтому мы могли бы записать цвет в
переменную типа vec4 и передать ее значение во fragColor:
fragColor = solidRed;
Давайте попробуем заполнить экран градиентом. У нас не получится это сделать, если
мы не знаем координат пикселя, на цвет которого мы хотим воздействовать.
vec2 xy = fragCoord.xy; //We obtain our coordinates for the current pixel
if(xy.x > 300.0){//Arbitrary number, we don't know how big our screen is!
fragColor = solidRed;
Давайте улучшим наш код так, чтобы он корректно распознавал, где находится центр
экрана. Нам потребуется использовать переменную iResolution из вкладки Shader
Inputs:
01
02
03
04
05
06
07
08
09
10
11
12
vec2 xy = fragCoord.xy; //We obtain our coordinates for the current pixel
xy.x = xy.x / iResolution.x; //We divide the coordinates by the screen size
// Now x is 0 for the leftmost pixel, and 1 for the rightmost pixel
fragColor = solidRed;
Если перейти в полноэкранный режим в этот раз, то теперь экран будет разделен
цветами ровно пополам.
Переходим к градиенту.
01
02
03
04
05
06
07
08
09
10
void mainImage( out vec4 fragColor, in vec2 fragCoord )
vec2 xy = fragCoord.xy; //We obtain our coordinates for the current pixel
xy.x = xy.x / iResolution.x; //We divide the coordinates by the screen size
// Now x is 0 for the leftmost pixel, and 1 for the rightmost pixel
fragColor = solidRed;
Вуаля!
Рисуем картинки
Если бы мы писали обычный шейдер, то наше изображение (или текстуру) нужно было
бы передавать в GPU как uniform переменную, также как и информацию о
разрешении/размерах экрана. ShaderToy же позаботился обо всем за нас. Внизу
редактора есть четыре канала входящих данных:
Итак, если мы можем возвращать значение цвета каждого пикселя, как же нам
нарисовать нашу текстуру? Нам нужно каким-то образом соотнести координаты
текущего обрабатываемого пикселя с соответствующим пикселем текстуры:
Также вспомним, что левый верхний пиксель экрана имеет координаты (0,1), в то
время как левый верхний пиксель текстуры имеет координаты (0,0), поэтому прежде
всего нам необходимо перевернуть ось y.
Сейчас нам важно просто увидеть изображение на экране, поэтому будем соотносить
все пиксели один к одному:
4
5
texColor.b = xy.x;
01
02
03
04
05
06
07
08
09
10
texColor.r *= abs(sin(iGlobalTime));
texColor.g *= abs(cos(iGlobalTime));
В GLSL есть встроенные функции синуса и косинуса, так же как и множество других
полезных функций, таких как длина вектора или расстояние между векторами. Цвет не
может принимать отрицательное значение, поэтому нужно использовать встроенную
функцию abs, которая возвращает абсолютное значение (модуль) числа без учета
знака.
Заключение
Есть одна вещь, которая не освещена в этой статье - это вертексные шейдеры. Их пишут
на том же самом языке, единственная разница состоит в том, что они выполняются не
попиксельно, а (как понятно из названия) на каждой вершине, и возвращают не только
цвет, но и позицию вершины. Вертексные шейдеры обычно ответственны за
проецирование и отрисовку 3D-сцены на экране (возмжоность, встроенная в
большинство графических движков). Пиксельные же шейдеры ответственны за
создание продвинутых визуальных эффектов, именно поэтому мы обратили основное
внимание именно на них.
Финальная задача: Сможете ли вы написать шейдер, который удаляет зеленый экран
из видео на ShaderToy и вставляет вместо него другое видео на заднем плане?
На этом все! Обратная связь и вопросы горячо приветствуются. Вопросы можно также
задавать в комментариях. В следующих уроках будут освещены вопросы более
глубокой работы с цветом, а также основы систем освещения, в будущем также
возможны уроки по подготовке шейдеров для конкретных платформ или симуляция
жидкостей с помощью шейдеров.
Profile final
Omar Shehata
Northfield Minnesota
Currently a student at St. Olaf College in Northfield, Minnesota. Originally from Egypt. I've
been making games for over 7 years. I'm super passionate about building tools or crafting
experiences that make life a little better. I enjoy teaching, and am usually far more eloquent
on paper.
omar4ur
Subscribe below and we’ll send you a weekly email summary of all new Game Development
tutorials. Never miss out on learning about the next big thing.
Translations
Envato Tuts+ tutorials are translated into other languages by our community members—you
can be involved too!
envato-tuts+
Watch any
course now
Envato Tuts+
Advertise
Forums
Community Meetups
Help
FAQ
Help Center
envato-tuts+
23,429
Tutorials
991
Courses
5,584
Translations
Envato.comOur productsCareers
© 2017 Envato Pty Ltd. Trademarks and brands are the property of their respective owners.