Встроенный DisplacementFilter

DisplacementFilter в PixiJS является мощным инструментом для создания визуальных эффектов, основанных на смещении пикселей текстуры относительно карты смещения (displacement map). Этот фильтр часто используется для имитации волн на воде, искажений в воздухе, эффектов воды, жидкостей или динамичных текстурных трансформаций.


Принцип работы

DisplacementFilter работает на основе карты смещения — текстуры, которая определяет, насколько каждый пиксель исходного изображения смещается по координатам X и Y. Цветовые каналы карты (обычно красный и зелёный) преобразуются в смещение пикселей:

  • Красный канал (R) — смещение по оси X.
  • Зелёный канал (G) — смещение по оси Y.

Фильтр использует значения каналов в диапазоне [0, 255] и масштабирует их с помощью свойства scale, которое задаёт силу смещения.

Формула смещения для пикселя может быть выражена так:

newX = originalX + (redChannelValue / 255 - 0.5) * scaleX
newY = originalY + (greenChannelValue / 255 - 0.5) * scaleY

Где scaleX и scaleY — коэффициенты, определяющие интенсивность искажения.


Создание DisplacementFilter

Для использования фильтра требуется две текстуры:

  1. Основная текстура, к которой будет применён фильтр.
  2. Текстура смещения, задающая шаблон искажения.

Пример создания фильтра:

const app = new PIXI.Application({ width: 800, height: 600 });
document.body.appendChild(app.view);

const baseSprite = PIXI.Sprite.from('assets/image.png');
app.stage.addChild(baseSprite);

const displacementTexture = PIXI.Texture.from('assets/displacement.png');
const displacementSprite = new PIXI.Sprite(displacementTexture);
displacementSprite.texture.baseTexture.wrapMode = PIXI.WRAP_MODES.REPEAT;
app.stage.addChild(displacementSprite);

const displacementFilter = new PIXI.filters.DisplacementFilter(displacementSprite);
displacementFilter.scale.set(50, 50);

baseSprite.filters = [displacementFilter];

Ключевые моменты:

  • texture.baseTexture.wrapMode = PIXI.WRAP_MODES.REPEAT позволяет текстуре смещения повторяться за пределами исходного изображения, что обеспечивает плавное непрерывное искажение.
  • Свойство scale управляет интенсивностью смещения по осям X и Y.
  • DisplacementFilter должен ссылаться на отдельный спрайт, который добавляется в сцену, даже если он не видим.

Анимация эффекта

DisplacementFilter часто используют с анимацией текстуры смещения. Например, для имитации движения воды можно сдвигать спрайт displacement:

app.ticker.add((delta) => {
    displacementSprite.x += 2 * delta;
    displacementSprite.y += 1 * delta;
});

Такое движение текстуры создаёт иллюзию динамичного искажения на основном изображении.


Настройка и оптимизация

  • scale: Увеличение значений scale приводит к более заметным искажениям, уменьшение — к мягким эффектам.
  • anchor: Настройка anchor displacementSprite влияет на точку отсчёта смещения.
  • wrapMode: Для циклической анимации использовать WRAP вместо CLAMP предотвращает резкие обрывы при движении карты смещения.
  • размер текстуры: Чем больше разрешение displacement map, тем точнее эффект, но выше нагрузка на GPU.

Использование с другими фильтрами

DisplacementFilter можно комбинировать с другими фильтрами PixiJS, такими как:

  • BlurFilter — создаёт эффект размытия и смягчает искажения.
  • ColorMatrixFilter — позволяет менять цветовую палитру в процессе деформации.
  • ShockwaveFilter — используется для эффекта ударной волны с дополнительным смещением.

Комбинация фильтров выполняется через массив:

baseSprite.filters = [displacementFilter, new PIXI.filters.BlurFilter(4)];

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


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

  1. Для плавных циклических эффектов displacementSprite лучше перемещать с помощью tilePosition при использовании TilingSprite.
  2. Цветовые каналы карты смещения можно программно генерировать через Canvas, чтобы создавать динамические и анимированные деформации.
  3. В WebGL-проектах PixiJS DisplacementFilter работает быстрее, если текстура смещения загружается как Power-of-Two (например, 512x512, 1024x1024), что оптимизирует использование GPU.
  4. Для интерактивных эффектов можно привязать смещение к движению мыши, джойстика или сенсорного ввода:
app.renderer.plugins.interaction.on('mousemove', (event) => {
    displacementFilter.scale.x = (event.data.global.x - app.screen.width/2) / 10;
    displacementFilter.scale.y = (event.data.global.y - app.screen.height/2) / 10;
});

DisplacementFilter остаётся одним из самых гибких фильтров PixiJS для создания визуально выразительных эффектов, сочетая GPU-оптимизированные вычисления с простым интерфейсом управления смещением. Его применение открывает широкий спектр художественных и интерактивных решений для веб-графики и игр.