Оптимизация производительности 3D | Расскажите о сжатии файлов glTF

внешний интерфейс three.js
Оптимизация производительности 3D | Расскажите о сжатии файлов glTF

введение

В последнее время для взаимодействия на уровне T мне нужно использовать 3D-модели. Я считаю, что у всех, как и у меня, в начале пути возникнут следующие вопросы:

  • 1. Как выбрать формат экспорта 3D модели
  • 2. Как оптимизировать файл модели
  • 3. Как насчет совместимости в проектах с высокой посещаемостью

Давайте проведем подробное исследование, исследование и осадки в этой статье.


1. Что такое файл glTF

glTFполное имяGraphics Language Transmission Format, является стандартным форматом файлов для 3D-сцен и моделей.

Трехмерные объекты, которые появляются в сцене, определяются с помощью мешей, соединенных с узлами. Материалы определяют внешний вид объекта. Анимации описывают, как 3D-объект трансформируется с течением времени, а скины определяют, как деформируется геометрия объекта в зависимости от позы скелета. Камеры описывают конфигурацию представления средства визуализации.

Кроме того, он включает ссылку с двоичными данными и файлами изображений, как показано ниже.


Это видно из экспорта файла Blender:

Файлы glTF имеют два расширения: .gltf (JSON/ASCII) или .glb (двоичный). Файлы .gltf могут быть автономными и могут также ссылаться на внешние двоичные ресурсы и ресурсы текстур, в то время как файлы .glb полностью автономны (но использование внешних инструментов может сохранять их буферы/текстуры как встроенные или отдельные файлы, которые будут обсуждаться позже). ).

2.1 Причины появления файлов .glb

glTF предоставляет два варианта доставки, которые также можно использовать вместе:

  • glTF JSON указывает на внешние двоичные данные (геометрию, ключевые кадры, скины) и изображения.
  • glTF JSON встраивает двоичные данные в кодировке base64 и встраивает изображения с помощью URI данных.

Для этих ресурсов glTF требуется отдельный запрос или дополнительное пространство из-за кодировки base64. Кодирование Base64 требует дополнительной обработки для декодирования и увеличивает размер файла (примерно на 33% больше ресурсов кодирования). В то время как gzip уменьшает увеличение размера файла, распаковка и декодирование по-прежнему значительно увеличивают время загрузки.

Для решения этой проблемы был введен формат контейнера Binary glTF. В двоичном glTF активы glTF (JSON, .bin и изображения) могут храниться в двоичных BLOB-объектах, которые.glb-файл.

2.2 Сравнение файлов

2.2.1 Тот же файл glTF, формат .glb меньше, чем .gltf

  • Автономный:

  • Ссылки на внешние бинарные и текстурные ресурсы:

2.2.2 Предварительный просмотр файла .gltf:

  • Автономный:

  • Автономный:

  • Ссылка внешних двоичных и текстурных ресурсов:

Это видно из рисунка, когда несамостоятельный тип запроса glTF файл, файл изображения вместе с запросом.


Три, файл glTF разделен

Как упоминалось выше, файлы glTF можно разделить на файлы .gltf/.glb + двоичные файлы + изображения текстур, после чего мы можемРазделить его и отдельно сжать изображение текстуры, чтобы оптимизировать производительность.

можно использоватьgltf pipeLine, который имеет следующие функции:

  • Взаимопреобразование между glTF и glb
  • Сохраняйте буферы/текстуры как встроенные или отдельные файлы
  • Преобразование моделей glTF 1.0 в glTF 2.0 (используяKHR_techniques_webglа такжеKHR_blend)
  • Сжатие сетки с Драко

Здесь мы собираемся использовать функцию «Сохранить буфер/текстуру как встроенный или отдельный файл».

Давайте посмотрим на разделение файла

Напомним, что файл .glb представляет собой способ введения внешних отдельных файлов текстур и двоичных файлов.

