Многостраничные атласы

Многостраничные атласы текстур (multi-page texture atlases) представляют собой набор изображений, объединённых в несколько страниц, каждая из которых представляет собой отдельный текстурный блок. В PixiJS они используются для оптимизации производительности рендеринга, так как позволяют уменьшить количество переключений текстур в GPU и упрощают управление большим количеством спрайтов.

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

Подключение и загрузка многостраничного атласа

PixiJS использует PIXI.Loader для загрузки атласов. Атлас обычно представлен в виде JSON-файла с описанием каждой текстуры и соответствующими страницами. Структура JSON может быть как TexturePacker, так и собственная, поддерживаемая PixiJS.

Пример загрузки:

const loader = new PIXI.Loader();

loader
  .add('characters', 'assets/characters.json')
  .load((loader, resources) => {
    const characterTextures = resources.characters.textures;
    const hero = new PIXI.Sprite(characterTextures['hero_idle_0.png']);
    app.stage.addChild(hero);
  });

Особенности загрузки:

  • Все страницы атласа загружаются автоматически через JSON.
  • Каждая текстура атласа доступна по имени.
  • Разделение на страницы скрыто для разработчика, что упрощает работу.

Работа с отдельными страницами

Хотя PixiJS скрывает работу с конкретными страницами, важно понимать, что каждая текстура всё равно связана с определённым PIXI.BaseTexture. В случае большого атласа с несколькими страницами можно получить доступ к базовым текстурам:

const baseTextures = Object.values(resources.characters.textures).map(tex => tex.baseTexture);
console.log('Количество базовых текстур (страниц):', new Set(baseTextures).size);

Это полезно при отладке или оптимизации использования видеопамяти, особенно если атлас содержит сотни спрайтов.

Анимации с многостраничными атласами

Многостраничные атласы часто применяются для создания спрайтовых анимаций. PixiJS поддерживает PIXI.AnimatedSprite, где кадры могут быть распределены по разным страницам:

const frames = [];
for (let i = 0; i < 10; i++) {
  frames.push(resources.characters.textures[`hero_run_${i}.png`]);
}

const heroRun = new PIXI.AnimatedSprite(frames);
heroRun.animationSpeed = 0.15;
heroRun.play();
app.stage.addChild(heroRun);

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

Оптимизация рендеринга

Несмотря на удобство многостраничных атласов, важно учитывать несколько принципов оптимизации:

  1. Минимизация количества страниц. Чем меньше страниц, тем меньше переключений текстур в GPU, что улучшает производительность.
  2. Группировка объектов по текстуре. Размещая на сцене объекты с одинаковой базовой текстурой рядом, можно снизить overhead рендеринга.
  3. Использование кэширования. Кэширование отдельных спрайтов и контейнеров помогает при сложных сценах, где много анимированных объектов.
const container = new PIXI.Container();
container.cacheAsBitmap = true; // кэширование контейнера с несколькими спрайтами

Инструменты генерации многостраничных атласов

Наиболее популярные инструменты для создания атласов с поддержкой нескольких страниц:

  • TexturePacker – позволяет экспортировать многостраничные JSON и поддерживает оптимизацию текстур.
  • Shoebox – бесплатный инструмент, подходит для простых атласов.
  • Free Texture Packer – открытое решение с возможностью генерации нескольких страниц и автоматической оптимизации.

При экспорте важно включать trim и rotation, так как PixiJS корректно обрабатывает смещённые и повернутые текстуры, что снижает расход видеопамяти.

Взаимодействие с фильтрами и масками

Каждая базовая текстура страниц атласа может использовать фильтры PixiJS, но следует помнить, что фильтры применяются к текстуре на этапе рендеринга:

const blurFilter = new PIXI.filters.BlurFilter();
hero.filters = [blurFilter];

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

Динамическое обновление текстур

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

const newTexture = PIXI.Texture.from('assets/new_hero.png');
hero.texture = newTexture;

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

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

  • При большом количестве спрайтов использовать многостраничные атласы обязательно, иначе производительность падает.
  • При генерации атласа стараться балансировать размер страниц: слишком большие страницы расходуют видеопамять, слишком маленькие — создают много страниц и увеличивают overhead.
  • Для анимаций предусматривать одинаковую нумерацию кадров, чтобы легко создавать массивы текстур для AnimatedSprite.
  • Проверять загрузку всех страниц атласа перед рендерингом: loader.onComplete гарантирует, что все базовые текстуры готовы.

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