Fragment Shader — cos'è, compiti e principio di funzionamento

Autore: IT Sectr Pubblicato: 2026-06-11 Tempo di lettura: 10 min

Fragment Shader è una fase programmabile della pipeline grafica che determina il colore finale di ogni frammento (pixel) di un'immagine. Secondo Khronos Group, 2025, lo shader di frammenti riceve dati interpolati dal Vertex Shader ed esegue calcoli di illuminazione, texturing ed effetti di colore. Fragment Shader viene invocato per ogni pixel, rendendolo la fase più dispendiosa in termini di risorse della pipeline grafica.

Punti chiave

  • Fragment Shader — una fase programmabile della GPU che determina il colore di ogni pixel sullo schermo.
  • Numero di invocazioni equivale alla risoluzione dello schermo, rendendolo il carico computazionale principale del rendering.
  • Texturing e illuminazione Phong sono compiti tipici implementati nello shader di frammenti.
  • GLSL e Metal Shading Language forniscono strumenti standard per scrivere Fragment Shader.
  • Prestazioni di Fragment Shader sono critiche per raggiungere 60 FPS nelle applicazioni mobili.

Cos'è Fragment Shader?

Fragment Shader (shader di frammenti o pixel) è una fase programmabile della pipeline grafica che calcola il colore finale di ogni frammento dell'immagine. Un frammento è un pixel potenziale che diventa un pixel visibile sullo schermo dopo aver superato i test di profondità e stencil.

Fragment Shader viene eseguito dopo la rasterizzazione, quando i primitivi 3D (triangoli) sono già stati convertiti in un insieme di frammenti. Lo shader riceve attributi interpolati — coordinate di texture, normali, colori che sono stati calcolati nel Vertex Shader per i vertici del triangolo e interpolati linearmente per ogni pixel all'interno del triangolo.

Storia dell'evoluzione di Fragment Shader

Prima dell'avvento degli shader programmabili (prima di DirectX 8 / OpenGL 2.0), il calcolo del colore dei pixel veniva eseguito da una pipeline fissa con un insieme limitato di operazioni. Il Fragment Shader programmabile è apparso nel 2001 e ha radicalmente ampliato le capacità grafiche: gli sviluppatori hanno ottenuto il controllo completo sul colore di ogni pixel, consentendo di implementare illuminazione fotorealistica, materiali complessi e post-effetti.

Come funziona Fragment Shader?

Fragment Shader viene avviato dalla GPU per ogni frammento generato dal rasterizzatore. Ogni invocazione dello shader elabora un frammento, legge i suoi dati di input, esegue il codice utente e scrive il valore di output — il colore del frammento in formato RGBA.

Dati di input e output

I dati di input di Fragment Shader includono attributi interpolati dal Vertex Shader (coordinate di texture, normali, colori), variabili uniform (fonti di luce, matrici) e sampler di texture. I dati di output sono il vettore di colore (gl_FragColor in OpenGL ES 2.0 o una variabile definita dall'utente in ES 3.0), che viene scritto nel buffer di colore.

glsl
#version 300 es
precision mediump float;

in vec2 vTexCoord;
uniform sampler2D uTexture;
out vec4 fragColor;

void main() {
    fragColor = texture(uTexture, vTexCoord);
}

Compiti principali di Fragment Shader

Fragment Shader è responsabile della qualità visiva dell'immagine. Tutti gli effetti che l'utente vede sullo schermo — colore, ombre, riflessi, trasparenza — vengono calcolati in questa fase della pipeline grafica.

Texturing

L'operazione più frequente è il campionamento del colore da una texture utilizzando coordinate UV interpolate. Sampler2D e la funzione texture() permettono di ottenere il colore di un pixel da un atlas di texture. Il filtraggio (bilineare, trilineare, anisotropico) è controllato attraverso i parametri del sampler e influisce sulla nitidezza dell'immagine a diversi angoli di visuale.

Illuminazione Phong

Il modello di illuminazione Phong viene calcolato in Fragment Shader per pixel, fornendo riflessi più morbidi rispetto all'illuminazione per vertici (ombreggiatura Gouraud). L'illuminazione Phong include tre componenti: ambiente, diffusa e speculare.

glsl
// 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);
}

Post-effetti e blending

Fragment Shader consente di applicare post-elaborazione: correzione del colore tramite tabelle di lookup (LUT), sfocatura (blur), effetto bagliore (bloom) e tonemapping per il rendering HDR. Tutti questi effetti funzionano a livello di pixel e vengono eseguiti in tempo reale.

Prestazioni e ottimizzazione di Fragment Shader

