В современных веб-приложениях, работающих с 3D-графикой, особенно критично контролировать использование ресурсов GPU. В библиотеке Three.js объекты, такие как геометрия, текстуры и материалы, после удаления из сцены не освобождают автоматически видеопамять. Для предотвращения утечек памяти используется метод dispose.
Каждая геометрия в Three.js (THREE.BufferGeometry)
содержит буферы, хранящие данные вершин, нормалей, UV-координат и
индексов. При удалении объекта из сцены эти буферы остаются в памяти
GPU.
Пример освобождения геометрии:
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshStandardMaterial({ color: 0xff0000 });
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
// Удаление
scene.remove(mesh);
geometry.dispose(); // Освобождает буферы на GPU
Важно: вызывать dispose нужно
после удаления объекта из сцены и если геометрия больше
не используется нигде в коде.
Материалы (THREE.Material) управляют шейдерами и
текстурами. Помимо освобождения шейдеров, материалы могут содержать
ссылки на текстуры.
Пример:
material.dispose();
Если материал использует текстуры, их необходимо освободить отдельно,
так как dispose материала не освобождает связанные текстуры
автоматически.
Текстуры (THREE.Texture) могут занимать значительное
количество видеопамяти, особенно при использовании карт высокого
разрешения. Для их освобождения используется метод
dispose:
texture.dispose();
При работе с несколькими объектами, использующими одну и ту же текстуру, важно убедиться, что текстура больше нигде не используется. В противном случае её преждевременное удаление приведёт к отсутствию изображения на других объектах.
Рендер-таргеты (THREE.WebGLRenderTarget) и буферы
(THREE.DataTexture, THREE.DepthTexture) также
занимают память GPU. Их очистка критична при динамическом создании
текстур или использовании эффектов постобработки:
renderTarget.dispose();
dataTexture.dispose();
Для сложных сцен удобно создавать функцию, которая рекурсивно освобождает все ресурсы объекта и его потомков:
function disposeObject(obj) {
if (obj.geometry) obj.geometry.dispose();
if (obj.material) {
if (Array.isArray(obj.material)) {
obj.material.forEach(mat => mat.dispose());
} else {
obj.material.dispose();
}
}
if (obj.texture) obj.texture.dispose();
obj.children.forEach(child => disposeObject(child));
}
Использование такой функции гарантирует, что удаляемый объект не оставит «мусор» в GPU.
Three.js не предоставляет встроенного сборщика мусора для GPU. Для мониторинга состояния памяти можно использовать инструменты браузера:
Регулярное вызовы dispose после удаления объектов
помогают избежать утечек и падения производительности при длительной
работе приложения.
Эффективное использование dispose позволяет значительно
снизить нагрузку на GPU, предотвращает утечки памяти и обеспечивает
стабильную работу приложений Three.js при динамическом создании и
удалении объектов.