Fragment Shader — je programovatelná fáze grafické pipeline, která určuje konečnou barvu každého fragmentu (pixelu) obrázku. Podle údajů Khronos Group, 2025, fragmentový shader přijímá interpolovaná data z Vertex Shader a provádí výpočty osvětlení, texturování a barevných efektů. Fragment Shader je volán pro každý pixel, což z něj činí nejnáročnější fázi grafické pipeline z hlediska zdrojů.
Hlavní body
Fragment Shader (fragmentový nebo pixelový shader) — je programovatelná fáze grafické pipeline, která vypočítává konečnou barvu každého fragmentu obrázku. Fragment je potenciální pixel, který se po absolvování testů hloubky a šablony stává viditelným pixelem na obrazovce.
Fragment Shader se provádí po rasterizaci, kdy byly trojrozměrné primitivy (trojúhelníky) již převedeny na sadu fragmentů. Shader na vstupu přijímá interpolované atributy — texturové souřadnice, normály, barvy, které byly vypočteny ve Vertex Shader pro vrcholy trojúhelníku a lineárně interpolovány pro každý pixel uvnitř něj.
Před příchodem programovatelných shaderů (před DirectX 8 / OpenGL 2.0) byl výpočet barvy pixelu prováděn pevnou pipeline s omezenou sadou operací. Programovatelný Fragment Shader se objevil v roce 2001 a radikálně rozšířil možnosti grafiky: vývojáři získali plnou kontrolu nad barvou každého pixelu, což umožnilo realizovat fotorealistické osvětlení, komplexní materiály a post-efekty.
Fragment Shader je spouštěn GPU pro každý fragment generovaný rasterizátorem. Každé volání shaderu zpracovává jeden fragment, čte jeho vstupní data, provádí uživatelský kód a zapisuje výstupní hodnotu — barvu fragmentu ve formátu RGBA.
Vstupní data Fragment Shader zahrnují interpolované atributy z Vertex Shader (texturové souřadnice, normály, barvy), uniformní proměnné (zdroje světla, matice) a texturové samplery. Výstupní data — barevný vektor (gl_FragColor v OpenGL ES 2.0 nebo uživatelská proměnná v ES 3.0), který je zapsán do barevného bufferu.
#version 300 es
precision mediump float;
in vec2 vTexCoord;
uniform sampler2D uTexture;
out vec4 fragColor;
void main() {
fragColor = texture(uTexture, vTexCoord);
}
Fragment Shader je zodpovědný za vizuální kvalitu obrazu. Všechny efekty, které uživatel vidí na obrazovce — barva, stíny, odrazy, průhlednost — se počítají právě v této fázi grafické pipeline.
Nejčastější operace — získání barvy z textury podle interpolovaných UV souřadnic. Sampler2D a funkce texture() umožňují získat barvu pixelu z texturového atlasu. Filtrace (bilineární, trilineární, anizotropní) je řízena parametry samplera a ovlivňuje ostrost obrazu při různých úhlech pohledu.
Model osvětlení Phong (Phong shading) se počítá ve Fragment Shader pro každý pixel, což poskytuje hladší odlesky než vrcholové osvětlení (Gouraud shading). Phong lighting zahrnuje tři složky: ambient (okolní), diffuse (difuzní) a specular (zrcadlový odraz).
// Fragment shader s Phong osvětlením
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 umožňuje aplikovat post-processing: korekci barev pomocí LUT tabulek, rozostření (blur), efekt záře (bloom) a tonemapping pro HDR renderování. Všechny tyto efekty pracují na úrovni pixelů a jsou prováděny v reálném čase.
Výkon Fragment Shader — hlavní faktor omezující FPS v moderních mobilních hrách. Protože je shader volán pro každý pixel, i malé zvýšení složitosti kódu může vést k znatelnému poklesu snímkové frekvence.
Pro mobilní GPU (Qualcomm Adreno, ARM Mali) se doporučuje: použití mediump precision pro float proměnné, kombinování vzorkování textur, aplikování early-z testů pro vyřazení neviditelných fragmentů před provedením shaderu.
| Metoda | Popis | Zisk |
|---|---|---|
| Mediump precision | 16bitová přesnost místo 32bitové | Až 2x rychlost |
| Early-Z | Test hloubky před shaderem | Snižení volání |
| Texture atlasing | Jedna textura místo několika | Méně přepínání |
Oba typy shaderů jsou programovány vývojářem, ale pracují v různých fázích pipeline a řeší různé úkoly. Fragment Shader je výrazně náročnější na zdroje kvůli počtu volání.
| Parametr | Fragment Shader | Vertex Shader |
|---|---|---|
| Počet volání | Miliony (rozlišení obrazovky) | Tisíce (počet vrcholů) |
| Vstupní data | Interpolované atributy | Atributy vrcholů |
| Hlavní funkce | Výpočet barvy fragmentu | Transformace geometrie |
| Přístup k texturám | Plný (více samplerů) | Omezený |
| Dopad na výkon | Vysoký (závisí na rozlišení) | Mírný (závisí na geometrii) |
Fragment Shader může být jednoduchý (vzorkování textury) nebo složitý (vícevrstvé osvětlení). Podívejme se na dva praktické příklady: základní texturování a efekt gradientu s použitím času.
#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;
}
Často kladené otázky
Fragment Shader — je mini-program na GPU, který určuje, jakou barvu bude mít každý pixel na obrazovce. Pokud Vertex Shader určuje tvar objektu, pak Fragment Shader určuje, jak tento objekt vypadá — textura, osvětlení, barva.
Fragment Shader je volán pro každý pixel na obrazovce. Na zařízení s rozlišením 2532x1170 (iPhone) to je téměř 3 miliony volání za snímek. Při 60 FPS se shader provádí 180 milionkrát za sekundu, což vyžaduje obrovský výpočetní výkon.
Ve Fragment Shader se implementují: texturování, osvětlení (Phong, PBR), stíny, odrazy, lom světla, bloom, hloubka ostrosti, korekce barev, LUT filtry a procedurální generování textur.
Používejte mediump precision pro float, snižte počet vzorkování textur, aplikujte early-z vyřazování, kombinujte operace shaderu a vyhýbejte se podmíněnému větvení uvnitř shaderu.
Je to totéž. Termín Fragment Shader se používá v OpenGL / Vulkan, zatímco Pixel Shader v terminologii Direct3D (Microsoft). Funkčně jsou identické: oba počítají barvu každého fragmentu/pixelu.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také