Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Baking e lightmaps

Velocizzare il rendering del gioco generando ombre e luci già pronte per gli oggetti statici sulle scene e creando insiemi di illuminazione in tempo reale
Velocizzare il rendering del gioco generando ombre e luci già pronte per gli oggetti statici sulle scene e creando insiemi di illuminazione in tempo reale
Link copiato negli appunti

Una lightmap, come dice il nome, è una texture map che contiene i valori della luce e delle ombre proiettate sugli oggetti della scena. Le lightmap si sommano alle texture diffuse moltiplicandone i valori RGB, e definendo il colore finale dell'oggetto. Di fatto, le lightmap sono spesso in bianco e nero - a meno che non ci siano luci colorate in scena o oggetti colorati che riflettono la luce.

In Unity le lightmap vengono create con un software incluso nell'engine stesso, di nome Beast. Quando vogliamo renderizzare le luci e le ombre sulle lightmap, possiamo lanciare un'operazione chiamata bake (ovvero "cuocere al forno") dal pannello Lightmap (si può aprirlo partendo da Window > Lightmapping nel menu in alto). A questo punto Beast raccoglie tutte le informazioni sulla scena, sulle geometrie e sulle luci, e fa i suoi calcoli, producendo infine le lightmap che verranno automaticamente importate nel progetto ed assegnate agli oggetti.

Una cosa da ricordare è che il baking è viene effettuato in fase di creazione del gioco e non in tempo reale durante il gameplay, quindi è utile solo per quegli oggetti che non si muovono durante il gioco, come strade, edifici, sfondi, lampioni, ecc.

Prima di fare un baking, la scena necessita di essere preparata. Per prima cosa, tutti gli oggetti che devono avere una lightmap vanno segnati come Static, spuntando la casellina in alto a destra nell'Inspector. L'oggetto non deve necessariamente essere statico in tutti i sensi, basta che sia Lightmap Static:

Questo perché - ad esempio - potremmo avere una 'nave volante' (come in Super Mario Bros 3!) per la quale di fatto vogliamo creare le lightmap, ma che si muove nel cielo. Non deve quindi essere Batching Static, altrimenti verrà unita alle altre geometrie ai fini dell'ottimizzazione e non si potrà muovere.

Inoltre, gli oggetti da lightmappare devono avere un set di coordinate UV per la lightmap (che molto spesso non coincide con le UV delle texture diffuse o normal). Se l'oggetto è un .fbx, .obj, ecc. importato, nelle proprietà di importazione basterà spuntare Generate Lightmap UVs, e Unity le creerà per voi (sostituendole a qualunque set UV2 che trovi).

A questo punto, basterà mettere una luce in scena e possiamo iniziare il bake. Se si vogliono le ombre, basta abilitarle dall'Inspector avendo selezionato la luce. Se attive però, non vengono più regolate nell'Inspector come abbiamo visto nella lezione precedente (quelli sono i valori delle ombre realtime), ma direttamente nel pannellino Lightmapping.

Il baking

Attenzione: il Lightmapping è una di quelle feature che differisce un po' fra la versione gratuita di Unity e quella Pro. In questa lezione andremo fino in fondo, facendo riferimento alla versione Pro ai fini didattici. I concetti ed i consigli valgono in ogni caso anche per la versione gratuita.

Per cominciare un bake, apriamo il pannellino Lightmapping (Window > Lightmapping nel menu in alto). Questi si divide in 3 sotto pannelli: Object, in cui si possono regolare i parametri dei singoli oggetti coinvolti nel bake; Bake, dove possiamo regolare la qualità del bake e lanciare l'operazione vera e propria; e Maps, in cui possiamo ispezionare le texture map prodotte.

Il pannello Bake si presenta così:

