Мы разрабатываем кастомные шейдеры для мобильных игр с учётом архитектуры мобильных GPU — TBDR (tile-based deferred rendering) у Apple и Arm Mali, отличной от десктопного immediate mode. Если не понимать эту разницу, производительность может упасть в 3-5 раз. Наш опыт показывает, что грамотная оптимизация шейдеров даёт прирост FPS без потери качества. Например, на устройствах с Mali-G78 замена float на half в UV-семплах повысила FPS с 25 до 55. Экономия бюджета на рендеринг составляет 20–40%, а время отклика снижается до 30%. Свяжитесь с нами для предварительной оценки вашего проекта.
Как оптимизация шейдеров влияет на производительность?
Почему half precision быстрее float?
На мобиле разница между float (32 бит), half (16 бит) и fixed (10 бит, устарело) ощутима. Arm Mali и Adreno поддерживают нативную 16-битную арифметику, и на них half работает вдвое быстрее float. Позиции вершин — float, цвета и UV — half. В GLSL ES 3.0 это mediump vs highp.
| Тип | Разрядность | Применение | Скорость (отн.) |
|---|---|---|---|
| float | 32 бита | Позиции вершин, матрицы | 1x |
| half | 16 бит | Цвета, UV-координаты | 2x |
| fixed | 10 бит | Устарел, не рекомендуется | - |
Как уменьшить overdraw на мобильных GPU?
Overdraw — повторная закраска одного пикселя. В TBDR каждый лишний проход увеличивает fillrate. Для уменьшения используйте early-z rejection и прозрачные объекты только при необходимости. В Unity: правильный Sorting Layer и Queue в шейдере (Geometry перед Transparent) позволяют рендеру использовать early-z. Прозрачные объекты убивают early-z — их количество в мобильной игре должно быть минимальным. В типовой сцене выигрыш от сортировки — до 40% времени кадра. Согласно документации Arm Mali, overdraw — основная причина падения производительности.
Шейдеры в Unity: URP vs Built-in
Universal Render Pipeline — стандарт для мобильных Unity-игр. Shader Graph позволяет строить шейдеры визуально, но узкие места всё равно нужно дописывать в HLSL. Кастомный SubGraph в Shader Graph — переиспользуемый блок, который компилируется один раз.
Пример простого шейдера растворения (dissolve) на URP HLSL:
half4 frag(Varyings input) : SV_Target { half4 baseColor = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv); half noiseValue = SAMPLE_TEXTURE2D(_NoiseMap, sampler_NoiseMap, input.uv).r; half edge = smoothstep(_Threshold - _EdgeWidth, _Threshold + _EdgeWidth, noiseValue); clip(noiseValue - _Threshold); half3 edgeColor = lerp(baseColor.rgb, _EdgeColor.rgb, edge); return half4(edgeColor, baseColor.a); } clip() на мобиле работает быстро — TBDR архитектура ещё до растеризации отбрасывает tile, если все пиксели заклипаны.
Как мы оптимизируем шейдеры под конкретные GPU
Наш процесс включает:
- Анализ целевых устройств (Apple GPU, Mali, Adreno) и их возможностей.
- Выбор precision и устранение overdraw путём сортировки очереди рендера.
- Использование Shader Graph с кастомными HLSL-вставками для тонкой настройки.
- Тестирование на реальных устройствах с профилированием в RenderDoc или Xcode GPU Frame Capture.
- Итеративная оптимизация до достижения целевого FPS (обычно 60).
Какие постэффекты допустимы на мобильных устройствах?
Полноэкранные постэффекты (bloom, depth of field, motion blur) — дорого. Стратегия:
| Эффект | Рекомендация | Экономия (vs naive) |
|---|---|---|
| Bloom | Kawase blur вместо Gaussian | до 50% семплов |
| Цветокоррекция | Tonemapping + Color Adjustments | ~0.5 мс |
| DOF | Только для кинематики | 3+ мс на 778G |
| Motion blur | Trail Renderer вместо velocity buffer | ~2 мс на кадр |
В URP Bloom override с отключённым High Quality Filtering — для мобильного пресета.
Particle шейдеры и VFX
VFX Graph в Unity требует Compute Shader — поддерживается на Vulkan (Android 7+) и Metal (iOS 11+). Старый Particle System работает через CPU, что хуже при большом количестве частиц. Для мобильных таргетов: VFX Graph на современных устройствах, CPU particles как fallback для бюджетников.
Шейдер для частиц должен быть максимально простым: Unlit, Additive blending, half precision, без Lighting. Lit-шейдер на 500 частицах — распространённая ошибка, которая даёт -10 FPS.
Godot и GLSL ES
В Godot 4 шейдеры пишутся на диалекте GLSL с собственными расширениями. Шейдерный язык Godot компилируется в SPIR-V (Vulkan) или GLSL ES (совместимость). Для мобильного экспорта Godot использует Compatibility renderer на основе OpenGL ES 3.0 — он поддерживается шире, чем Vulkan на старых Android.
Что входит в нашу работу
- Получение и анализ референсов, целевых устройств.
- Разработка до 10 кастомных шейдеров с учётом TBDR и precision.
- Интеграция в ваш проект (Unity, Godot, Unreal).
- Профилирование и оптимизация до 60 FPS.
- Документация по шейдерам и их настройкам.
- Гарантия поддержки в течение 30 дней после сдачи.
Частые ошибки новичков
- Использование float везде, вместо half.
- Забывают про mip-maps.
- Применяют full-screen постэффекты без оглядки на бюджет.
Получите бесплатную оценку вашего проекта — свяжитесь с нами для консультации. Наши инженеры имеют 5+ лет опыта в мобильной графике и реализовали 50+ проектов для iOS и Android. Инвестиции в оптимизацию окупаются за счёт прироста FPS и снижения требований к железу. Закажите аудит шейдеров вашей игры — мы оценим потенциал оптимизации.
Более подробно о TBDR архитектуре можно прочитать в Wikipedia.







