Stencil-маска и её особенности

Stencil-маски в PixiJS представляют собой мощный инструмент управления визуальным отображением объектов на сцене, позволяя создавать сложные эффекты обрезки и вырезания содержимого. В отличие от обычных масок, которые используют прозрачность спрайта или графического объекта, stencil-маски применяют буфер трафарета (stencil buffer), что обеспечивает более гибкий контроль над отображением и позволяет комбинировать несколько масок с высоким уровнем точности.

Основы работы stencil-масок

Stencil-маска определяется объектом PIXI.Graphics или любым другим графическим объектом, который можно отрисовать в WebGL. Она не использует пиксельную прозрачность для ограничения области, а работает через запись и проверку значений в stencil buffer. Это позволяет:

  • Создавать маски с прозрачными и непредсказуемыми формами, включая сложные кривые и пересекающиеся фигуры.
  • Использовать множественные маски одновременно, комбинируя их с помощью операций логического AND/OR.
  • Применять маски на группы объектов, объединяя их в PIXI.Container.

Stencil-маска активируется через свойство mask у объекта DisplayObject. Для stencil-масок необходимо установить тип маски через PIXI.MASK_TYPES.STENCIL. Пример базовой инициализации:

const graphics = new PIXI.Graphics();
graphics.beginFill(0xffffff);
graphics.drawCircle(100, 100, 50);
graphics.endFill();

const sprite = PIXI.Sprite.from('texture.png');
sprite.mask = graphics;
sprite.maskType = PIXI.MASK_TYPES.STENCIL;

В этом примере пиксельный контент sprite будет видим только внутри круга, определённого graphics.

Отличия stencil-масок от обычных масок

Основное отличие заключается в производительности и типе обработки:

  1. Производительность при больших сценах: stencil-маски требуют дополнительной работы с GPU, но позволяют обрабатывать более сложные комбинации объектов без необходимости модифицировать текстуры.
  2. Гибкость комбинирования: обычные маски в PixiJS применяются по принципу «перекрытия прозрачностью», а stencil-маски позволяют использовать логические операции между масками.
  3. Поддержка вложенных контейнеров: stencil-маска корректно работает с PIXI.Container, применяя ограничения ко всем дочерним объектам.

Управление stencil-масками

Stencil-маски поддерживают динамическое обновление формы. Любые изменения объекта Graphics автоматически отражаются на маске. Пример динамического эффекта:

app.ticker.add(() => {
    graphics.clear();
    graphics.beginFill(0xffffff);
    graphics.drawCircle(100, 100, 50 + 20 * Math.sin(app.ticker.lastTime / 500));
    graphics.endFill();
});

В этом случае видимая область sprite будет изменяться в зависимости от анимации радиуса круга, создавая эффект пульсации.

Использование нескольких stencil-масок

Для создания сложных эффектов можно комбинировать несколько stencil-масок. В PixiJS существует возможность использования maskStack, где каждая новая stencil-маска добавляется поверх предыдущей, а затем удаляется после отрисовки объекта. Пример:

const mask1 = new PIXI.Graphics().beginFill(0xffffff).drawRect(0, 0, 200, 200).endFill();
const mask2 = new PIXI.Graphics().beginFill(0xffffff).drawCircle(100, 100, 50).endFill();

container.mask = mask1;
container.maskType = PIXI.MASK_TYPES.STENCIL;

// Добавление второй маски поверх первой
container.addChild(mask2);
mask2.maskType = PIXI.MASK_TYPES.STENCIL;

При таком подходе объекты контейнера будут видны только в пересечении двух масок.

Особенности и ограничения

  • Не все фильтры совместимы с stencil-масками. Некоторые эффекты, особенно постэффекты типа PIXI.filters.BlurFilter, могут работать некорректно при наложении stencil-маски.
  • Stencil buffer ограничен глубиной GPU. На большинстве устройств глубина буфера составляет 8 бит, что накладывает ограничения на количество одновременно активных масок.
  • Применение к спрайтам с альфа-прозрачностью. Stencil-маска не учитывает прозрачность текстур; все пиксели в области маски будут полностью видимы. Для комбинированного эффекта прозрачности следует использовать обычную маску или фильтры.

Практические советы

  • Использовать PIXI.Graphics для создания форм маски вместо спрайтов с альфа-каналом для оптимизации производительности.
  • Для сложных анимационных эффектов маску можно обновлять каждый кадр с помощью ticker.
  • Комбинировать stencil-маски и фильтры осторожно, тестируя на разных устройствах, чтобы избежать артефактов.
  • При работе с большим количеством объектов применять контейнеры и назначать маску на контейнер, а не на каждый объект отдельно.

Stencil-маски обеспечивают высокий контроль над визуальной композицией сцены, позволяя создавать сложные эффекты обрезки и динамических областей видимости, недоступные при использовании стандартных масок на основе прозрачности. Их использование особенно эффективно для интерактивных приложений, игр и визуализаций с множеством наложенных графических объектов.