Sotto la Scocca

Risoluzione dinamica e Tile Rendering – Sotto la Scocca

Game

Con questo articolo volevo andare a spiegare in termini più semplici possibili due aspetti del rendering grafico: la risoluzione dinamica e la pipeline di rendering. Sono due argomenti distinti, ma sufficientemente corti da poter essere condensati […]

Con questo articolo volevo andare a spiegare in termini più semplici possibili due aspetti del rendering grafico: la risoluzione dinamica e la pipeline di rendering. Sono due argomenti distinti, ma sufficientemente corti da poter essere condensati […]

22 Marzo 2017

Con questo articolo volevo andare a spiegare in termini più semplici possibili due aspetti del rendering grafico: la risoluzione dinamica e la pipeline di rendering. Sono due argomenti distinti, ma sufficientemente corti da poter essere condensati e che hanno un punto di congiunzione inaspettato: The Legend of Zelda: Breath of the Wild.

Partiamo subito con il chiarire quel che riguarda la risoluzione nativa, l’upscaling e altro. Vi ricordate il processo che deve fare una scheda grafica? Bene il risultato finale è un’immagine di un determinato numero di pixel. Quanto sarà grande quest’immagine è deciso dagli sviluppatori. La risoluzione dell’immagine risultante dai calcoli fatti dalla GPU è quella che viene considerata “nativa”.

Luther-Resolution-Large
La differenza c’è ma  immagini fatte così sono tutto marketing. Certo, 480 fanno schifo davvero.

Quando l’immagine è pronta, questa viene salvata in un’apposita porzione della memoria chiamata framebuffer e viene letta dal monitor. Nel mondo digitale le immagini sono formate da un certo numero di pixel e questi sono comunemente indicati dal numero di pixel dei lati del rettangolo dell’immagine. Dando per scontato un formato di immagine 16:9 si può invece indicare solo il valore dei punti verticali: 1920×1080 o 1080p insomma. La “p” alla fine indica che l’immagine è costruita in modo progressivo, oramai il metodo preferito dalla maggior parte dei sistemi videoludici.

Per ottenere una resa di immagine perfetta si dovrebbe mappare l’informazione 1:1. Ad ogni pixel dell’immagine preparata dalla scheda grafica corrisponde un pixel del televisore. A volte questo non è possibile per questioni di performance. L’approccio per risolvere questo problema è molto semplice: si riduce la risoluzione con la quale si prepara l’immagine. Per evitare immagini quindi sgranate sul monitor, si fa passare l’immagine attraverso un’unità chiamata upscaler, che attraverso complessi algoritmi ricostruisce l’informazione mancante. Questo processo ovviamente non è perfetto e la qualità di un’immagine upscalata sarà sempre inferiore ad una nativa. Ovviamente maggiore è la differenza con la risoluzione del monitor, maggiore sarà l’informazione persa. C’è da dire inoltre che l’aspetto più importante è sempre la densità di informazione. Quando si guarda un’immagine imperfetta da una certa distanza, non ci accorgiamo degli errori. Se avete una TV grande, evitate di starci molto vicino e noterete meno le storpiature grafiche.

Blaskovitch
Upscaling perfetto!!!

Su un monitor full HD vedrete sempre un’immagine in 1080p, ma questa può essere nativa oppure upscalata. Negli ultimi anni i motori dei giochi sono diventati sempre più dinamici e difficili da costruire prevedendo ogni caso. Ricordiamo che un gioco a 30fps deve calcolare ogni immagine in 33 millisecondi. Il framerate consistente ha in generale precedenza sul resto. Così è nata una tecnica chiamata risoluzione dinamica: il motore di gioco riesce a prevedere come il numero di pixel da elaborare influenzi il tempo di calcolo e cambia in tempo reale la risoluzione per mantenere un framerate costante. Come dice il mio professore “Un dato matematicamente corretto che arriva in ritardo è comunque un dato sbagliato”.

