11

Shader e Stuttering: cosa sono e perché se ne parla così tanto

Vi parleremo delle problematiche che affliggono i giochi moderni e del perché le parole shader e stuttering siano adesso così presenti nelle analisi tecniche.

Shader e Stuttering: cosa sono e perché se ne parla così tanto
SPECIALE di Virginia Paravani   —   12/05/2023

Ci sono due precise parole che sono entrate nel nostro vocabolario negli ultimi due anni quando si analizza in modo tecnico un videogioco: gli shader e lo stuttering. Difficilmente, prima del 2020, questi due concetti venivano associati alle produzioni di videogiochi se non in analisi estremamente tecniche.

Ogni progresso in campo di codifica di codici sorgente o di motori grafici porta con sé anche la scoperta di nuovi limiti degli attuali metodi di programmazione, così da far affiorare alcune problematiche finora mai affrontate; finché la tecnologia non si è spinta tanto oltre, molti dei problemi attuali non erano calcolabili e prevedibili. La corsa alla miglior risoluzione, alla pulizia dei dettagli e al realismo in termini di illuminazione, ombre e modelli poligonali hanno dato il via a nuove difficoltà con cui gli sviluppatori devono combattere per ottimizzare al meglio il proprio prodotto.

In questo nostro speciale vi parleremo di come l'aumento del dettaglio grafico ha portato ai problemi di ottimizzazione che si riscontrano nelle produzioni recenti, con processi di calcolo indirizzati a schede video e processori sempre più complessi e difficili da digerire, tali da compromettere la fluidità in gioco con vistosi singhiozzi dell'immagine e tempi di caricamento sempre più consistenti.

Che cos'è uno shader?

Gli shader agiscono direttamente su molti degli aspetti grafici degli oggetti in gioco, una dimostrazione è il lavoro compiuto su Minecraft
Gli shader agiscono direttamente su molti degli aspetti grafici degli oggetti in gioco, una dimostrazione è il lavoro compiuto su Minecraft

Per poter approfondire questa tematica dobbiamo partire dalle basi iniziando dalla parte tecnica, ma spiegata con parole semplici; dunque, che cos'è uno shader? Ci sono vari tipi di shader ma potete considerarli un insieme di comandi, o meglio di istruzioni, che assieme creano un piccolo programma che va ad agire sulla visualizzazione di un'immagine a schermo. Ci sono ad esempio i vertex shader applicati ai vertici dei triangoli o i pixel shader che sono ovviamente applicati ai singoli pixel.

In sostanza, la programmazione del codice di un gioco determina cosa verrà riprodotto mentre lo shader agisce sul come sarà riprodotto. Questo processo può essere accomunato al creare un disegno su carta e, una volta delineate le forme, si passa a lavorare sui dettagli, le ombre e la colorazione: gli shader entrano in scena indicando appunto la tipologia di colore, geometria, luminosità, contrasto, nitidezza e tanto altro dell'oggetto prestabilito.

