В Dagon 1.0 я очень много времени потратил на поддержку этого монструозного формата моделей, и спустя пять лет работы с ним у меня не осталось ничего, кроме разочарования. Главный вывод: glTF — не для игровых ассетов (т.е. карт и отдельных переиспользуемых моделей). Это формат, предназначенный исключительно для просмотра, причем в основном в браузере, на WebGL, при помощи вьюверов типа Sketchfab. В этом он свою задачу выполняет, хотя и тоже неидеально. Но то, что его все начали использовать как формат обмена данными между программами моделирования и игровыми движками — это фундаментальная ошибка, которую я и сам по наивности допустил. Ниже мой личный список недостатков glTF, актуальных, прежде всего, в контексте игрового рендеринга.

  • Трансформация нод в glTF хранится либо в виде комбинации позиции, поворота и масштаба (TRS), либо в виде матрицы 4×4. Такая вариативность сильно усложняет игровую логику, так как без декомпозиции матрицы обратно в TRS вы не можете ничего анимировать. Декомпозиция — задача нетривиальная, у нее нет стопроцентно надежных решений, и это делает glTF-сцены в общем случае неподходящими для интерактивных приложений. Намного оптимальнее всегда хранить трансформацию в виде TRS и конвертировать в матрицу в движке, что является простейшей задачей.
  • Нефиксированный лейаут вершин — то есть, физическое расположение атрибутов в общем массиве данных может вариьироваться от одного меша к другому, равно как и формат чисел в буферах. Это совместимо с OpenGL/WebGL, но очень плохо для низкоуровневых API, где формат вершин фиксирован на уровне PSO и не может меняться в проходе. Движок вынужден конвертировать буфер в свое внутреннее представление, что убивает саму идею формата — прямую загрузку данных в видеопамять без препроцессинга.
  • Поддержка моделей без некоторых атрибутов — например, без текстурных координат или нормалей. В игровом движке не может быть такого, что нормали отсутствуют, для PBR-пайплайна их все равно нужно предоставить шейдеру. Поэтому отсутствующие атрибуты приходится генерировать — а как это делать, glTF не регламентирует, приходится изобретать свою логику. Это, опять-таки, противоречит идее «эффективного GPU-формата».
  • Кости для скелетной анимации определены как обычные ноды сцены, хотя они логически принадлежат не сцене, а отдельному виду объектов — собственно скелету. Скелет не вставляется в граф сцены, а используется как источник данных для построения pose-матриц для каждой индивидуально анимированной модели в сцене. То есть, с точки зрения архитектуры движка, glTF-подход к скелетке очень далек от эффективного решения несложной в принципе задачи.
  • Поддержка отрицательного масштаба. Для рендеринга это зло, потому что меняет winding и влияет на отбор видимости. Иногда при рендеринге это используется целенаправленно, но в форматах 3D-моделей практически всегда приводит к проблемам совместимости.
  • Использование web-first форматов текстур — PNG и JPEG. В AAA-движках эти форматы практически не используются из-за того, что они требуют декодирования на стороне CPU. Кроме того, для игр с большими мирами жизненно важно блочное сжатие текстур, это индустриальный стандарт. А с glTF получается, что нужен отдельный этап декодирования и сжатия изображений в GPU-френдли форматы. Это может и не быть большой проблемой, если движок поддерживает такой процесс, но все равно возникает много сложностей. Основной вопрос — в какой формат сжимать? Если это base color, то, конечно, достаточно BC1/BC3 (в зависимости от наличия альфа-канала), но для карт нормалей уже желателен BC7, а для черно-белых изображений эффективнее BC4. glTF никак не регламентирует семантику текстур, она определяется на уровне материалов, что в общем случае не позволяет реализовать полностью автоматический алгоритм выбора формата.

В общем, для Dagon 2.0 я обязательно буду пилить собственный формат ассетов, учитывая весь этот опыт. Поддержка glTF сохранится благодаря библиотеке Assimp, но формат больше не будет позиционироваться как основной.

Оставить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *