О чем этот пример
Визуальные эффекты — ключ к созданию атмосферы в игре. Шейдеры позволяют реализовать сложные динамические эффекты, такие как огонь, вода, искажения и свечение, напрямую на видеокарте, что даёт огромную производительность. Эта статья покажет, как просто и быстро загрузить готовый GLSL шейдер и отрисовать его в Phaser 3, добавив в ваш проект эффект огненного шара или любой другой пиксельной магии.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.glsl('fireball', 'assets/shaders/shader0.frag');
}
create ()
{
this.add.shader('fireball', 400, 300, 800, 600);
}
}
const config = {
type: Phaser.WEBGL,
parent: 'phaser-example',
width: 800,
height: 600,
scene: Example
};
const game = new Phaser.Game(config);
Базовый принцип: шейдер как игровой объект
В Phaser шейдер — это полноценный игровой объект (Game Object), который можно добавить на сцену, как спрайт или текст. Это реализовано через класс Phaser.GameObjects.Shader. Для его создания используется метод this.add.shader(). Внутри него работает фрагментный шейдер (Fragment Shader), написанный на языке GLSL, который вычисляет цвет каждого пикселя в своей области. Это открывает возможности для процедурной генерации текстур, пост-обработки и динамических эффектов, не загружая CPU.
Ключевое отличие от обычных текстур: шейдер генерирует изображение программно в реальном времени по заданным математическим формулам.
Шаг 1: Загрузка шейдерного кода в preload()
Код шейдера обычно хранится в отдельном файле с расширением .frag (фрагментный шейдер) или .glsl. Для его загрузки используется специальный загрузчик load.glsl(). Важно указать корректный базовый URL, если файлы находятся на удалённом сервере.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.glsl('fireball', 'assets/shaders/shader0.frag');
}
Здесь мы делаем две операции:
1. setBaseURL() задаёт корневую папку для загрузки всех последующих ассетов.
2. load.glsl() загружает файл шейдера. Первый аргумент ('fireball') — это уникальный ключ (key), по которому мы будем обращаться к шейдеру позже. Второй аргумент — путь к файлу относительно базового URL.
Шаг 2: Создание и добавление шейдера в create()
После загрузки всех ресурсов в методе create() мы можем создать визуальное представление нашего шейдера. Для этого используется метод this.add.shader().
create ()
{
this.add.shader('fireball', 400, 300, 800, 600);
}
Разберём параметры:
- 'fireball' — ключ, под которым был загружен шейдерный код.
- 400, 300 — координаты X и Y центра шейдера на сцене.
- 800, 600 — ширина и высота области отрисовки шейдера. В нашем примере они совпадают с размерами холста, поэтому шейдер займёт весь экран.
Шаг 3: Конфигурация движка (Важный нюанс!)
Поскольку шейдеры требуют доступа к WebGL контексту, тип рендерера в конфигурации игры **обязательно** должен быть Phaser.WEBGL. При использовании Phaser.CANVAS шейдеры работать не будут.
const config = {
type: Phaser.WEBGL, // Используем WebGL рендерер
parent: 'phaser-example',
width: 800,
height: 600,
scene: Example
};
const game = new Phaser.Game(config);
Это критически важный момент. Если ваш проект уже использует Canvas, переключение на WEBGL может потребовать проверки совместимости других элементов, но откроет путь к современной графике.
Что попробовать дальше
Как видите, для добавления сложного шейдерного эффекта в Phaser 3 требуется всего несколько строк кода. Механика load.glsl() + add.shader() инкапсулирует всю низкоуровневую работу с WebGL. Для экспериментов попробуйте изменить размеры и позицию шейдера, наложить несколько шейдеров друг на друга или найти в открытых источниках другие готовые шейдеры (например, эффект воды, плазмы или шума) и подгрузить их по той же схеме.
