Повторное использование геометрии через GraphicsContext

В PixiJS объект Graphics используется для отрисовки примитивной геометрии: линий, фигур, кривых и текста. Однако постоянное создание новых объектов для каждой фигуры в больших сценах ведёт к значительным потерям производительности. Повторное использование графических ресурсов позволяет оптимизировать отрисовку и снизить нагрузку на GPU.


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

Graphics создаётся через конструктор:

const graphics = new PIXI.Graphics();

Для рисования используются методы вроде:

  • graphics.beginFill(color, alpha) — начинает заливку цветом;
  • graphics.lineStyle(width, color, alpha) — устанавливает параметры линии;
  • graphics.drawRect(x, y, width, height) — рисует прямоугольник;
  • graphics.drawCircle(x, y, radius) — рисует окружность;
  • graphics.endFill() — завершает заливку.

Каждое изменение свойств Graphics перезаписывает внутренний буфер, что при множественных объектах вызывает лишние вычисления.


Использование повторно одного Graphics объекта

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

graphics.clear();
graphics.beginFill(0xff0000);
graphics.drawCircle(100, 100, 50);
graphics.endFill();

Метод clear() удаляет предыдущие пути, сохраняя сам объект и его привязку к сцене. Это важно для динамических сцен, где фигуры меняются каждый кадр.


Кэширование геометрии через текстуры

Для сложной геометрии, которая не меняется, эффективнее создать текстуру один раз и использовать её многократно:

const graphics = new PIXI.Graphics();
graphics.beginFill(0x00ff00);
graphics.drawRect(0, 0, 200, 100);
graphics.endFill();

const texture = app.renderer.generateTexture(graphics);
const sprite = new PIXI.Sprite(texture);
sprite.position.set(300, 200);
app.stage.addChild(sprite);

Преимущества кэширования:

  • Отрисовка превращается в рендеринг спрайта, который GPU обрабатывает быстрее;
  • Можно использовать один и тот же texture для множества объектов.

Повторное использование при анимации

Для анимации часто применяют один Graphics объект с динамической геометрией. Пример: движение круга по траектории:

const circle = new PIXI.Graphics();
circle.beginFill(0x0000ff);
circle.drawCircle(0, 0, 50);
circle.endFill();
circle.x = 100;
circle.y = 100;
app.stage.addChild(circle);

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

Если необходимо изменять форму, лучше использовать clear() и перерисовывать фигуру на том же объекте, чем создавать новый Graphics.


GraphicsBatch и контейнеры

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

const container = new PIXI.Container();
for (let i = 0; i < 50; i++) {
    const g = new PIXI.Graphics();
    g.beginFill(0xffff00);
    g.drawRect(0, 0, 20, 20);
    g.endFill();
    g.x = i * 25;
    container.addChild(g);
}
app.stage.addChild(container);

Можно объединить графику в один Graphics, если геометрия однотипная, используя массив координат и циклы.


Практика оптимизации

  1. Минимизировать создание объектов — повторно использовать Graphics для динамических фигур.
  2. Кэшировать сложные формы в текстуры для многократного использования.
  3. Использовать контейнеры для групп объектов одного типа, чтобы задействовать batching.
  4. Очистка с clear() вместо удаления и создания новых объектов.
  5. Стараться объединять одинаковые стили (заливка, линии) для уменьшения переключений состояния GPU.

Важные методы для повторного использования

  • clear() — сбрасывает текущее содержимое Graphics;
  • beginFill(color, alpha) / endFill() — управляют заливкой;
  • lineStyle(width, color, alpha) — задаёт линии для всех последующих фигур;
  • generateTexture(renderer, scaleMode, resolution) — превращает графику в текстуру для повторного использования;
  • cacheAsBitmap = true — позволяет рендерить статичную графику как текстуру внутри рендерера без явного создания Texture.

Эффективные подходы к повторной геометрии

  • Повторная отрисовка в одном объекте: подходит для динамических сцен.
  • Кэширование текстур: оптимально для статичных фигур, которые нужно многократно отобразить.
  • Контейнеризация: позволяет объединять одинаковые элементы, улучшая batching.
  • Использование cacheAsBitmap: для объектов, которые не изменяются каждый кадр, превращая их в “живую текстуру” без дополнительных затрат GPU.

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