Any3DAny3D
·Any3D Team

Почему 3D-модели такие тяжёлые?

3d-compressiongltfwebglperformance

Ваша модель незаметно становится тяжелее

Вы экспортировали GLB-файл — 10 МБ, всё вроде бы нормально. Открываете на телефоне: белый экран, заикания или даже краш.

На компьютере всё работает, а на телефоне взрывается. Это не ваша ошибка в коде. В этом заключается непростое свойство 3D-моделей: на диске и в VRAM они имеют совершенно разный размер.

JPG-изображение может весить всего 200 КБ на диске. Но GPU не понимает JPG; он понимает только сырые пиксели. Поэтому перед загрузкой в VRAM изображение полностью распаковывается. Текстура 2048x2048 занимает около 22 МБ VRAM после распаковки. Если использовать 6 текстур (альбедо, нормали, шероховатость, металличность, AO, эмиссия), одна модель занимает 132 МБ.

На телефоне может быть всего 2-4 ГБ VRAM, и текстуры одной модели занимают 3-6% от этого. А теперь представьте 10 моделей в сцене.

Разбираем: куда уходят байты

Типичная GLB-модель состоит из трёх основных частей: данные вершин, текстуры и метаданные с анимациями.

Возьмём реальную PBR-модель:

КомпонентЧто этоТипичная доляПримечания
Текстурыальбедо, нормали, шероховатость, металличность, AO и т.д.70-85%Почти всегда основная часть
Данные вершинкоординаты, нормали, UV, тангенты, цвет10-20%Зависит от сложности модели
Данные анимациискелеты, скинг, ключевые кадры0-15%Только при наличии анимации
Прочееопределения материалов, структура сцены, камеры< 2%Пренебрежимо мало

Текстуры занимают около 80%. Часто кажется, что нужно оптимизировать вершины, но на самом деле основное пространство съедают текстуры.

"Маленький на диске" не означает "маленький в VRAM"

Это, пожалуй, самый важный момент в понимании производительности 3D.

PNG и JPG разработаны для сетевой передачи — компактные на диске, быстрые для скачивания. Но GPU не может использовать их напрямую; их необходимо полностью распаковать в сырые пиксели. Формула:

VRAM = ширина * высота * 4 байта (RGBA) * 1.333 (с мипмапами)

Текстура 4096x4096 RGBA:

МетрикаЗначение
Размер PNG файла~8 МБ
Размер JPG файла~1.5 МБ
Использование VRAM (с мипмапами)~87 МБ

JPG весом 1.5 МБ превращается в 87 МБ VRAM.

Что такое мипмапы? GPU генерирует серию постепенно уменьшающихся версий текстуры — от оригинального размера до 1x1 пикселя, каждый уровень вдвое меньше предыдущего. Это ускоряет и делает более чёткой отрисовку удалённых объектов, но требует примерно на 33% больше VRAM. Почти все 3D-приложения используют мипмапы, поэтому этот overhead является стандартом.

Таким образом, PNG и JPG — это как вакуумные пакеты для хранения: спрессованы для перевозки, но на месте нужно полностью развернуть. Скачивание ускорилось, но экономия VRAM: ноль.

Что происходит при нехватке VRAM

Вы не увидите аккуратного диалога «недостаточно памяти». Реальность хуже:

  • Мобильные устройства: белый экран или ОС убивает вкладку целиком
  • VR-шлемы: пропуск кадров. В VR пропущенный кадр — это не «немного подлагивает», а вызывает тошноту
  • Десктоп: мерцание текстур, деградация, замедление рендеринга

На Reddit один разработчик создал WebXR-галерею и запихнул 60 стереоизображений на Quest. Сначала работало, но потом стало нестабильным и вылетело. Он потратил дни на отладку кода, прежде чем понял, что вообще не думал о VRAM — просто продолжал пихать JPG в GPU.

Два направления сжатия

Сжатие 3D-моделей делится на два направления:

Сжатие вершин — более компактное хранение геометрических данных (координаты вершин, нормали, UV). Например, замена 32-битных float на 16-битные целые (это называется квантизация). Типичные решения: Draco, MeshOpt, KHR_mesh_quantization.

Сжатие текстур — сохранение текстур в сжатом виде даже внутри VRAM. GPU распаковывает отдельные пиксели «на лету» при выборке, практически без потери производительности. Типичное решение: KTX2 + Basis Universal.

Сжатие вершинСжатие текстур
Что уменьшаетГеометрические данныеТекстуры
Типичный эффектНа 50-90% меньшеНа 50-70% меньше на диске, на 75% меньше VRAM
Потеря качества?Да, потеря точностиДа, потеря качества
Лучше всего подходитВершинно-ёмкие моделиПрактически любая PBR-модель
ПодробнееЧасть 2Части 3 и 4

Распространённое заблуждение: сжать вершины Draco и на этом остановиться. Но текстуры — это 80% размера модели. Уменьшите вершины вдвое, а общее уменьшение может составить всего 10%. Нужно работать в обоих направлениях.

Нет универсального метода

Это основной тезис всей серии:

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

СценарийОсновное ограничениеПриоритет
Десктопная веб-визуализацияСкорость загрузкиРазмер файла
Мобильный браузерVRAMСжатие текстур
VR-шлемVRAM + частота кадровСжатие текстур + упрощение вершин
WeChat Mini ProgramРазмер пакета + совместимостьЛёгкие варианты (MeshOpt)
Крупные сценыVRAM + draw callsПолное сжатие + LOD

Каждая следующая статья не просто скажет «используйте X и всё». Она объяснит: где X блестит, когда он даёт обратный эффект, и когда стоит обратиться к Y.

Что дальше

Эта статья закрепила проблему. Следующая будет практической — знакомство с тремя инструментами сжатия вершин: квантизация, MeshOpt и Draco.

Поддержите нас