Ми розробляємо кастомні шейдери для мобільних ігор з урахуванням архітектури мобільних 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.