La risoluzione dinamica può essere implementata in più modi. Può modificare uno solo dei due assi o entrambi, oppure può operare a risoluzioni impostate in precedenza fisse o ancora avere libertà totale di risoluzione. Lo svantaggio di avere un’immagine meno definita, in questo modo, è minimizzato in quanto capita solo in momenti di massimo stress, generalmente non la norma per il gioco. Inoltre nei casi di maggiore carico spesso il giocatore è ingaggiato nella dinamiche di gameplay ed ha meno tempo per ammirare lo scenario. Zelda ne fa uso per esempio e sulle macchine della concorrenza è una pratica molto diffusa.

Ora, per evitare problemi di lettura/scrittura contemporanea nel buffer, si adopera spesso un sistema chiamato a doppio buffer, così scrivo e leggo da due posti diversi. Questo può causare problemi di sincronizzazione. Per riparare a questi si forza la sincronia attraverso il V-Sync con il refresh rate del monitor. Quando però ho problemi a mantenere il framerate l’effetto combinato di questi due elementi fa scendere il framerate a sottomultipli del refresh del monitor, senza scali intermedi. Se sto giocando a 30fps ed un calo mi porterebbe a 28, il sistema scende invece a 20 per poi riprendersi. Per evitare questo problema si utilizza quindi il triplo buffering: aggiungendo un terzo elemento si evitano questi problemi, ma questa pratica ha un costo maggiore in termini di processore e memoria occupata.

IMR vs TBR
Differenza della pipeline di Rendering Immediata e Tiled, come illustrato da PowerVR

Cambiando argomento: vi ricordate i processi che compie una GPU per generare l’immagine? (Si lo chiedo ancora). Ebbene, non esiste un solo modo per farlo. La procedura spiegata nell’altro articolo è comunemente chiamata Immediate mode e viene utilizzata nella maggioranza degli elaboratori grafici ad alta potenza. Nel mondo mobile si usa però un’altra tecnica chiamata Tile Rendering.

Il tile rendering opera dividendo l’immagine in piccoli quadratini (Tile) prima di procedere ad eseguire operazioni sui pixel. Questo riduce il quantitativo di memoria necessario per le singole operazioni, in quanto non c’è bisogno di avere in memoria l’intera immagine. Inoltre lavorando su settori divisi, è possibile parallelizzare il processo. Lo svantaggio di questo approccio è che alcuni triangoli possono essere ripetuti se occupano più tiles, ma i vantaggi in termini di memoria risparmiata sono tali da far sì che ogni GPU mobile sul mercato usi questo sistema. Power VR, Mali, Adreno fanno tutte uso di questo sistema. E Nvidia. Esatto, la serie Maxwell e Pascal, oltre a schede desktop, fanno uso di questo sistema di rendering. In questo caso mi riferisco al Tile Rendering a livello hardware, perché a livello software è possibile imitare questo approccio, ma averlo hardware è ben diverso.

Tiled based rendering Bandwidth
Un esempio di differenza di banda richiesta tra il rendering tradizione e quello a caselle

Questo è interessante perché Switch monta una scheda Maxwell e può in qualche modo far luce sul comportamento della macchina. Switch sappiamo che monta solo 4GB di Ram a 25GB/s. Un passo avanti rispetto a quelle del Wii U, ma Wii U aveva 32MB di memoria veloce. Molti si sono chiesti in effetti come possa Switch offrire risoluzioni superiori a Wii U senza far uso di memoria veloce. Il trucco è proprio qui: dato che funziona in modo diverso, non ne ha bisogno. Se Wii U si basava sull’avere il suo target di rendering nei 32MB, Switch lo tiene tutto nelle cache interne della GPU.

Con questo è possibile spiegare il perché Zelda in modalità Docked ogni tanto abbia lo stesso problemi con il suo framerate. Si tratta di un gioco pensato per spingere al limite il Wii U sfruttandone i punti di forza, che purtroppo sono in antitesi con quelli di Switch. A risoluzioni più alte quindi, ci possono essere colli di bottiglia inaspettati ed aggirabili con più difficoltà, soprattutto per la volontà di mantenere parità visiva tra le versioni.

Il tile rendering risolve tutti i problemi? No, in quanto questo metodo aiuta in alcuni ambiti, ma non in altri, non rende magicamente Switch più potente, semplicemente fa un uso più efficiente delle proprie risorse rispetto alla concorrenza e per una console portatile è più importante di ogni altra cosa.