Per poter coprire tutti questi aspetti esistono varie tipologie di shader che agiscono nelle diverse sfere di influenza appena elencate: ad esempio, i pixel shader o i ray shader (nati con l'avvento del ray tracing) si occupano di impartire l'ordine su come l'illuminazione e il texturing apparirà a schermo. I videogiochi, rispetto ad altri programmi, richiedono una maggiore potenza di calcolo in quanto il contenuto grafico può essere estremamente dettagliato e calcolato in tempo reale tanto che ogni elemento su schermo riceverà migliaia di istruzioni.

Con la potenza delle CPU e GPU più recenti, il calcolo di tutte le istruzioni è rapidissimo nonostante, come accennato in precedenza, il lavoro degli shader sui pixel sia estremamente complesso. Risulta abbastanza ovvio che più un processore e una scheda grafica sono performanti, minore è il carico di lavoro a cui sono chiamate le componenti e migliore sarà la resa grafica e la fluidità di gioco. Seppure questo in parte spieghi come funzioni il lavoro dietro un disegno o un video in 3D, il processo di elaborazione dell'immagine e la sua resa grafica non finiscono qui.

I tempi di compilazione degli shader

Tutti codici che compongono la struttura di gioco, e allo stesso tempo gli shader, devono essere 'tradotti' per funzionare sull'hardware di destinazione
Tutti codici che compongono la struttura di gioco, e allo stesso tempo gli shader, devono essere "tradotti" per funzionare sull'hardware di destinazione

Una volta delineate le informazioni con cui gli shader dovranno subentrare nel processo vi è un passaggio a 2 fasi che converte concretamente il tutto in quello che si vede su schermo. Innanzitutto il programmatore sceglie a quale API, Application Programming Interface, appoggiarsi tra quelle comuni a disposizione, come ad esempio le Direct3D o le librerie Vulkan che convertiranno il linguaggio degli shader in un codice generico e poi intervengono i driver della GPU per tradurre questo risultato in un codice binario direttamente digeribile dal processore presente sulla scheda video. Per riassumere in modo molto superficiale, ogni codice sorgente o shader ha bisogno di essere "tradotto" per poter essere eseguito correttamente sull'hardware presente nella macchina.

Compiuta la conversione, il processo di computazione viene elaborato dalla GPU (in frazioni di secondo per dare un'idea) e se si è in possesso di componenti performanti non è in alcun modo percepibile, dato che il tutto avviene nella schermata principale o durante i caricamenti. Se invece la scheda video è datata o, soprattutto, i driver non sono correttamente ottimizzati, potrebbe subentrare il fenomeno dello stuttering visto che le GPU si ritrovano costrette a dare una scala di priorità ai calcoli da compiere richiedendo un tempo aggiuntivo rispetto al caricamento standard.

Questa introduzione offre la spiegazione a quelle problematiche che sempre più frequentemente si riscontrano nei giochi di recente fattura, una grana che non veniva percepita fino a qualche anno fa, o almeno non in modo così evidente. Vi basti pensare che agli albori di questa tecnologia i comandi che si potevano assegnare con gli shader erano massimo una decina mentre nelle produzioni recenti si superano di gran lunga le migliaia. Tutto ciò illustra, a grandi linee, come mai nei titoli recenti ci sono sempre più problematiche grafiche: l'aumento del dettaglio all'interno dei videogiochi comporta un maggior numero di shader in campo, un maggior numero di shader comporta più calcoli e, spesso, più problemi.

Il problema degli open world

Uno dei giochi che ha dovuto fare i conti con lo stuttering al lancio è Elden Ring
Uno dei giochi che ha dovuto fare i conti con lo stuttering al lancio è Elden Ring

Non è infatti un caso che tali problematiche siano sorte con gli open world degli ultimi anni: Cyberpunk 2077 ed Elden Ring sono due esempi fondamentali ben rappresentativi. Trattandosi di giochi molto estesi in termini di superficie giocabile, gli shader non vengono istantaneamente compilati per tutta l'area di gioco ed il processo avviene man mano che ci si avvicina a determinate zone: se ci troviamo ad esplorare Liurnia, il nostro PC in quel momento non calcola gli shader di Caelid, ma lo farà solamente quando ci avvicineremo a quell'area di influenza o durante il caricamento quando si compie un viaggio rapido.

Non sempre questa è una soluzione pratica per scongiurare problemi tecnici e tutto ciò cambia in funzione dell'hardware su cui si riproduce il gioco. Su console come PlayStation 5 e Xbox Series X è consuetudine che gli shader siano già precompilati, eliminando buona parte dei grattacapi con cui gli sviluppatori si trovano a lavorare per ottimizzare tutte le possibili combinazioni hardware in campo PC.

Qualsiasi team di sviluppo, quando lavora ad un gioco per console, sa che l'hardware è statico, ovvero tutte le PlayStation e Xbox hanno un determinato processore e una specifica scheda grafica, mentre nel momento in cui si approda su PC bisogna tenere conto di un numero enorme di combinazioni di CPU e GPU; questo chiarisce in parte perché su computer le problematiche sono esponenzialmente più probabili.

Come nasce lo stuttering?

Uno dei titoli ad offrire un'opzione per i giocatori sul caricamento degli shader è la versione PC di Horizon Zero Dawn
Uno dei titoli ad offrire un'opzione per i giocatori sul caricamento degli shader è la versione PC di Horizon Zero Dawn

La situazione della schermata di caricamento degli shader che abbiamo citato poco sopra è una delle soluzioni adottate dagli sviluppatori per prevenire alcune problematiche. Avviando su un PC equipaggiato di NVIDIA RTX 1060 da 3 GB e un Intel Core i7 di ottava generazione il porting dello scorso anno di Uncharted, abbiamo ricevuto un avviso nel menu principale che gli shader erano in caricamento e che avviare il gioco prima della fine di questa operazione avrebbe compromesso la resa grafica. Questo perché gli sviluppatori hanno preferito obbligare i giocatori ad attendere più a lungo all'inizio per non avere poi problemi durante la partita.

Un'altra soluzione è invece quella di far sì che gli shader si carichino solo quando richiesti; in questo caso il caricamento iniziale sarà più breve ma potrebbero sopraggiungere dei problemi in game: può infatti subentrare lo stuttering, ovvero il ritardo o la perdita di frame durante l'esecuzione. Se la libreria di shader venisse caricata in modo adeguato con un processo di ottimizzazione operato dagli sviluppatori, non ci dovrebbero essere questi fastidiosi singhiozzi grafici durante la partita.

Dal momento che i videogiochi moderni si sono fatti più complessi, anche gli shader sono divenuti sempre più articolati e lunghi, tanto da aumentare notevolmente il carico di lavoro richiesto per l'elaborazione. Per ovviare al problema dello stuttering vi è una via intermedia che prevede di compilare gli shader un po' alla volta, nascondendoli in parte nel menu principale e in parte durante i filmati, ma ovviamente tutto rimane dipendente dall'hardware in cui viene riprodotto il gioco.

Qual è la soluzione?

Hogwarts Legacy ha un caricamento degli shader variabile, caricandone alcuni all'avvio ed altri durante l'esecuzione
Hogwarts Legacy ha un caricamento degli shader variabile, caricandone alcuni all'avvio ed altri durante l'esecuzione

Purtroppo il giocatore può far ben poco, avendo come sola possibilità di lasciare la CPU più libera possibile durante il gioco, chiudendo ogni altro processo non essenziale in background. Il lavoro di ottimizzazione è completamente nelle mani degli sviluppatori e nell'impiego di fondi e di tempo nel risolvere queste problematiche anche con patch correttive post lancio. Ci piacerebbe poter dire che tutti i team di sviluppo impiegano enormi risorse nel controllare il gioco minuziosamente prima del debutto, ma la realtà è che il comparto di Q&A, come tanti altri, sono sempre meno centrali.

Se si pensa a cinque anni fa, la parola stuttering era probabilmente conosciuta da pochi, tanto che pochissime produzioni ne erano afflitte. Le ragioni sono molte e non solo biecamente riconducibili ad una "pigrizia" degli sviluppatori, costretti dai publisher a pubblicare i giochi il prima possibile e a compiere correzioni in corso d'opera. La programmazione si è fatta via via più complessa, le combinazioni di hardware sono divenute infinite ed i tempi di produzione sono aumentati a dismisura.

Al momento solo una manciata di giochi lascia la scelta sul caricamento degli shader in mano ai giocatori. Come per Uncharted citato poco sopra, anche Horizon Zero Dawn offre la possibilità di compilarli nella schermata del menu principale ma dà anche l'opzione di saltarli se le tempistiche previste divengono alte (situazione riscontrabile nelle configurazioni di fascia bassa, ovviamente). Hogwarts Legacy, invece, compila buona parte degli shader durante l'avvio e nel menu principale, lasciando che il resto si carichi durante l'esecuzione.

Un futuro a scatti

Il lavoro compiuto su Cyberpunk 2077 con il Path Tracing ci offre un possibile sguardo al futuro
Il lavoro compiuto su Cyberpunk 2077 con il Path Tracing ci offre un possibile sguardo al futuro

Anche i produttori di GPU giocano un ruolo fondamentale in questo processo, tanto che AMD e NVIDIA memorizzano gli shader comunemente utilizzati in cartelle specifiche sui nostri PC, ma vengono cancellate e sovrascritte ad ogni aggiornamento. Anche Steam cerca di fare la sua parte e offre un servizio di archiviazione cache per tutti quei giochi che operano tramite OpenGL o Vulkan, ma se provate a dare uno sguardo, quasi sempre questa cartella risulta vuota.

Nonostante alcune accortezze il tutto rimane in mano agli sviluppatori, che veterani o meno, devono fare i conti con questa problematica e avere sia il tempo che l'esperienza per far sì che il gioco sia esente da criticità. Dati i ritmi di questo settore e la corsa alla monetizzazione per rimanere competitivi sul mercato è più che lecito avere una visione cupa sul futuro. La scesa in campo del DLSS e del futuro FSR 3 che, grazie all'intelligenza artificiale permettono miglioramenti significativi ai frame per secondo con poco sforzo "umano", è una variante da aggiungere nel calderone dei problemi che affliggono le produzioni moderne, che riducono il tempo speso nel controllo qualità in fase di testing.

La speranza è che i motori grafici divengano più facilmente gestibili da parte delle software house, che si trovano altresì costrette a fare i conti con feature sempre più nuove e pesanti come vi abbiamo raccontato nel nostro approfondito speciale su Unreal Engine 5: ulteriori processi che incidono sulla visualizzazione dell'oggetto, che creano a sua volta altri calcoli, alcuni dei quali che appesantiscono l'elaborazione inutilmente. Una corsa al massimo impatto grafico che sembra non arrestarsi più.