Le prestazioni di Fragment Shader sono il fattore principale che limita gli FPS nei giochi mobili moderni. Poiché lo shader viene invocato per ogni pixel, anche un piccolo aumento della complessità del codice può portare a un notevole calo del frame rate.

Principali problemi di prestazioni

  • Overdraw — ridisegno dello stesso pixel a causa della sovrapposizione di oggetti. Particolarmente critico per oggetti semitrasparenti.
  • Rami condizionali — le diramazioni in Fragment Shader riducono l'efficienza dell'esecuzione SIMD, poiché la GPU deve eseguire entrambi i rami.
  • Campionamenti di texture — ogni campionamento di texture ha una latenza di decine di cicli di clock della GPU. Minimizzare il numero di sampler accelera lo shader.

Metodi di ottimizzazione di Fragment Shader

Per GPU mobili (Qualcomm Adreno, ARM Mali) si raccomanda di: usare mediump precision per variabili float, combinare campionamenti di texture, applicare test early-z per scartare frammenti invisibili prima dell'esecuzione dello shader.

MetodoDescrizioneGuadagno
Mediump precisionPrecisione a 16 bit invece di 32 bitFino a 2x velocità
Early-ZTest di profondità prima dello shaderRiduzione invocazioni
Texture atlasingUna texture invece di piùMeno cambi

Fragment Shader vs Vertex Shader: confronto

Entrambi i tipi di shader sono programmabili dallo sviluppatore, ma lavorano in fasi diverse della pipeline e risolvono compiti diversi. Fragment Shader è significativamente più dispendioso in termini di risorse a causa del numero di invocazioni.

ParametroFragment ShaderVertex Shader
Numero di invocazioniMilioni (risoluzione schermo)Migliaia (numero di vertici)
Dati di inputAttributi interpolatiAttributi dei vertici
Funzione principaleCalcolo del colore del frammentoTrasformazione della geometria
Accesso alle textureCompleto (più sampler)Limitato
Impatto sulle prestazioniAlto (dipende dalla risoluzione)Moderato (dipende dalla geometria)

Esempi di codice Fragment Shader

Fragment Shader può essere semplice (campionamento di texture) o complesso (illuminazione multistrato). Consideriamo due esempi pratici: texturing di base e un effetto gradiente usando il tempo.

Texturing di base in GLSL

glsl
#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);
}

Esempio in Metal Shading Language

cpp
#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;
}

Domande frequenti

Cos'è Fragment Shader in parole semplici?

Fragment Shader è un mini-programma sulla GPU che determina di che colore sarà ogni pixel sullo schermo. Se Vertex Shader determina la forma dell'oggetto, allora Fragment Shader determina l'aspetto di quell'oggetto — texture, illuminazione, colore.

Perché Fragment Shader consuma così tante risorse?

Fragment Shader viene invocato per ogni pixel sullo schermo. Su un dispositivo con risoluzione 2532x1170 (iPhone) si tratta di quasi 3 milioni di invocazioni per frame. A 60 FPS lo shader viene eseguito 180 milioni di volte al secondo, richiedendo un'enorme potenza di calcolo.

Quali effetti si possono creare in Fragment Shader?

In Fragment Shader si implementano: texturing, illuminazione (Phong, PBR), ombre, riflessi, rifrazioni, bloom, profondità di campo, correzione del colore, filtri LUT e generazione procedurale di texture.

Come ottimizzare Fragment Shader sui dispositivi mobili?

Usa mediump precision per float, riduci il numero di campionamenti di texture, applica early-z culling, combina le operazioni dello shader ed evita rami condizionali all'interno dello shader.

Qual è la differenza tra Fragment Shader e Pixel Shader?

È la stessa cosa. Il termine Fragment Shader viene usato in OpenGL / Vulkan, mentre Pixel Shader viene usato nella terminologia Direct3D (Microsoft). Funzionalmente sono identici: entrambi calcolano il colore di ogni frammento/pixel.

Riepilogo

  • Fragment Shader — una fase programmabile della GPU che calcola il colore di ogni pixel dell'immagine.
  • Numero di invocazioni equivale alla risoluzione dello schermo, rendendolo la fase di rendering più dispendiosa in risorse.
  • Texturing, illuminazione Phong e post-effetti sono i compiti principali dello shader di frammenti.
  • Prestazioni dipendono direttamente dal numero di campionamenti di texture e dall'uso di highp precision.
  • Mediump precision e test early-z sono le tecniche chiave di ottimizzazione per GPU mobili.
  • OpenGL ES usa il termine Fragment Shader, Direct3D usa Pixel Shader — il significato è lo stesso.
  • GLSL e Metal Shading Language sono i principali linguaggi per scrivere Fragment Shader nello sviluppo mobile.

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche