Geometry в PixiJS представляет низкоуровневую структуру
данных для описания геометрии объекта: вершин, индексов и произвольных
атрибутов, передаваемых в шейдеры. Этот класс используется совместно с
Mesh и позволяет полностью контролировать процесс
рендеринга через WebGL.
В отличие от Graphics, который ориентирован на векторную
отрисовку высокого уровня, Geometry работает напрямую с
буферами GPU. Это фундамент для создания кастомных мешей, систем частиц,
процедурной геометрии и нестандартных шейдерных эффектов.
Класс Geometry хранит:
Каждая геометрия описывает, как именно данные расположены в памяти GPU и как они должны интерпретироваться шейдером.
Основные компоненты:
Buffer — контейнер данных (обычно
Float32Array, Uint16Array и др.)Attribute — описание того, как читать данные из
буфераБазовое создание геометрии:
import { Geometry } from 'pixi.js';
const geometry = new Geometry();
Далее в неё добавляются атрибуты и индексы.
Атрибут — это описание данных, которые будут переданы в вершинный шейдер. Каждый атрибут связан с именем, совпадающим с именем переменной в GLSL.
Пример добавления позиции:
geometry.addAttribute(
'aPosition',
new Float32Array([
0, 0,
100, 0,
100, 100,
0, 100
]),
2
);
Метод addAttribute принимает:
id — имя атрибута (должно совпадать с GLSL)buffer — данные или экземпляр Buffersize — количество компонентов на вершину (2 для vec2, 3
для vec3)normalized — нормализовать ли данныеtype — тип данных (по умолчанию FLOAT)stride — шаг между вершинамиstart — смещениеМинимальный вариант:
geometry.addAttribute('aPosition', vertices, 2);
Если требуется более гибкий контроль, создаётся явный буфер:
import { Buffer } from 'pixi.js';
const vertexBuffer = new Buffer(new Float32Array([
0, 0,
100, 0,
100, 100,
0, 100
]));
geometry.addAttribute('aPosition', vertexBuffer, 2);
Буфер может быть:
const dynamicBuffer = new Buffer(data, true);
Второй аргумент true указывает, что буфер
динамический.
Обновление данных:
dynamicBuffer.update();
При работе с анимациями или частицами динамические буферы обязательны для производительности.
Без индексов каждые три вершины формируют отдельный треугольник. Индексы позволяют переиспользовать вершины.
Добавление индексов:
geometry.addIndex([
0, 1, 2,
0, 2, 3
]);
Или через типизированный массив:
geometry.addIndex(new Uint16Array([
0, 1, 2,
0, 2, 3
]));
Для сложной геометрии индексный буфер критически важен.
Геометрия может содержать произвольное количество атрибутов.
Пример с цветом:
geometry
.addAttribute('aPosition', vertices, 2)
.addAttribute('aColor', new Float32Array([
1, 0, 0,
0, 1, 0,
0, 0, 1,
1, 1, 0
]), 3);
Вершинный шейдер должен содержать:
attribute vec2 aPosition;
attribute vec3 aColor;
Каждый атрибут синхронизируется по индексу вершины.
Для оптимизации можно использовать один общий буфер, в котором данные чередуются.
Пример структуры:
[x, y, r, g, b, x, y, r, g, b, ...]
Создание:
const interleaved = new Float32Array([
0, 0, 1, 0, 0,
100, 0, 0, 1, 0,
100, 100, 0, 0, 1,
0, 100, 1, 1, 0
]);
const buffer = new Buffer(interleaved);
geometry
.addAttribute('aPosition', buffer, 2, false, undefined, 20, 0)
.addAttribute('aColor', buffer, 3, false, undefined, 20, 8);
stride = 20 байт (5 float × 4 байта)offset = 0 — позиция начинается с началаoffset = 8 — цвет начинается после двух float (2 × 4
байта)Interleaved-буферы:
Обновление массива:
vertices[0] += 1;
vertexBuffer.update();
Если геометрия динамическая, обновления отправляются в GPU без пересоздания буфера.
Для частых изменений рекомендуется:
Геометрия хранит GPU-ресурсы, поэтому важно освобождать память:
geometry.destroy();
Это удаляет связанные буферы и WebGL-объекты.
Geometry используется вместе с Mesh:
import { Mesh, Shader } from 'pixi.js';
const mesh = new Mesh(geometry, shader);
Mesh:
Одна геометрия может быть использована несколькими мешами, если требуется повторное использование данных.
Каждый атрибут увеличивает объём данных. Передача только необходимых параметров снижает нагрузку.
Повторное использование вершин сокращает память и ускоряет рендеринг.
Чередование атрибутов в одном буфере снижает переключения состояния WebGL.
Buffer.update()Можно использовать:
Float32ArrayUint16ArrayUint32ArrayInt8ArrayТип должен соответствовать параметру type.
PixiJS поддерживает инстансинг через дополнительные атрибуты с
делителем (instance-атрибуты). Это позволяет:
Geometry хранит:
attributes — словарь атрибутовindexBufferПри первом использовании данные отправляются в GPU. При обновлении версии увеличиваются, и PixiJS повторно загружает изменённые буферы.
Минимальный пример прямоугольника:
const geometry = new Geometry()
.addAttribute('aPosition', new Float32Array([
-50, -50,
50, -50,
50, 50,
-50, 50,
]), 2)
.addIndex([0, 1, 2, 0, 2, 3]);
Такой объект полностью управляется GPU и может быть использован с любым кастомным шейдером.
Geometry — ключевой инструмент для работы с
низкоуровневой графикой в PixiJS. Он предоставляет прямой контроль над
структурой вершинных данных, позволяет оптимизировать производительность
и создавать сложные визуальные эффекты, недоступные при использовании
высокоуровневых абстракций.