Fragment Shader — este o etapă programabilă a conductei grafice care determină culoarea finală a fiecărui fragment (pixel) al imaginii. Potrivit datelor Khronos Group, 2025, shader-ul de fragmente primește date interpolate de la Vertex Shader și efectuează calcule de iluminare, texturare și efecte cromatice. Fragment Shader este apelat pentru fiecare pixel, ceea ce îl face cea mai consumatoare resurse etapă a conductei grafice.
Principalele puncte
Fragment Shader (shader de fragmente sau pixeli) — este o etapă programabilă a conductei grafice care calculează culoarea finală a fiecărui fragment al imaginii. Fragmentul este un pixel potențial care, după trecerea testelor de adâncime și șablon, devine un pixel vizibil pe ecran.
Fragment Shader se execută după rasterizare, când primitivele tridimensionale (triunghiuri) au fost deja transformate într-un set de fragmente. La intrare, shader-ul primește atribute interpolate — coordonate de textură, normale, culori care au fost calculate în Vertex Shader pentru vârfurile triunghiului și interpolate liniar pentru fiecare pixel din interiorul acestuia.
Înainte de apariția shader-elor programabile (înainte de DirectX 8 / OpenGL 2.0), calcularea culorii pixelului era efectuată de o conductă fixă cu un set limitat de operații. Fragment Shader programabil a apărut în 2001 și a extins radical capacitățile grafice: dezvoltatorii au obținut control complet asupra culorii fiecărui pixel, ceea ce a permis implementarea iluminării fotorealiste, a materialelor complexe și a post-efectelor.
Fragment Shader este lansat de GPU pentru fiecare fragment generat de rasterizator. Fiecare apel al shader-ului procesează un fragment, citește datele sale de intrare, execută codul utilizatorului și scrie valoarea de ieșire — culoarea fragmentului în format RGBA.
Datele de intrare ale Fragment Shader includ atribute interpolate de la Vertex Shader (coordonate de textură, normale, culori), variabile uniform (surse de lumină, matrici) și sampleare de textură. Datele de ieșire — vectorul de culoare (gl_FragColor în OpenGL ES 2.0 sau variabilă utilizator în ES 3.0) care este scris în buffer-ul de culoare.
#version 300 es
precision mediump float;
in vec2 vTexCoord;
uniform sampler2D uTexture;
out vec4 fragColor;
void main() {
fragColor = texture(uTexture, vTexCoord);
}
Fragment Shader răspunde de calitatea vizuală a imaginii. Toate efectele pe care utilizatorul le vede pe ecran — culoare, umbre, reflexii, transparență — se calculează exact în această etapă a conductei grafice.
Cea mai frecventă operație — extragerea culorii din textură după coordonatele UV interpolate. Sampler2D și funcția texture() permit obținerea culorii pixelului din atlasul de texturi. Filtrarea (bilineară, trilineară, anizotropică) este controlată prin parametrii sampler-ului și influențează claritatea imaginii la diferite unghiuri de vizualizare.
Modelul de iluminare Phong (Phong shading) se calculează în Fragment Shader pentru fiecare pixel, ceea ce oferă reflexii mai netede decât iluminarea pe vârfuri (Gouraud shading). Phong lighting include trei componente: ambient (de fundal), diffuse (difuză) și specular (speculară).
// Shader de fragmente cu iluminare Phong
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 permite aplicarea post-procesării: corecția culorii prin tabele LUT, estomparea (blur), efectul de strălucire (bloom) și tonemapping pentru randarea HDR. Toate aceste efecte funcționează la nivel de pixeli și sunt executate în timp real.
Performanța Fragment Shader — factorul principal care limitează FPS în jocurile mobile moderne. Deoarece shader-ul este apelat pentru fiecare pixel, chiar și o mică creștere a complexității codului poate duce la o scădere vizibilă a ratei cadrelor.
Pentru GPU-urile mobile (Qualcomm Adreno, ARM Mali) se recomandă: utilizarea mediump precision pentru variabilele float, combinarea extragerilor de textură, aplicarea testelor early-z pentru eliminarea fragmentelor invizibile înainte de execuția shader-ului.
| Metodă | Descriere | Câștig |
|---|---|---|
| Mediump precision | Precizie de 16 biți în loc de 32 de biți | Până la 2x viteză |
| Early-Z | Test de adâncime înainte de shader | Reducerea apelurilor |
| Texture atlasing | O singură textură în loc de mai multe | Mai puține comutări |
Ambele tipuri de shader-e sunt programate de dezvoltator, dar lucrează în etape diferite ale conductei și rezolvă sarcini diferite. Fragment Shader este semnificativ mai consumator de resurse din cauza numărului de apeluri.
| Parametru | Fragment Shader | Vertex Shader |
|---|---|---|
| Numărul de apeluri | Milioane (rezoluția ecranului) | Mii (numărul de vârfuri) |
| Date de intrare | Atribute interpolate | Atributele vârfurilor |
| Funcția principală | Calculul culorii fragmentului | Transformarea geometriei |
| Acces la texturi | Complet (mai multe samplere) | Limitat |
| Impact asupra performanței | Ridicat (depinde de rezoluție) | Moderat (depinde de geometrie) |
Fragment Shader poate fi simplu (extragere din textură) sau complex (iluminare pe mai multe straturi). Să analizăm două exemple practice: texturarea de bază și efectul de gradient utilizând timpul.
#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;
}
Întrebări frecvente
Fragment Shader — este un mini-program pe GPU care determină ce culoare va avea fiecare pixel de pe ecran. Dacă Vertex Shader determină forma obiectului, atunci Fragment Shader determină cum arată acel obiect — textură, iluminare, culoare.
Fragment Shader este apelat pentru fiecare pixel de pe ecran. Pe un dispozitiv cu rezoluția 2532x1170 (iPhone) aceasta înseamnă aproape 3 milioane de apeluri per cadru. La 60 FPS, shader-ul se execută de 180 de milioane de ori pe secundă, ceea ce necesită o putere de calcul enormă.
În Fragment Shader se implementează: texturarea, iluminarea (Phong, PBR), umbrele, reflexiile, refracțiile, bloom, adâncimea de câmp, corecția culorii, filtrele LUT și generarea procedurală de texturi.
Utilizați mediump precision pentru float, reduceți numărul de extrageri de textură, aplicați eliminarea early-z, combinați operațiile shader-ului și evitați ramificările condiționale în interiorul shader-ului.
Este același lucru. Termenul Fragment Shader este utilizat în OpenGL / Vulkan, iar Pixel Shader — în terminologia Direct3D (Microsoft). Funcțional sunt identice: ambele calculează culoarea fiecărui fragment/pixel.
Rezumat
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și