Поэтому, пока эти файлы разделены,на тот же путьи импортируйте его, как и раньше.

  • Метод сжатия
gltf-pipeline -i male.glb -o male-processed.glb -s

import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'

const loader = new GLTFLoader()
loader.load(MODEL_FILE_PATH, (gltf) => {
 // ....
})
  • Сравнение производительности


Как описано выше, файлы glTF включают файлы .gltf/.glb, файлы .bin и ресурсы текстур. Основные плагины, относящиеся к glTF2.0, следующие:

Итак, давайте возьмем некоторые из них и проанализируем их.


4.1 Сжатие сетки

4.1.1 KHR_draco_mesh_compression

наиболееобщийМетод сжатия сетки, который использует алгоритм Draco с открытым исходным кодом для сжатия и распаковки трехмерных сеток и облаков точек и может изменять порядок и количество вершин в сетке. Сжатие делает файл намного меньше, но требуется на клиентском устройстве.дополнительное время декодирования.

  • Метод сжатия

можно использоватьgltf-pipelineинструмент оптимизации файлов gltf для сжатия

gltf-pipeline -i male.glb -o male-processed.glb -d
  • Как использовать (в Three.js)
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'

const loader = new GLTFLoader()

// 创建解码器实例
const dracoLoader = new DRACOLoader()
// 设置解压库文件路径
dracoLoader.setDecoderPath(DECODER_PATH)
// 加载解码器实例
loader.setDRACOLoader(dracoLoader)

loader.load(MODEL_FILE_PATH, (gltf) => {
 // ....
})
  • Анализ производительности и сравнение

Этот исходный размер файла glb составляет 3,2 МБ, после того, как draco сжал 1,8 МБ, об исходном файле56%.

Как видно из приведенного выше кода, создание экземпляра декодера требует внедрения дополнительных библиотек для декодирования,setDecoderPathФайл wasm автоматически запрашивается для расшифровки. И эти два файла wasm также увеличивают время запроса и количество запросов, поэтому, добавив эти два файла, реальная степень сжатия составляет около62.5%.

Таким образом, если проекту необходимо загрузить несколько файлов glTF, вы можете создать экземпляр DRACOLoader и использовать его повторно. Но если проекту нужно только загрузить файл glTF, стоит подумать, является ли «рентабельным» использование алгоритма draco.

Используйте демо, чтобы сравнить производительность:

可见 draco 算法首次加载和解密时间,要大于原文件。 пока вдействительныйProject, разрыв более очевиден, иПериодическая блокировка дешифрования, вам необходимо повторно войти на страницу, чтобы восстановить функциональность.

Как показано на рисунке, он есть в iPhone 12 и Xiaomi Mix2:

В общем, если вы хотите применить алгоритм сжатия draco к крупномасштабному проекту, вам необходимо провести следующие сравнения в сочетании с реальным проектом:

  • (1) Запрос двух файлов + расшифровка занимает много времени, по сравнению с размером самого сжатого файла glb, сравнение реальной производительности;
  • (2) Будет ли какая-либо потеря качества изображения, которую дизайнер не может принять.

4.1.2 KHR_mesh_quantization

Атрибуты вершин обычно используютсяFLOATВведите хранилище, преобразуйте исходное необработанное значение с плавающей запятой в 16-битное или 8-битное хранилище, чтобы соответствовать унифицированной трехмерной или двумерной сетке, что мы называем векторизацией квантования, этот плагин в основном предназначен для его векторизации.

Например, для статических готовых к PBR сеток обычно требуется каждая вершина.POSITION(12 байт),TEXCOORD(8 байт),NORMAL(12 байт) иTANGENT(16 байтов) всего 48 байтов. С этим расширением вы можете использоватьSHORTданные о месте хранения и координатах текстуры (8 и 4 байта соответственно) иBYTEСохраняет данные нормали и касательной (по 4 байта каждый), всего 20 байтов на вершину.

  • Метод сжатия

