Troika-three-text: производительный текст в 3D

Библиотека Troika-three-text представляет собой высокопроизводительный инструмент для рендеринга текста в 3D-сценах на базе Three.js. Она оптимизирована для быстрого отображения больших объемов текста с минимальной нагрузкой на GPU и CPU. Основная идея заключается в использовании текстурных атласов и геометрии на основе шрифтов с поддержкой многострочности, выравнивания и стилевых атрибутов.

Основной класс библиотеки — Text, который наследуется от THREE.Mesh. Он объединяет в себе геометрию, материал и текстовые данные, что позволяет легко интегрировать текст в стандартные Three.js-сцены.

import { Text } from 'troika-three-text';

const textMesh = new Text({
  text: 'Привет, 3D мир!',
  fontSize: 0.5,
  color: 0xffffff,
  anchorX: 'center',
  anchorY: 'middle'
});

scene.add(textMesh);

Настройка шрифта

Troika-three-text поддерживает загрузку шрифтов в формате .ttf или .otf через URL или Blob. Используется свойство font:

textMesh.font = '/fonts/Roboto-Regular.ttf';

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

textMesh.sync(); // Принудительное обновление геометрии после изменения текста или шрифта

Форматирование и стилизация текста

Troika-three-text предоставляет широкие возможности по стилизации текста:

  • Цвет и прозрачность:
textMesh.color = 0xff0000;
textMesh.opacity = 0.8;
textMesh.transparent = true;
  • Выравнивание:
textMesh.anchorX = 'center'; // left, center, right
textMesh.anchorY = 'middle'; // top, middle, bottom
  • Многострочность и перенос слов:
textMesh.text = "Первая строка\nВторая строка";
textMesh.maxWidth = 2; // Автоматический перенос по ширине
textMesh.overflowWrap = 'break-word';
  • Межстрочный интервал и кернинг:
textMesh.lineHeight = 1.2; // коэффициент высоты строки
textMesh.letterSpacing = 0.05; // расстояние между буквами

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

Troika-three-text оптимизирован для изменения текста на лету. Геометрия пересоздается только при изменении свойств, влияющих на визуализацию:

textMesh.text = "Обновленный текст";
textMesh.color = 0x00ff00;
textMesh.sync();

Важно вызывать sync(), чтобы обновления вступили в силу, особенно при анимации текста.

Оптимизация производительности

  1. Использование атласов: Troika-three-text создаёт атлас шрифта для всех символов текста, что уменьшает количество draw calls. Атлас можно кэшировать для повторного использования.
  2. Ленивая генерация геометрии: Геометрия создается только при необходимости (sync()), а не каждый кадр.
  3. Масштабирование текста через fontSize: Изменение размера текста не требует пересоздания шрифта, так как атлас масштабируется на GPU.
  4. Минимизация обновлений: Избегать постоянного изменения свойств текста без необходимости, чтобы не перегружать GPU.

Применение эффектов и материалов

Troika-three-text поддерживает любые материалы Three.js. Например, можно использовать MeshStandardMaterial для освещённого текста или MeshBasicMaterial для статичного цвета:

textMesh.material = new THREE.MeshStandardMaterial({
  color: 0xffffff,
  metalness: 0.5,
  roughness: 0.5
});

Для создания анимационных эффектов можно изменять параметры color, opacity или применять шейдерные материалы. Troika-three-text корректно работает с instanced rendering и post-processing эффектами.

Интеграция с Three.js сценой

Troika-three-text полностью совместим с камерами, светом и тенями Three.js:

const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(5, 10, 7.5);
scene.add(directionalLight);

textMesh.castShadow = true;
textMesh.receiveShadow = true;

Можно комбинировать несколько текстов в сцене, сохраняя производительность за счет совместного использования атласов и минимизации вызовов sync().

Поддержка Unicode и Emoji

Troika-three-text корректно отображает Unicode-символы и большинство emoji, если выбранный шрифт их поддерживает. Для emoji рекомендуется использовать специализированные шрифты с полной цветовой поддержкой.

textMesh.text = "Привет ?";

Использование с React и React Three Fiber

Troika-three-text можно легко интегрировать в React Three Fiber через компонент <primitive>:

<primitive object={textMesh} />

Таким образом, весь мощный функционал библиотеки становится доступен в декларативном стиле React, что упрощает создание динамических UI и 3D-интерфейсов.

Итоговые возможности

  • Высокопроизводительный текст в 3D.
  • Поддержка многострочности, кернинга, межстрочного интервала.
  • Динамическое обновление текста без потери производительности.
  • Совместимость с Three.js материалами и эффектами.
  • Поддержка Unicode и emoji.
  • Простая интеграция с React Three Fiber.

Troika-three-text сочетает гибкость, производительность и простоту, делая текстовые объекты полноценным инструментом для сложных 3D-сцен.