Привязка текстуры к спрайту

В основе рендеринга в PixiJS лежит связка текстура → спрайт → сцена. Текстура (PIXI.Texture) представляет собой область изображения, которая может быть отображена на экране. Спрайт (PIXI.Sprite) — это отображаемый объект сцены, использующий текстуру как источник пикселей.

Текстура может быть:

  • создана из отдельного файла изображения;
  • получена из атласа текстур;
  • сформирована из BaseTexture;
  • сгенерирована программно (например, из RenderTexture или Graphics).

Связь текстуры со спрайтом определяет внешний вид графического объекта, его размеры, масштабирование, поворот и прочие визуальные свойства.


Создание текстуры

Загрузка изображения

Наиболее распространённый способ — создание текстуры из файла:

const texture = PIXI.Texture.from('assets/player.png');

Метод Texture.from() автоматически:

  1. Создаёт BaseTexture (если он ещё не существует).
  2. Кэширует текстуру.
  3. Подготавливает её к использованию в WebGL или Canvas.

BaseTexture хранит реальный источник данных (HTMLImageElement, видео, canvas и т.д.), а Texture описывает конкретную область внутри этого источника.


Использование атласа текстур

При работе с игровыми проектами часто применяется атлас — одно большое изображение с набором спрайтов. Загрузка выполняется через PIXI.Assets:

await PIXI.Assets.load('assets/atlas.json');
const texture = PIXI.Texture.from('player_idle');

В этом случае:

  • JSON-файл содержит координаты фреймов;
  • текстура ссылается на область внутри общего BaseTexture;
  • экономится память и уменьшается количество переключений текстур в GPU.

Создание спрайта с текстурой

После получения текстуры она привязывается к спрайту:

const sprite = new PIXI.Sprite(texture);
app.stage.addChild(sprite);

Или сокращённый вариант:

const sprite = PIXI.Sprite.from('assets/player.png');

Sprite.from() объединяет создание текстуры и спрайта в один шаг.


Механизм привязки текстуры

При создании спрайта происходит следующее:

  1. Спрайт сохраняет ссылку на объект Texture.
  2. Вычисляются локальные размеры (width, height) на основе размеров текстуры.
  3. При рендеринге передаются UV-координаты в шейдер.
  4. GPU использует BaseTexture для выборки пикселей.

Важно понимать: несколько спрайтов могут использовать одну и ту же текстуру, что значительно снижает расход памяти.

const texture = PIXI.Texture.from('enemy.png');

const enemy1 = new PIXI.Sprite(texture);
const enemy2 = new PIXI.Sprite(texture);

В данном примере в память загружается одно изображение, но создаются два независимых объекта сцены.


Замена текстуры у существующего спрайта

Текстуру можно изменить динамически:

sprite.texture = PIXI.Texture.from('player_jump.png');

При этом:

  • автоматически пересчитываются размеры (если не были зафиксированы вручную);
  • обновляются UV-координаты;
  • объект остаётся в сцене.

Если требуется сохранить прежние размеры, используется установка размеров после смены текстуры:

const oldWidth = sprite.width;
const oldHeight = sprite.height;

sprite.texture = newTexture;

sprite.width = oldWidth;
sprite.height = oldHeight;

Область кадра (frame) и обрезка текстуры

Texture может отображать не всё изображение, а только его часть. Это особенно важно при работе с атласами.

Пример создания текстуры из части изображения:

const baseTexture = PIXI.BaseTexture.from('spritesheet.png');
const rectangle = new PIXI.Rectangle(0, 0, 64, 64);
const texture = new PIXI.Texture(baseTexture, rectangle);

const sprite = new PIXI.Sprite(texture);

В этом случае:

  • BaseTexture хранит всё изображение;
  • Rectangle определяет область;
  • Texture связывает их.

Такой подход позволяет создавать множество текстур из одного графического файла без дублирования данных.


Масштабирование и исходный размер текстуры

Размеры спрайта по умолчанию равны размерам текстуры:

console.log(sprite.width, sprite.height);

Для изменения масштаба применяется свойство scale:

sprite.scale.set(2);      // увеличение в 2 раза
sprite.scale.x = 1.5;
sprite.scale.y = 0.5;

Изменение width и height фактически изменяет масштаб относительно исходного размера текстуры.


Anchor и влияние текстуры на позиционирование

Текстура определяет геометрию спрайта, а свойство anchor — точку привязки:

sprite.anchor.set(0.5);

Значения:

  • (0, 0) — левый верхний угол;
  • (0.5, 0.5) — центр;
  • (1, 1) — правый нижний угол.

Позиция спрайта (x, y) рассчитывается относительно точки anchor, а значит, размеры текстуры напрямую влияют на итоговое размещение объекта.


Фильтрация и режимы масштабирования

Текстура поддерживает разные режимы фильтрации:

texture.baseTexture.scaleMode = PIXI.SCALE_MODES.NEAREST;

Основные режимы:

  • LINEAR — сглаживание;
  • NEAREST — пиксельная резкость (актуально для ретро-графики).

Режим фильтрации влияет на то, как GPU интерполирует пиксели при масштабировании.


Повторение текстуры (tiling)

Обычный спрайт отображает текстуру один раз. Для повторяющейся текстуры используется TilingSprite:

const tilingSprite = new PIXI.TilingSprite(texture, 800, 600);

Особенности:

  • текстура повторяется по ширине и высоте;
  • можно изменять смещение через tilePosition;
  • используется для фонов и параллакса.

Управление жизненным циклом текстуры

PixiJS кэширует текстуры. При длительной работе приложения необходимо освобождать ресурсы:

texture.destroy(true);

Параметр true указывает на уничтожение связанного BaseTexture.

Если текстура используется несколькими спрайтами, преждевременное уничтожение приведёт к ошибкам рендеринга.


Кэширование и повторное использование

Texture.from() использует внутренний кэш. Повторный вызов с тем же путём возвращает уже созданный объект:

const t1 = PIXI.Texture.from('hero.png');
const t2 = PIXI.Texture.from('hero.png');

console.log(t1 === t2); // true

Это поведение:

  • снижает нагрузку на память;
  • предотвращает повторную загрузку изображения;
  • упрощает управление ресурсами.

Асинхронная загрузка и гарантии готовности текстуры

При использовании PIXI.Assets рекомендуется дожидаться загрузки:

await PIXI.Assets.load('player.png');
const sprite = PIXI.Sprite.from('player.png');

Без ожидания возможно создание спрайта до полной инициализации текстуры, что приведёт к временной нулевой ширине и высоте.


Рендеринг и GPU-представление

В процессе рендеринга:

  1. PixiJS группирует спрайты по BaseTexture.
  2. Формируются батчи (batching).
  3. Передаются данные вершин и UV.
  4. GPU выполняет выборку текстур в шейдере.

Минимизация количества различных текстур в кадре повышает производительность за счёт уменьшения переключений текстурных блоков.


Практическая схема работы

Типовой алгоритм привязки текстуры к спрайту:

  1. Загрузка изображения или атласа.
  2. Создание Texture.
  3. Создание Sprite.
  4. Добавление в контейнер или сцену.
  5. Настройка позиции, масштаба, anchor.
  6. Рендеринг в цикле обновления.

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