можно использоватьgltfpackинструмент для сжатия

gltfpack -i male.glb -o male-processed.glb
  • Как использовать (в Three.js)

Хорошо использовать его в обычном режиме, и он ничем не отличается от несжатого.

import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'

const loader = new GLTFLoader()
loader.load(MODEL_FILE_PATH, (gltf) => {
 // ....
})
  • Сравнение производительности

Исходный файл 3,2 МБ, сжатый 1,9 МБ, 59,3% исходного файла, скорость загрузки, чем исходная модель, также намного быстрее. В реальном проекте нет потери качества и проблемы долгой загрузки.

4.1.3 EXT_meshopt_compression

В дополнение к оптимизации соотношения сжатия, сжатый формат имеет два свойства - очень быстрое декодирование (с использованием Webassembly SIMD, декодеру проходит при ~ 1 Гбит / с на современном настольном аппаратном обеспечении), а также общеобразовательные сжатия. То есть вместо того чтобы уменьшить размер кодирования максимально возможным, постройте битовый поток таким образом, чтобы общий компрессор мог сжать его дальше.

  • Метод сжатия

можно использоватьgltfpackинструмент для сжатия

gltfpack -i male.glb -o male-processed.glb -cc
  • Как использовать (в Three.js)
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { MeshoptDecoder } from 'three/examples/jsm/libs/meshopt_decoder.module.js'

const loader = new GLTFLoader()
loader.setMeshoptDecoder(MeshoptDecoder)
loader.load(MODEL_FILE_PATH, (gltf) => {
 // ....
})
  • Анализ производительности и сравнение

Исходный файл имеет размер 3,2 МБ, а сжатый файл — 1,1 МБ, то есть исходный файл.65.6%, первое время загрузки намного быстрее, чем у исходной модели. Поместите его в реальный проект, нет проблем с потерей качества изображения и долгой загрузкой.

5. Результаты сравнения нескольких моделей оборудования и оптимизация

Чтобы избежать вышеупомянутого сжатия «драко», которое повреждает модель, я нашел несколько телефонов iPhone и Android, чтобы провести тест производительности и совместимости, давайте посмотрим на результаты. PS: Сеть компании имеет разную скорость сети в разные периоды времени (например, утром и днем), что может иметь небольшое влияние на цифры, но не влияет на горизонтальное сравнение оптимизации файлов.

iPhone 12 (iOS 14.4, для личного использования)

Huawei Mate 40 pro (HarmonyOS, для личного пользования)

Xiaomi Mix2 (Android 8.0, тестовая машина)

iPhone 6sp (iOS 13.7, персональный компьютер)

5.1 Резюме

Видно, что для небольшого количества предприятий, которым необходимо использовать модели и нужно загрузить только одну модель, используйтеKHR_mesh_quantizationилиEXT_meshopt_compressionСжатие сетки, затем используйтеgltf-pipelineРазличение модулей и сжатие текстурных изображений — лучшее решение для оптимизации, найденное до сих пор.


6. Другие

На самом деле, все еще существует множество плагинов, оптимизированных для производительности, которые в настоящее время отлаживаются и исследуются и будут продолжать обновляться при последующих итерациях или новых разработках:

Сетка оптимизирована:

Есть также некоторые текстуры-оптимизированные плагины:

7. Ссылки

  1. The Basic Structure of glTF

  2. GLB File Format Specification

  3. Extensions for glTF 2.0

  4. KHR_draco_mesh_compression

  5. DRACOLoader — документы three.js

  6. CesiumGS/gltf-pipeline: Content pipeline tools for optimizing glTF assets.

  7. KHR_mesh_quantization

  8. 📦 gltfpack | оптимизатор сетки

  9. GLTFLoader

  10. EXT_meshopt_compression

  11. [Оценка сжатия сетки] MeshQuan, MeshOpt, Драко