Il primo valore Mode si riferisce al tipo di lightmapping che applichiamo, in questo caso Single. Esistono anche Dual, e Directional, ne parleremo a breve.

  • Quality indica la qualità del risultato: è importante ricordare che trovare i parametri giusti per il lightmapping può essere lungo e complesso, quindi è meglio tenere la Quality su Low in un primo momento mentre si fanno prove, e poi usare High per produrre le lightmap definitive.
  • Bounces indica il numero di rimbalzi che la luce può fare sugli oggetti, creando la cosiddetta Global Illumination (ovvero un illuminazione che non arriva solo dalla fonte di luce, ma anche dagli oggetti vicini… un'illuminazione globale). Nella realtà, sarebbero infiniti (finché non 'muore'), ma ai nostri fini dovremmo definire un numero da 0 a 4. Più rimbalzi più le lightmap saranno di qualità, ma più tempo ci vorrà per calcolarle. I Bounces sono una feature di Unity Pro.

    Quando il pannellino Lightmapping è aperto, nella Scene View compare un pannello fluttuante in basso a destra:

    Qui si trovano alcune opzioni minori, che in generale non influenzano il bake ma solo la visualizzazione delle Lightmap in fase di lavoro. Con Use Lightmaps ad esempio, possiamo disabilitare temporaneamente le mappe per poter vedere la scena con un'illuminazione dinamica, senza effettivamente rimuoverle.

    Esempi di lightmaps

    Creiamo una scena di prova per fare dei test. Creiamo due cubi colorati ed un piano bianco, e mettiamo una luce Directional bianca con un valore di 0.5 di Intensity ed attiviamo le ombre (non importa di che tipo). Prima di fare il bake, avendo solo le luci dinamiche otterremo un risultato simile:

    Come è possibile notare, la luce illumina i cubi e proietta un'ombra, ma sul piano bianco non c'è traccia di riflessi di luce, ogni lato dei cubi è di un colore netto senza sbavature, il tutto è molto asettico e finto.

    Se attiviamo Show Resolution nel pannellino grigio nella Scene View, la scena sarà coperta da una scacchiera: questa indica qual è la risoluzione della Lightmap una volta applicata al modello. Una trama più fitta vuol dire più ricchezza di dettagli, ma anche che verranno usate più lightmap per coprire tutta la scena. A seconda dei settaggi, alcuni modelli potrebbero avere caselle più grandi o più piccole di altri.

    Per variare la dimensione di questa scacchiera, bisogna utilizzare il valore di Resolution che si trova come penultima opzione nel sotto-pannello Bake all'interno dell'Inspector. In questo caso, l'abbiamo impostato su 30 texels per world unit (ovvero, un cubo grande 1 unità userà 30x30 pixel per lato sulla texture della Lightmap):

    Non c'è bisogno che la risoluzione della lightmap sia altissima, ma come sempre dipende dal tipo di gioco. Per giochi in cui il terreno è visto da un punto di vista alto, anche valori come 10 o 5 potrebbero andare bene. Per altri generi (soprattutto FPS al chiuso) saranno necessari anche 20, 30 o anche 50 texel per un risultato dignitoso.

    Disattiviamo Show Resolution, e lanciamo finalmente un bake premendo sul bottone Bake Scene. Se gli oggetti non sono impostati correttamente (non statici), Unity tirerà fuori un errore in console. Altrimenti, partirà correttamente il bake, con una barra di caricamento in basso a destra:

    Fintanto che la barra carica, possiamo anche continuare a lavorare sulla scena, ma non possiamo salvare né mettere in Play il gioco. Una volta finito il bake, Unity importerà le lightmaps nel progetto in un formato .exr, in una cartella che ha lo stesso nome della scena per cui sono state create (perciò la scena va salvata prima!). Cancellando la cartella (o premendo il tasto Clear) le lightmap vengono rimosse e la scena torna ad un'illuminazione dinamica. Se vogliamo vedere la scena con illuminazione dinamica solo temporaneamente, come detto, possiamo usare l'opzione Use Lightmaps nel pannellino nella Scene View per spegnere e riaccendere le lightmap.

    Il risultato del primo bake in modalità Single Lightmaps:

    Il risultato non è male, più interessante dell'illuminazione realtime, sebbene le ombre abbiano un bordo seghettato (è colpa del settaggio Low su Quality). Questo bake ha richiesto 11 secondi.

    Aumentiamo la Ambient Occlusion da 0 a 0.7. La tecnica dell'Ambient Occlusion non tiene in conto le luci in scena, ma quanto una superficie è “nascosta” dagli altri oggetti, e permette di avere parti più scure negli anfratti e dove gli oggetti sono molto ravvicinati:

    Attivando l'Ambient Occlusion, i tempi di rendering salgono a 17 secondi ma otteniamo un interessante effetto alla base dei cubi.

    Le ombre sono ancora molto nere, quindi attiviamo i Bounces. Questo ci dà accesso anche alla Skylight, ovvero una luce globale che viene “dal cielo”, e che di default impostiamo su un azzurrino a 0.3 di Intensity. Questo ci permetterà di creare un effetto da esterno, schiarendo tutte le ombre. Con 1 bounce, i tempi di rendering vanno a 24 secondi:

    2 Bounces, 22 secondi:

    4 Bounce, 23 secondi:

    Si può notare che fra 2 e 4 bounce non ci sono molte differenze, né di qualità né di tempo. Questo probabilmente perché essendo la scena vuota, i raggi rimbalzano via prima di effettuare 4 rimbalzi.

    Essendo contenti del risultato, possiamo attivare la High Quality:

    I tempi di rendering salgono a 32 secondi, ma il risultato è molto migliore.

    Altre modalità: Directional Lightmaps e Dual Lightmaps

    Single Lightmaps non è l'unica modalità con cui si può fare il bake. Selezionando Directional Lightmaps in Mode, Unity produrrà due set di lightmaps (quindi il numero di texture verrà duplicato, tenetene conto!).

    Il primo set assomiglierà molto a quello prodotto sin'ora, ovvero con le informazioni di intensità della luce. Nel secondo set, Unity incorporerà le informazioni sulla direzione da cui proviene la luce. Così facendo, è possibile avere materiali con specular o normal maps. In aggiunta, Unity starà attento a non calcolare la seconda Lightmap per gli oggetti che non hanno bisogno di specular o normal maps (quindi attenti ai materiali, o meglio agli shader, che utilizzate!).

    Come contro, c'è che bisogna gestire un secondo set di immagini (quindi serve più ram per queste texture, che spesso sono grandi) e che i render durano di più, e inoltre a volte la compressione di queste texture fa sì che sgranino, producento risultati non ottimali. Se però usate i rimbalzi di luce, il gioco potrebbe valere la candela. Vediamo un render con le Directional Lightmaps:

    Qui i tempi di rendering sono saliti a 52 secondi. Un bell'aumento dai 32 che avevamo con le Single!

    In ultimo, le Dual Lightmaps. Come dice il nome, Unity crea due set di lightmap, uno “lontano” ed uno “vicino”. Per decidere a che distanza usare uno e a che distanza l'altro, possiamo regolare il valore di Shadow Distance nel box nella Scene View.

    Questi due set hanno diverse funzioni: nel set lontano, Unity immagazzina le informazioni di luce ed ombre in maniera liscia (ovvero non ne sa la direzione, esattamente come per le Single Lightmaps), che impedisce di avere riflessi, normal e specular. Questo set viene usato per gli oggetti lontani, che non ricevono ombre dinamiche.

    Nel set vicino, Unity immagazzina le informazioni complete sulla luce (come per le lightmap lontane), ma solo per le luci che sono impostate come Baked Only nella proprietà Ligthmapping (in basso nell'Inspector). Per quelle impostate come Auto, immagazzina solo la luce indiretta (rimbalzi), ma lascia che siano le luci realtime a definire ombre, specular e normal.

    Detto in altri termini, quando una luce è entro la distanza di Shadow Distance, Unity la tratta come fosse realtime, usando le ombre realtime, e calcolando i riflessi e le normal ogni frame. A questi aggiunge le lightmap vicine, per avere colori sfumati e i rimbalzi di luce. Appena esce dal campo d'azione, Unity la rende baked, usando la lightmap lontana anche per le ombre, e disattivando normal e specular (perché questa lightmap, al contrario del caso delle Directional Lightmaps, non contiene informazioni su da dove provenga la luce).

    In questo modo si possono avere delle buone luci ed ombre, e da vicino avere personaggi (magari fermi sul posto, ma con un ciclo animato di idle) o bandiere con ombre dinamiche, con normal maps e specular.

    Ad esempio, attivando le Dual Lightmaps avremo questo risultato:

    Come si può vedere, le ombre dei cubi sono peggio di prima (perché sono realtime), ma abbiamo il vantaggio che se li alziamo da terra l'ombra si muove con loro. Ciononostante, sui bordi in basso dei cubi possiamo vedere un accenno di global illumination che li rende più interessanti dell'esempio completamente realtime che abbiamo fatto ad inizio lezione.

    Le Dual Lightmaps in Unity funzionano solo con il rendering deferred. Per farle funzionare nel forward, bisogna scrivere degli shader appositi e spuntare la casellina Use Dual Lightmaps in Forward Rendering nel pannello Lightmapping.

    A prescinedere dalla tecnica usata, il lightmapping permette di avere risultati molto belli se le luci sono usate con sapienza. Inoltre, permette di avere luci ed ombre multiple dove non potremmo averle (ovvero nel forward rendering), ed avere ombre anche per luci Point e Spot (non possibili in realtime). Un esempio banale con qualche altra luce colorata:

    Nella prossima lezione vedremo altre informazioni sul lightmapping, e sulla soluzione per far funzionare la Global Illumination con oggetti in movimento: le Light Probe.

    Ti consigliamo anche