nVidia MFAA antialiasing: la migliore alternativa a Supersampling e Multisampling

Durante la renderizzazione di una scena tridimensionale le schede video lavorano con triangoli e linee che per essere mostrati a schermo devono prima essere campionati (sampling). Il campionamento è un’operazione molto semplice: quando una linea attraversa più pixel, la GPU sceglie un punto all’interno di ciascuno di essi, valuta il colore associato all’area adiacente e in base a quello decide come colorare l’intero pixel. La colorazione dei pixel è ciò che consente al sistema di “dipingere” la scena sullo schermo. Il problema dell’aliasing  si genera nel momento in cui la GPU deve effettuare il campionamento su una linea non perfettamente verticale od orizzontale, e si manifesta soprattutto sui bordi degli oggetti tridimensionali, oppure nelle regioni di confine caratterizzate da repentini cambiamenti nella tonalità del colore. L’immagine sottostante presenta un chiaro esempio di aliasing:

 

aliased-image-me

 

Ma come si creano di preciso le scalettature? L’immagine che vediamo sullo schermo del nostro computer viene creata a partire da una griglia di pixel, il cui colore è determinato dalla GPU. Per semplicità assumiamo di voler tracciare una linea obliqua avendo a disposizione solo due colori, bianco per lo sfondo e nero per i poligoni. Se il campionamento è singolo la scelta è semplice: il pixel sarà tutto bianco, oppure tutto nero. Se invece il campionamento è multiplo, e quindi la GPU valuta più punti all’interno del pixel, il colore risultante avrà una gradazione intermedia tra il bianco e il nero. Nel primo caso si avrà un effetto di aliasing piuttosto evidente, mentre nel secondo le scalettature saranno meno accentuate. Intuitivamente comprendiamo subito che per limitare il problema dell’aliasing è necessario ricolorare i pixel effettuando il maggior numero possibile di campionamenti, in modo da rendere meno evidente la transizione tra un colore e l’altro. Proveremo ad illustrare meglio il concetto servendoci di alcune semplici immagini. Come già accennato il monitor del nostro computer può essere visto come una griglia suddivisa in quadrati di uguale dimensione, dove ciascun quadrato rappresenta un pixel. Cosa accade nel momento in cui proviamo a disegnare una linea obliqua?

 

griglia-1

 

griglia-2

 

Se la linea copre almeno il 50% del pixel la GPU colora l’intero quadrato di nero, in caso contrario lo colora di bianco. Come potete notare seguendo questo approccio la GPU non può fare a meno di disegnare una linea scalettata, che costituisce una rozza approssimazione della geometria di partenza. Ovviamente nel nostro esempio i pixel sono grandissimi, quindi il risultato finale è particolarmente accentuato! Sul monitor del vostro computer l’effetto non sarà mai così evidente, perché il risultato migliora con l’aumento della risoluzione (rappresentata dal numero di quadratini). Quello che ci serve ora è un metodo per prendere i pixel della prima immagine, che sono solo parzialmente colorati, e generare una transizione più morbida tra il nero e il bianco in modo tale che le scalettature siano meno evidenti.

 

griglia-3

 

griglia-4

 

griglia-5

 

Grazie alla nostra opera di “sfumatura” dei pixel il miglioramento tra la prima e la terza immagine è piuttosto netto, e se i pixel fossero più piccoli sarebbe ancor più marcato. Per ottenere questo risultato abbiamo “campionato” gruppi di pixel presi dal bordo della figura, ne abbiamo determinato il colore medio e successivamente abbiamo “sfumato” la colorazione dei gruppi di pixel al confine. Questo è a grandi linee il principio sul quale si fondano i filtri di antialiasing, studiati con il preciso scopo di eliminare le scalettature sui bordi degli oggetti renderizzati a schermo.

 

 

HARDWARE ANTIALIASING: SUPERSAMPLING (SSAA) E MULTISAMPLING (MSAA)
Ora sappiamo che l’aliasing può essere ridotto colorando in modo opportuno i pixel che delimitano il bordo degli oggetti. Ma come fa la GPU a determinare quali sono questi pixel? E una volta trovati, come fa a stabilire la gradazione di colore da assegnare? Nella pratica calcolare l’esatto numero di pixel che definiscono i bordi di un poligono potrebbe richiedere un tempo infinito, quindi occorre studiare degli algoritmi che agiscano in modo approssimato. La tecnica più semplice, ma anche la più dispendiosa in termini di risorse, è il Supersampling (SSAA). Assumiamo che il nostro monitor viaggi ad una risoluzione di 800×600 pixel. Se decidiamo di applicare 4 livelli di antialiasing con la tecnica supersampling, la nostra GPU deve renderizzare la scena al quadruplo della risoluzione originale (1600x1200p) creando quattro pixel per ogni pixel nativo, effettuare un downscaling a 800x600p e calcolare nel frattempo la media del colore di ogni quaterna di pixel così ottenuta, assegnandola ad un singolo quadrato.

 

