HWW Portfolio

Software and Hardware Developer

Sweet Spot для GPU: правила оптимизации графики под мобильные платформы

Большинство 3D-художников уверены: оптимизация модели — это исключительно борьба за низкий полигонаж. Это опасное заблуждение. Современные мобильные чипы легко переваривают миллионы треугольников, но моментально «вешают» игру из-за невидимых для глаза ловушек в структуре мешей и материалов.

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


Оглавление

  1. Ловушка полигонажа: скрытая стоимость материалов
  2. Закон Атласа: логика общих материалов против текстур
  3. Анатомия мобильного рендера: почему большие объекты — это зло
  4. Размер текстур
  5. Культура прозрачности и батчинга
  6. Культура производства: нормали, UV и именование

1. Ловушка полигонажа: скрытая стоимость материалов

Художник может потратить два дня, ужимая сетку модели с 5000 до 3000 полигонов, думая, что спасает проект. Но если при этом на объекте висит три материала вместо одного, производительность игры станет хуже.

Упрощенная формула стоимости рендеринга кадра:

\[Resources = RP + (SM + SMesh + SMesh + Pix) + Shad + RCnt\]

Для 3D-моделлера критически важна группа в скобках: (SM + SMesh + SMesh).

В чем физика процесса:
Самый дорогой ресурс на мобильных платформах — это количество Draw Calls (команд отрисовки). Каждый новый материал → новый Draw Call. CPU отправляет эти команды, и именно он становится узким горлышком. Видеокарта же (GPU) считает треугольники с огромной скоростью.

Правило:
Если объект содержит менее 500 треугольников, его оптимизация по сетке не дает прироста FPS. Единственное, что реально влияет — минимизация количества уникальных материалов.

Draw Calls Cost
Figure 1 - Влияние вызовов отрисовки (draw calls) на стоимость рендеринга. Элементы (SM + SMesh + SMesh) — главный приоритет для 3D-моделлера.

2. Закон Атласа: логика общих материалов против текстур

Чтобы сократить количество Draw Call’ов, есть три основных подхода:

А) Shared Materials (общие материалы без текстур)

Использование нескольких чистых цветов-материалов на всю сцену.
Пример: шахматы — 32 фигуры и доска рендерятся всего через два материала (черный и белый).
✅ Видеокарте не нужно загружать текстуры — это самый дешевый рендеринг.
⚠️ Работает только при малом количестве цветов (до 10–20).

Chess Board
Figure 2 - Шахматные фигуры требуют всего двух материалов — черного и белого.

Б) Texture Atlas (текстурный атлас)

Объединение сотен мелких текстур в одно большое полотно.
Пример: целый город или лес упаковываются в 2 текстуры (одна для непрозрачных объектов, вторая — для полупрозрачных).
✅ Позволяет использовать один материал для тысяч разных объектов → один Draw Call.
⚠️ Требует аккуратной UV-развертки, чтобы избежать кровотечения пикселей (mipmap bleeding). Загрузка текселей из атласа стоит GPU-ресурсов.

Вывод:
Если нужно 10–20 цветов — выбирайте Shared Materials.
Если нужно визуальное разнообразие и сотни объектов — используйте атлас, но с осторожностью.

Texture Atlas with Colors Texture Atlas with subtextures
Figure 3 - Текстурный атлас с чистыми цветами. Figure 4 - Текстурный атлас с субтекстурами (изображениями).

В) Весь мир состоит из одного или двух материалов

Если невозможно использовать подходы 1 и 2, то в большинстве случаев действует правило:

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

Хороший пример разделения по слоям описан в статье Texturing Game Characters in Substance Painter.

1-2 Materials World
Figure 5 - Такая сцена может быть отрисована небольшим количеством текстур и материалов.

Главный закон оптимизации материалов В любом из этих трёх случаев количество материалов должно быть равно количеству сабмешей.


3. Анатомия мобильного рендера: почему большие объекты — это зло

Моделлеры любят собирать крупные объекты (длинные заборы, ангары, монолитные участки земли) единым мешем. Для мобильных платформ и VR-шлемов (Oculus Quest, Pico) это технический приговор.

В чем физика процесса:
Мобильные GPU используют Tile-Based Rendering — разбивают экран на маленькие квадраты (плитки) и просчитывают их изолированно.
Огромный монолитный объект всегда находится в поле зрения хотя бы частично. Движок не может его отсечь (culling) и вынужден прокручивать геометрию гиганта через кэш памяти для каждой плитки. Результат — перегрев чипа и падение FPS.

