О чем этот пример

Визуальные эффекты, применяемые к камере, — мощный инструмент для создания атмосферы в играх на Phaser. Они позволяют выделить важные объекты, передать состояние персонажа или просто добавить стиль сцене. В этом примере мы рассмотрим, как добавить эффект размытия по Гауссу к основной камере, при этом оставив один спрайт резким, используя систему фильтров и управление рендерингом через несколько камер.

Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.

Живой запуск

Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.

Исходный код


class Example extends Phaser.Scene
{
    constructor ()
    {
        super();
    }

    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.image('volcano', 'assets/pics/bw-face.png');
        this.load.image('hotdog', 'assets/sprites/hotdog.png');
    }

    create ()
    {
        const volcano = this.add.image(400, 300, 'volcano').setAlpha(0.5);
        const hotdog = this.add.image(400, 300, 'hotdog').setScrollFactor(0);

        this.cameras.main.filters.internal.addBlur();

        const extracam = this.cameras.add();

        this.cameras.main.ignore(hotdog);
        extracam.ignore(volcano);
    }
}

const config = {
    type: Phaser.WEBGL,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    backgroundColor: '#000000',
    scene: Example
};

const game = new Phaser.Game(config);

Загрузка ресурсов и настройка сцены

В методе preload загружаются два изображения, которые будут использоваться в примере. Одно — текстура фона, другое — спрайт, который должен оставаться резким.

preload ()
{
    this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
    this.load.image('volcano', 'assets/pics/bw-face.png');
    this.load.image('hotdog', 'assets/sprites/hotdog.png');
}

В методе create сначала добавляются оба изображения в центр сцены. Фоновое изображение получает полупрозрачность 0.5 с помощью метода .setAlpha(0.5). Спрайт хот-дога устанавливает свой scrollFactor в 0, что означает, что он не будет двигаться при прокрутке камеры и всегда будет оставаться на одном месте на экране.

create ()
{
    const volcano = this.add.image(400, 300, 'volcano').setAlpha(0.5);
    const hotdog = this.add.image(400, 300, 'hotdog').setScrollFactor(0);
    // ... дальнейший код
}

Применение фильтра размытия к основной камере

Ключевой момент — применение эффекта размытия. У каждой камеры в Phaser 3 есть свойство filters, которое содержит внутренний стэк фильтров. Метод addBlur() добавляет в этот стэк шейдерный фильтр размытия по Гауссу.

this.cameras.main.filters.internal.addBlur();

Этот вызов применяет эффект ко всему, что рендерится через основную камеру. Фильтр работает на уровне WebGL, обеспечивая плавное и производительное размытие. Важно помнить, что для работы фильтров необходимо использовать рендерер WEBGL, что указано в конфигурации игры (type: Phaser.WEBGL).

Разделение рендеринга с помощью двух камер

Если просто применить размытие ко всей сцене, размытым станет и спрайт хот-дога. Чтобы этого избежать, используется техника разделения рендеринга. Создается вторая камера с помощью this.cameras.add().

const extracam = this.cameras.add();

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

this.cameras.main.ignore(hotdog);
extracam.ignore(volcano);

В результате основная камера рендерит только фон (к которому применено размытие), а дополнительная камера рендерит только спрайт (который остается резким). Поскольку обе камеры смотрят на одну и ту же сцену и их изображения накладываются друг на друга, мы видим резкий хот-дог на размытом фоне.

Конфигурация игры и важные настройки

Для корректной работы примера критически важна конфигурация игры. Необходимо указать type: Phaser.WEBGL, так как фильтры камеры работают только в контексте WebGL. Canvas-рендерер их не поддерживает.

const config = {
    type: Phaser.WEBGL,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    backgroundColor: '#000000',
    scene: Example
};

Также обратите внимание на черный цвет фона (backgroundColor: '#000000'). Он обеспечивает чистый задний план, на котором хорошо видны оба изображения и эффект размытия.

Что попробовать дальше

Использование фильтров камеры, таких как addBlur(), в сочетании с управлением несколькими камерами открывает широкие возможности для пост-обработки в Phaser 3. Вы можете экспериментировать: добавлять другие фильтры из коллекции filters.internal (например, addGlow или addColorMatrix), динамически включать и выключать размытие в зависимости от игровых событий, или применять эффект не ко всей камере, а к отдельному слою объектов, создав для него специальную камеру.