subpixel-1

 

In realtà le GPU moderne non renderizzano tutta la scena al quadruplo della risoluzione, ma creano dei subpixel per ogni sample e lavorano su quelli. Immaginiamo allora che il quadrato qui sopra rappresenti un singolo pixel, suddiviso dalle linee rosse in quattro subpixel. Se la GPU sta applicando 4 livelli di SSAA, dopo aver creato quattro nuovi quadratini deve calcolare il colore dell’area che circonda ciascuno dei punti rossi posti al centro del rispettivo subpixel, trattandoli come se fossero pixel separati. Per ciascuno di questi subpixel la GPU deve poi campionare le informazioni relative alle texture, effettuare le operazioni di shading, controllare lo z-buffer e occuparsi della gestione delle luci, assegnando infine il colore. Questa tecnica elimina quasi del tutto le scalettature e aumenta significativamente la qualità dell’immagine, sia sui bordi che all’interno dei pixel, ma sfortunatamente si tratta di un procedimento molto dispendioso che mette a dura prova le risorse hardware a disposizione. Pur eliminando le scalettature, infatti, il SSAA costringe la GPU a sobbarcarsi il quadruplo del lavoro, e oltretutto rischia di saturare la VRAM a causa delle informazioni duplicate associate alle texture.

 

Per ovviare al problema delle prestazioni è stata creata una versione ottimizzata del Supersampling, chiamata Multisampling (MSAA). Riprendiamo ora l’esempio di SSAA illustrato in precedenza, ma questa volta cerchiamo di sfruttare le risorse in modo più intelligente, senza costringere la scheda video a renderizzare la scena ad una risoluzione superiore. Teniamo la suddivisione in subpixel, assicurandoci però che nella fase di campionamento ogni quadratino contenga le stesse informazioni sulle texture, sugli shader e sull’illuminazione, evitando costose duplicazioni.

 

subpixel-2

 

Inizialmente la GPU elabora le informazioni sulle texture ed esegue i calcoli sull’illuminazione come se non stesse applicando alcun algoritmo di antialiasing. Il campionamento è fissato al centro del pixel, che abbiamo indicato con un quadratino blu. Nel caso di MSAA a 4 livelli la scheda renderizza ancora ogni singolo subpixel all’interno del pixel, ma senza occuparsi ogni volta delle texture e degli shader. Questo consente al chip di mettere in cache tutti i dati – in modo tale da alleggerire il carico sulla VRAM – e di applicare l’antialiasing solamente ai bordi degli oggetti. Il valore dello z-buffer, che indica la profondità dell’oggetto da renderizzare, è comparato con ciascuno dei campionamenti effettuati sui subpixel: se sono tutti uguali, allora la GPU capisce di essere all’interno dell’oggetto e non interviene; se sono diversi, invece, capisce di trovarsi su uno dei bordi e procede alla rimozione delle scalettature.

 

msaa-vs-ssaa

 

Il risultato che otteniamo applicando il MSAA è qualitativamente inferiore rispetto a quello ottenuto con il SSAA, ma ha un impatto sulle prestazioni quattro volte più leggero. Ha però un difetto, ovvero quello di non intervenire sulle texture che ricoprono l’area all’interno dei poligoni renderizzati. Il problema diventa evidente soprattutto quando la GPU deve disegnare oggetti tridimensionali trasparenti (come grate, reti, fogliame, etc…) e può essere risolto solamente affiancando all’MSAA un filtro adattivo per l’antialiasing delle trasparenze, come illustrato nell’immagine sottostante:

 

TrAA-in-Modern-Games

 

 

ANTIALIASING IN POST-PROCESSING
Sebbene i filtri SSAA e MSAA riescano a limitare efficacemente il problema dell’aliasing, il loro costo in termini di risorse spesso è troppo elevato per la maggior parte delle GPU. Per questa ragione nVidia e AMD hanno elaborato nel tempo nuove strategie per eliminare le scalettature senza impattare eccessivamente sulle prestazioni. L’idea è quella di agire sulle immagini a livello software, quando la scena è già stata renderizzata dalla GPU, senza costringere il chip a lavorare costantemente sui subpixel.

 