Large overlapped objects
Figure 6 - Крупные пересекающиеся объекты не дружественны для рендеринга на TBR-платформах.

Правило:
У мобильных платформ есть жесткая зона максимальной эффективности — Sweet Spot.
Например, для Oculus Quest это 5–7 тысяч треугольников на один батч.
Любой крупный объект обязан собираться из небольших модулей, размер которых укладывается в ограничения платформы.

Sweet Spot
Figure 7 - У каждой платформы есть своя оптимальная зона производительности (sweet spot) для отрисовки множества объектов с различным размером мешей. Например, для Oculus Quest наилучшая производительность достигается при использовании объектов в диапазоне 5–7 тысяч треугольников на один батч.

4. Размер текстуры: Ловушка пропускной способности

Большинство 3D-художников уверены: если текстура высокого разрешения физически «влезает» в объем видеопамяти шлема или смартфона, то её можно использовать. Это опасное архитектурное заблуждение. Сама по себе память может быть полупустой, но игра начнет нещадно тормозить.

Texture size threshold
Figure 8 - У платформы возникают проблемы, когда размер текстуры превышает определённый порог.

В чем физика процесса: На мобильных платформах и автономных VR-шлемах (Oculus Quest) оперативная (RAM) и видеопамять (VRAM) — это один физический чип. Они делят между собой общую шину данных, которая имеет очень узкое «горлышко» — пропускную способность (Memory Bandwidth). Когда GPU пытается одновременно отрисовать на экране десятки объектов с текстурами 4K, происходит следующее:

Правило: Размер текстуры должен определяться не «красотой вблизи», а её физическим разрешением на экране игрока. Если объект занимает на экране область 200x200 пикселей, натягивать на него текстуру 2048x2048 — это техническое преступление, которое сожрет драгоценный Bandwidth всей системы.

Всегда используйте Mipmap-уровни (LOD-текстуры), чтобы движок автоматически подменял разрешение текстуры на меньшее по мере удаления объекта от камеры.


5. Культура прозрачности и батчинга

Рендеринг полупрозрачных материалов — одна из самых тяжелых операций для графического чипа. В отличие от непрозрачной геометрии, которую видеокарта рисует «в лоб», прозрачность заставляет железо работать в режиме постоянного стресса. В чем физика процесса: Когда объект имеет полупрозрачные области (Alpha Blending), GPU не может просто записать цвет пикселя в буфер экрана. Он вынужден выполнять тяжелую операцию Read-Modify-Write: считать цвет того, что уже нарисовано сзади, смешать его с цветом прозрачного объекта и записать результат обратно. Если на экране друг на друга накладываются несколько слоев прозрачности (например, пышная крона дерева из прозрачных плашек или эффекты дыма), возникает катастрофический эффект Overdraw (Перерисовка). Один и тот же пиксель экрана пересчитывается по 5–10 за кадр. Мобильная видеокарта моментально захлебывается, шина памяти перегружается, а FPS падает в разы. Чтобы удержать симуляцию в рабочих рамках, трехмерщик обязан соблюдать три жестких правила:

1. Alpha Test против Alpha Blend: Анатомия компромисса

2. Иллюзия LOD (Level of Detail)

Системы автоматического переключения уровней детализации (LOD) — прекрасный инструмент, но художники часто пихают его повсюду.

3. Скрытая цена батчинга (Batching)

Когда программисты говорят: «Не переживай за Draw Call’ы, мы включим батчинг и движок сам все склеит», они умалчивают о побочных эффектах.


6. Культура производства: Скрытая математика геометрии

Большинство художников оценивают тяжесть модели по счетчику полигонов в Blender, Maya или 3ds Max. Однако игровой движок видит геометрию иначе. Из-за скрытых ловушек на этапе создания UV и нормалей модель из 1000 полигонов при импорте в движок может внезапно превратиться в 2000 или 3000 вершин, перегружая шейдерные процессоры.

Нормали и жесткие ребра (Hard Edges)

Некорректные нормали не просто создают некрасивые заломы и артефакты на свету, вынуждая программистов тратить время на исправление чужих ошибок. Они напрямую влияют на производительность.

