Tempo. Mesi. Forse anni. Hai trascorso il tuo tempo (un sacco di tempo) per creare il tuo gioco. Piccolo o grande, non importa. È il tuo gioco, e ora lo vuoi condividere con tutto il mondo e forse diventare famoso e ricco *. È perfetto: l'arte è buona e tu sei molto orgoglioso della tua idea all'interno del gioco. Il tuo gioco.
Ma c'è un ultimo problema che tu dovere risolvere prima del rilascio. No, non è un problema semplice. Il problema: il frame rate del tuo gioco è basso. Molto basso. E questo significa solo una cosa: devi trovare un modo per risolverlo. Devi. E tu non hai idea di come.
Non farti prendere dal panico: c'è un semplice trucco che può aiutarti. Si chiama "Texture Atlas".
* Se diventi ricco grazie a questo articolo, ricordati di me. Grazie mille!
Se ti stai avvicinando allo sviluppo di un videogioco 3D per la prima volta, inizierai a scoprire che la grafica 3D è composta da diverse parti: mesh 3D, trame, sistemi particellari e molti altri elementi che vengono solitamente disegnati sullo schermo 30 volte al secondo (in gergo: 30 fps) durante il processo di rendering, rendendo il mondo del gioco vario e vivace.
Che ci crediate o no, i primi videogiochi 3D che ho visto nella mia vita non avevano nessuno di questi elementi. Erano composti solo da linee che formavano oggetti o elementi in wireframe 3D.
Scrivere questo mi fa sicuramente sentire vecchio.
Tornando a noi (anzi, a voi) e alle cose importanti, oggi parleremo delle trame dell'interfaccia utente (UI in seguito) e, per estensione, di tutte le trame del gioco.
In un gioco 3D, l'interfaccia utente di solito è composta da elementi 3D (come aerei o scatole) con trame.
Abbiamo menzionato prima del processo di rendering: è l'operazione con cui gli elementi in memoria vengono disegnati fisicamente sullo schermo. È uno dei processi più complessi e costosi che si verificano in un gioco 3D in tempo reale. Quindi, qualsiasi espediente per ridurre il tempo impiegato da questo processo è benvenuto; meno tempo speso nella fase di rendering significa un frame rate più alto (cioè se raggiungi i 60 fps puoi renderizzare l'immagine due volte e poi pensare di sviluppare il tuo gioco anche per VR), o più elementi dello schermo (e poi un gioco più ricco, più animato, più bello).
Uno dei mezzi usati per ridurre la durata del processo di rendering è un Atlas Texture: non è altro che un'immagine che contiene molte trame.
Nota: come menzionato nel paragrafo precedente, questo articolo discuterà l'Atlante delle texture applicato all'interfaccia utente. Tuttavia, molti dei concetti illustrati qui possono essere applicati anche ai modelli 3D e alle loro trame.
Un Atlas Texture, abbiamo detto, è una raccolta di trame all'interno di una singola immagine.
Un Atlante è solitamente associato a un descrittore di file, che indica al gioco dove si trova una trama (in certe coordinate xey), per recuperarla.
A seconda del sistema che utilizzerai per generare e gestire l'Atlante, avrai più o meno opzioni, come la distanza tra le immagini che lo compongono (riducendo il rischio di artefatti sui bordi della trama, causato da una sovrapposizione di due elementi), o la possibilità di ruotare gli elementi per ottimizzare lo spazio all'interno dell'Atlante (spazio più ottimizzato significa più immagini all'interno dello stesso Atlante).
Esistono diversi modi per creare un Atlante. Un ambiente di sviluppo completo di solito consente la gestione interna dell'Atlante; ci sono anche molti strumenti esterni che offrono molte opzioni aggiuntive.
La scelta del sistema da utilizzare dipende ovviamente dalle preferenze personali. Qui ne spieghiamo due: Sprite Packer, interno a Unity e TexturePacker (uno strumento standalone, a pagamento).
Per aprire Sprite Packer, scegliere dal menu Finestra> Sprite Packer.
La gestione è davvero semplice: il pulsante Pack è usato per creare uno o più Atlanti (dipende dal numero delle tue immagini e dalla dimensione dell'Atlante che vuoi usare).
Ora puoi selezionare un'immagine per vedere dove si trova nell'Atlante. Se si aggiungono o rimuovono immagini dal progetto, è necessario utilizzare il pulsante Repack per aggiornare l'atlante.
Per configurare Sprite Packer, puoi scegliere dal menu Modifica> Impostazioni progetto> Editor; qui puoi disattivare l'Atlante, attivarlo solo per il gioco creato o accenderlo sempre.
Per ulteriori informazioni su Sprite Packer, puoi consultare la guida ufficiale.
Texture Packer è uno strumento autonomo utilizzato per gestire Atlas.
Puoi aggiungere una o più cartelle dal tuo progetto e Texture Packer creerà l'Atlante.
Successivamente, è possibile scegliere il formato dei dati per l'esportazione. Come puoi vedere, c'è anche l'opzione "JSON per Unity". Ciò significa che puoi esportare il tuo Atlas per il tuo progetto Unity. Tuttavia, per poterli utilizzare insieme, è necessario installare un'estensione editor gratuita dall'archivio risorse.
Per ulteriori informazioni su Texture Packer, puoi consultare la guida ufficiale.
Ma perché è così importante raccogliere più immagini in una singola più grande?
Torniamo per un momento al processo di rendering: se ogni elemento dell'interfaccia utente ha una trama separata, viene disegnato con una "chiamata di estrazione" separata. Questo significa che se nella nostra interfaccia abbiamo l'icona dei cuori (che rappresenta l'energia del giocatore) e l'icona delle monete raccolte, avremo due chiamate d'estrazione.
Ogni chiamata di disegno richiede un po 'di tempo per essere completata, rendendo il processo di rendering più lungo e più lungo. Se ci sono cinque elementi dell'interfaccia utente, invece di due come nell'esempio sopra, ci sono cinque chiamate di estrazione.
Cominci a vedere il punto?
Altre chiamate di disegno -> più tempo durante la fase di rendering -> meno fps -> gioco con una bassa frequenza di fotogrammi (con alcune cadute di fotogramma) o meno elementi sullo schermo (quindi visivamente poveri).
Sprecare chiamate in questo modo, a meno che non ci siano ragioni particolari, non ha davvero senso, specialmente per l'interfaccia utente.
In effetti, tutte le trame di un Atlante verranno renderizzate insieme, in un unico passaggio.
In conclusione, specialmente se stai sviluppando un gioco su una piattaforma in cui le prestazioni sono davvero importanti (come una piattaforma mobile):
E ... che la forza sia con te. E il tuo codice. Sempre.