nVidia Fast Approximate (FXAA): Invece di campionare i subpixel a livello hardware come fanno SSAA e MFAA, l’FXAA agisce via software in fase di post-processing. Per eliminare le scalettature il filtro FXAA analizza l’immagine già renderizzata e cerca di stabilire in modo approssimativo quali siano i bordi che necessitano di essere smussati. A differenza del Multisampling, l’FXAA interviene anche sugli artefatti che si generano all’interno dei pixel. Il suo costo in termini di risorse è ridottissimo, ma il risultato finale è qualitativamente inferiore rispetto a quello assicurato dai filtri hardware. Il problema risiede nel fatto che l’FXAA utilizza un effetto motion blur per smussare i bordi dei poligoni, che causa una forte sfocatura dell’immagine. Inoltre gli effetti dell’FXAA vengono quasi totalmente annullati quando gli elementi sono in movimento. Esiste un equivalente AMD chiamato MLAA (Morphological Antialiasing).

 

FXAA-nvidia

 

Enhanced Subpixel Morphological (SMAA): Questa tecnica di antialiasing è stata svuluppata da Crytek tra il 2011 e il 2012. L’SMAA elimina le scalettature adottando una tecnica ibrida che combina le caratteristiche di MSAA e SSAA con alcuni elementi tipici dei filtri post-processing. L’SMAA rappresenta attualmente il migliore connubio tra qualità e prestazioni, ma non tutti i giochi lo supportano e non può essere abilitato via hardware.

 

SMAA-nvidia

 

 

nVidia Temporal Antialiasing (TXAA): Introdotto per la prima volta con le GPU della famiglia Kepler (Geforce serie 600-700), l’antialiasing temporale è un filtro di post-processing che combina MSAA e FXAA. Il TXAA è particolarmente efficace nel risolvere i problemi relativi agli oggetti in movimento tipici del FXAA e ha un impatto ridottissimo sulle prestazioni, ma non è in grado di offrire lo stesso grado di qualità dei filtri più avanzati (SSAA, MSAA, SMAA).

 

TXAA-nvidia

 

 

NVIDIA MULTI-FRAME ANTIALIASING
Una delle innovazioni più importanti introdotte da nVidia con l’architettura Maxwell (GeForce serie 900) è l’MFAA, acronimo di Multi-Frame Sampled Antialiasing. L’MFAA è un nuovo algoritmo che garantisce la stessa qualità del MSAA-4X con un impatto sulle prestazioni dimezzato, paragonabile a quello del MSAA-2X. Come abbiamo spiegato in precedenza, il filtro MSAA a 4 livelli opera su quattro campionamenti (subpixel) per ogni singolo pixel, che preleva seguendo uno schema pre-programmato. L’MSAA agisce inoltre in una dimensione esclusivamente spaziale, ovvero non include nel campionamento alcun pixel appartenente ai frame precedenti. L’MFAA invece si comporta in modo diverso: all’inizio applica un filtro MSAA-2X operando su due campionamenti del frame ‘n’, dopodiché li raddoppia includendo altri due campionamenti del frame ‘n-1’ – per un totale di quattro campionamenti, che a differenza del MSAA possono essere raccolti seguendo uno schema casuale.

 

nvidia-mfaa-1

 

La nuova tecnologia di posizione del campione basata sulla RAM di Maxwell può ancora essere programmata con i motivi standard MSAA e TXAA, ma ora il driver o l’applicazione possono anche caricare nella RAM posizioni personalizzate che sono libere di variare da frame a frame, o persino nel contesto di un unico frame.

 

nvidia-mfaa-2

 

Ciascun campionamento è salvato in uno schema che indica il posizionamento dei singoli pixel, dopodiché l’algoritmo valuta le differenze tra i due frame adiacenti e applica un filtro TSF (Temporal Synthesis Filter). Il colore del pixel risultante viene poi determinato in funzione dei calcoli effettuati dal TSF. In sintesi, l’MFAA combina la tecnica di campionamento spaziale del MSAA a due livelli con quella di campionamento temporale del TXAA, ottenendo un risultato qualitativamente analogo a quello dei filtri hardware, però con un impatto sulle prestazioni molto simile a quello dei filtri di post-processing.

 

MFAA-comparo

 

L’approccio adottato da nVidia nella progettazione del suo Multi-Frame Sampled Antialiasing costuisce la perfetta sintesi delle tecniche di antialiasing avvicendatesi nell’ultimo decennio, e potrebbe rappresentare la soluzione definitiva per tutti quegli utenti che mirano ad ottenere la miglior resa grafica con un occhio di riguardo al portafogli. Per il momento sono pochissimi i giochi che supportano l’MFAA, ma in futuro le cose cambieranno e non è da escludere che nel giro di pochi anni potremmo assistere ad un definitivo abbandono delle tecniche di antialiasing basate esclusivamente su campionamento hardware. Per una valutazione più approfondita delle prestazioni del Multi-Frame Samplet Antialiasing vi rimandiamo a questo articolo di Tom’s Hardware.

 

FONTI: Hardware Luxx nVidia – Wikipedia – Tom’s Hardware

TODAY

17 Dec

Sunday

Le Rubriche

Photo Gallery