Fragment Shader — це програмований етап графічного конвеєра, що визначає підсумковий колір кожного фрагмента (пікселя) зображення. За даними Khronos Group, 2025, фрагментний шейдер отримує інтерпольовані дані від Vertex Shader і виконує розрахунки освітлення, текстурування та колірних ефектів. Fragment Shader викликається для кожного пікселя, що робить його найбільш ресурсоємною стадією графічного конвеєра.
Головне
Fragment Shader (фрагментний або піксельний шейдер) — це програмована стадія графічного конвеєра, яка обчислює підсумковий колір кожного фрагмента зображення. Фрагмент — це потенційний піксель, який після проходження тестів глибини та трафарету стає видимим пікселем на екрані.
Fragment Shader виконується після растеризації, коли тривимірні примітиви (трикутники) вже перетворені на набір фрагментів. На вхід шейдер отримує інтерпольовані атрибути — текстурні координати, нормалі, кольори, які були розраховані у Vertex Shader для вершин трикутника та лінійно інтерпольовані для кожного пікселя всередині нього.
До появи програмованих шейдерів (до DirectX 8 / OpenGL 2.0) розрахунок кольору пікселя виконувався фіксованим конвеєром з обмеженим набором операцій. Програмований Fragment Shader з'явився у 2001 році та радикально розширив можливості графіки: розробники отримали повний контроль над кольором кожного пікселя, що дозволило реалізувати фотореалістичне освітлення, складні матеріали та пост-ефекти.
Fragment Shader запускається GPU для кожного фрагмента, згенерованого растеризатором. Кожен виклик шейдера обробляє один фрагмент, читає його вхідні дані, виконує користувацький код та записує вихідне значення — колір фрагмента у форматі RGBA.
Вхідні дані Fragment Shader включають інтерпольовані атрибути від Vertex Shader (текстурні координати, нормалі, кольори), uniform-змінні (джерела світла, матриці) та текстурні семплери. Вихідні дані — вектор кольору (gl_FragColor у OpenGL ES 2.0 або користувацька змінна в ES 3.0), який записується в колірний буфер.
#version 300 es
precision mediump float;
in vec2 vTexCoord;
uniform sampler2D uTexture;
out vec4 fragColor;
void main() {
fragColor = texture(uTexture, vTexCoord);
}
Fragment Shader відповідає за візуальну якість зображення. Всі ефекти, які користувач бачить на екрані — колір, тіні, відбиття, прозорість — розраховуються саме на цій стадії графічного конвеєра.
Найчастіша операція — вибірка кольору з текстури за інтерпольованими UV-координатами. Sampler2D та функція texture() дозволяють отримати колір пікселя з текстурного атласу. Фільтрація (bilinear, trilinear, anisotropic) контролюється через параметри семплера та впливає на чіткість зображення при різних кутах огляду.
Модель освітлення Фонга (Phong shading) розраховується у Fragment Shader для кожного пікселя, що дає більш гладкі відблиски, ніж вершинне освітлення (Gouraud shading). Phong lighting включає три компоненти: ambient (фонове), diffuse (розсіяне) та specular (дзеркальне відбиття).
// Fragment shader with Phong lighting
in vec3 vNormal;
in vec3 vPosition;
uniform vec3 uLightDir;
uniform vec3 uLightColor;
void main() {
vec3 norm = normalize(vNormal);
float diff = max(dot(norm, uLightDir), 0.0);
fragColor = vec4(uLightColor * diff, 1.0);
}
Fragment Shader дозволяє накладати пост-обробку: колірну корекцію через lookup-таблиці (LUT), розмиття (blur), ефект світіння (bloom) та tonemapping для HDR-рендерингу. Всі ці ефекти працюють на рівні пікселів і виконуються в реальному часі.
Продуктивність Fragment Shader — головний фактор, що обмежує FPS у сучасних мобільних іграх. Оскільки шейдер викликається для кожного пікселя, навіть невелике збільшення складності коду може призвести до помітного падіння частоти кадрів.
Для мобільних GPU (Qualcomm Adreno, ARM Mali) рекомендується: використовувати mediump precision для float-змінних, об'єднувати текстурні вибірки, застосовувати early-z тести для відбраковки невидимих фрагментів до виконання шейдера.
| Метод | Опис | Виграш |
|---|---|---|
| Mediump precision | 16-бітна точність замість 32-бітної | До 2x швидкості |
| Early-Z | Тест глибини перед шейдером | Скорочення викликів |
| Texture atlasing | Одна текстура замість кількох | Менше перемикань |
Обидва типи шейдерів програмуються розробником, але працюють на різних етапах конвеєра та вирішують різні завдання. Fragment Shader суттєво більш ресурсоємний через кількість викликів.
| Параметр | Fragment Shader | Vertex Shader |
|---|---|---|
| Кількість викликів | Мільйони (роздільна здатність екрана) | Тисячі (кількість вершин) |
| Вхідні дані | Інтерпольовані атрибути | Атрибути вершин |
| Основна функція | Розрахунок кольору фрагмента | Трансформація геометрії |
| Доступ до текстур | Повний (множина семплерів) | Обмежений |
| Вплив на продуктивність | Високий (залежить від роздільної здатності) | Помірний (залежить від геометрії) |
Fragment Shader може бути простим (вибірка з текстури) або складним (багатошарове освітлення). Розглянемо два практичні приклади: базове текстурування та ефект градієнта з використанням часу.
#version 300 es
precision mediump float;
in vec2 vTexCoord;
in vec3 vColor;
uniform sampler2D uDiffuseMap;
out vec4 fragColor;
void main() {
vec4 texColor = texture(uDiffuseMap, vTexCoord);
fragColor = texColor * vec4(vColor, 1.0);
}
#include <metal_stdlib>
using namespace metal;
struct FragmentIn {
float2 texCoord;
float3 normal;
};
fragment float4
fragmentMain(FragmentIn in [[stage_in]],
texture2d<float> tex [[texture(0)]]) {
constexpr sampler s(filter = linear);
float4 color = tex.sample(s, in.texCoord);
return color;
}
Часті запитання
Fragment Shader — це міні-програма на GPU, яка визначає, якого кольору буде кожен піксель на екрані. Якщо Vertex Shader визначає форму об'єкта, то Fragment Shader визначає, як цей об'єкт виглядає — текстура, освітлення, колір.
Fragment Shader викликається для кожного пікселя на екрані. На пристрої з роздільною здатністю 2532x1170 (iPhone) це майже 3 мільйони викликів за кадр. При 60 FPS шейдер виконується 180 мільйонів разів на секунду, що потребує величезної обчислювальної потужності.
У Fragment Shader реалізуються: текстурування, освітлення (Phong, PBR), тіні, відбиття, заломлення, bloom, глибина різкості, колірна корекція, LUT-фільтри та процедурна генерація текстур.
Використовуйте mediump precision для float, скоротіть кількість текстурних вибірок, застосовуйте early-z відбраковку, об'єднуйте шейдерні операції та уникайте умовних переходів всередині шейдера.
Це одне й те саме. Термін Fragment Shader використовується у OpenGL / Vulkan, а Pixel Shader — у термінології Direct3D (Microsoft). Функціонально вони ідентичні: обидва обчислюють колір кожного фрагмента/пікселя.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також