Normal defects
Figure 9 - Дефекты, вызванные некорректными нормалями.

В чем физика процесса: Игровой движок считает нагрузку не по треугольникам, а по количеству вершин (Vertex Count). Когда вы назначаете ребру статус Hard Edge (острое ребро / разделение групп сглаживания), движок физически не может сгладить нормаль в этой точке. Ему приходится разрывать и дублировать вершины вдоль всего этого ребра. Каждая грань получает свою копию вершины со своим направлением нормали.

Правило: Чем больше на модели неоправданных Hard Edge’ей, тем выше её реальный вес в движке. Стремитесь переносить жесткие ребра на текстуру (через карту нормалей), оставляя саму сетку максимально сглаженной (Smooth Edges).

UV-развертка и ловушка швов (UV Seams)

Проверка развертки шахматной текстурой (checkerboard) — это не просто эстетическое требование для борьбы с растяжениями пикселей. Это техническая необходимость.

Normal defects
Figure 10 - Слева — хорошая развертка, справа — плохая (растянутые UV).

В чем физика процесса: Точно так же, как и в случае с Hard Edges, игровой движок дублирует вершины на каждом текстурном шве (UV Seam). Вершина геометрии может быть одна, но если она принадлежит двум разным островкам развертки, она имеет разные UV-координаты. Движок вынужден скопировать её в памяти. Если моделлер бездумно порезал меш на сотни мелких UV-островков, реальный Vertex Count модели на мобильном GPU вырастет в 2–3 раза. Видеокарта будет тратить лишние такты на обработку одних и тех же точек.

Именование как элемент архитектуры

Требование давать объектам понятные имена вместо стандартных Mesh_01, Box_offset_2 или Material_red — это не прихоть лид-артиста, а защита от человеческого фактора. Когда проект собирается под мобильные платформы, программисты настраивают автоматические скрипты оптимизации пайплайна (Asset Postprocessors). Например, скрипт может автоматически объединять в батчи все объекты, содержащие в имени Static_Prop_, или применять особые сжатые текстурные форматы к объектам с тегом UI. Если меши названы хаотично, автоматизация ломается, и команде приходится вручную перебирать тысячи ассетов в поисках причин падения производительности.

Правило: Имя ассета должно быть строго структурированным и самодокументируемым (например, Character_Body_01). Это единственный способ держать проект под контролем, когда количество объектов на сцене переваливает за тысячи.

Дополнительные рекомендации для production-культуры

Дополнительные рекомендации (для production-культуры)


Итоговый чек-лист оптимизации (Шкала критичности от 1 до 10)

Чем выше балл, тем сильнее эта ошибка бьет по производительности мобильной платформы. Проверяйте модель строго сверху вниз.

Действие при проверке ассета Влияние на FPS (0–10) Физический смысл / Почему это критично
1. Сократить количество материалов до минимума 10 / 10 Каждый материал генерирует новый Draw Call, перегружая процессор (CPU).
2. Использовать атлас или общие цвета вместо кучи текстур 10 / 10 Защищает шину памяти (Bandwidth) от забивания тяжелыми текстурными данными.
3. Проверить нормали (артефакты) и UV (шахматкой) 9 / 10 Хаотичные швы развертки и Hard Edge’и физически удваиваютVertex Count модели в движке.
4. Избегать Alpha Blend (строгое табу), использовать Alpha Test 8 / 10 Спасает мобильный чип от эффекта Overdraw (многократной перерисовки пикселей).
5. Разбивать крупные объекты на модули по 5–7k треугольников 7 / 10 Позволяет плиточному рендеру (TBR) эффективно отсекать невидимую геометрию.
6. Избегать двусторонней геометрии (Double-sided) 6 / 10 Сохраняет аппаратную оптимизацию Backface Culling (отсечение задних граней).
7. Применять статический батчинг только после профилирования 4 / 10 Защищает оперативную память от раздувания монолитными невидимыми мешами.
8. Включать LOD только для движущихся объектов/камеры 3 / 10 Избавляет CPU от холостых расчетов расстояний при статичном кадре.
9. Оптимизировать полигонаж, только если в сетке > 500 трисов 2 / 10 Экономит время художника. Мелкую сетку оптимизировать по полигонам бесполезно.

Автор: Валерия Пудова (hww)
Год: 2022
Контакты: Telegram @valery_h2w