CanvasTexture: текстура из элемента canvas

CanvasTexture — это класс библиотеки Three.js, позволяющий использовать HTML-элемент <canvas> в качестве источника текстуры для 3D-объектов. Такой подход открывает возможность динамического создания и обновления текстур в реальном времени без необходимости загружать изображения с сервера.


Создание CanvasTexture

Для начала необходимо иметь элемент <canvas> в документе или создавать его программно:

const canvas = document.createElement('canvas');
canvas.width = 512;
canvas.height = 512;

const context = canvas.getContext('2d');
context.fillStyle = 'blue';
context.fillRect(0, 0, canvas.width, canvas.height);
context.fillStyle = 'white';
context.font = '48px Arial';
context.fillText('Three.js', 50, 100);

Создание текстуры на основе этого элемента выполняется через конструктор CanvasTexture:

const texture = new THREE.CanvasTexture(canvas);

Теперь texture можно применять к материалам:

const material = new THREE.MeshBasicMaterial({ map: texture });
const geometry = new THREE.BoxGeometry(2, 2, 2);
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);

Важные параметры CanvasTexture

CanvasTexture наследует свойства от Texture, поэтому поддерживает все стандартные настройки текстуры:

  • wrapS и wrapT — режимы оборачивания по горизонтали и вертикали (THREE.RepeatWrapping, THREE.ClampToEdgeWrapping, THREE.MirroredRepeatWrapping).
  • minFilter и magFilter — фильтры масштабирования (THREE.LinearFilter, THREE.NearestFilter).
  • format — формат пикселей, обычно THREE.RGBAFormat.
  • anisotropy — уровень анизотропной фильтрации.

Пример использования фильтров и оборачивания:

texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set(2, 2);
texture.minFilter = THREE.LinearFilter;
texture.magFilter = THREE.LinearFilter;

Обновление текстуры в реальном времени

Одно из главных преимуществ CanvasTexture — возможность динамически обновлять изображение:

function animate() {
    requestAnimationFrame(animate);

    // обновление canvas
    context.clearRect(0, 0, canvas.width, canvas.height);
    context.fillStyle = 'black';
    context.fillRect(0, 0, canvas.width, canvas.height);
    context.fillStyle = 'red';
    context.font = '48px Arial';
    const time = new Date().toLocaleTimeString();
    context.fillText(time, 50, 100);

    // уведомление текстуры о необходимости обновления
    texture.needsUpdate = true;

    renderer.render(scene, camera);
}
animate();

Ключевой момент: после изменения содержимого <canvas> необходимо установить texture.needsUpdate = true, чтобы Three.js заново загрузил данные текстуры на видеокарту. Без этого изменения новые рисунки на канвасе не будут видны на 3D-объекте.


Применение CanvasTexture

  1. Динамические текстуры: часы, счетчики, геймерские HUD, статистика на объектах сцены.
  2. Генеративная графика: паттерны, шумы, procedural textures, создаваемые на лету с помощью canvas API.
  3. Анимации на поверхности объектов: перемещающиеся узоры, интерактивные эффекты, реагирующие на пользовательский ввод.

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

  • Размер канваса влияет на производительность и потребление памяти. Обычно стоит использовать степени двойки (256×256, 512×512, 1024×1024) для оптимальной работы с текстурами на GPU.
  • Частое обновление больших канвасов может снижать FPS, поэтому для динамических элементов рекомендуется минимизировать область перерисовки (clearRect) и обновлять только изменяющиеся фрагменты.
  • Для повторяющихся узоров можно использовать малый канвас с паттерном и применять его через context.createPattern вместо полного перерисовывания большого полотна.

Поддержка прозрачности и альфа-канала

CanvasTexture поддерживает альфа-канал. Для прозрачных областей достаточно использовать context.clearRect или задавать прозрачный fillStyle:

context.clearRect(0, 0, canvas.width, canvas.height);
context.fillStyle = 'rgba(255, 0, 0, 0.5)';
context.fillRect(50, 50, 200, 200);

Текстура с прозрачностью корректно взаимодействует с материалами MeshBasicMaterial, MeshStandardMaterial и другими при установке свойства transparent = true:

const material = new THREE.MeshBasicMaterial({
    map: texture,
    transparent: true
});

Использование нескольких CanvasTexture

В сложных сценах можно создавать несколько CanvasTexture, каждая со своей уникальной визуализацией. Это удобно для:

  • Отображения разных информационных панелей на отдельных объектах.
  • Создания эффектов многослойных текстур с наложением разных канвасов через THREE.MeshStandardMaterial с несколькими картами (map, alphaMap, aoMap).

CanvasTexture является мощным инструментом для интеграции динамической 2D-графики в 3D-сцену, позволяя гибко управлять визуализацией объектов без необходимости генерации отдельных изображений на сервере. Его использование открывает путь к интерактивным и адаптивным текстурам, которые можно обновлять в реальном времени, создавая богатую и динамичную графику.