123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- <!DOCTYPE html>
- <html lang="it">
- <head>
- <meta charset="utf-8">
- <base href="../../../" />
- <script src="page.js"></script>
- <link type="text/css" rel="stylesheet" href="page.css" />
- </head>
- <body>
- <h1>Come liberare le risorse ([name])</h1>
- <p>
- Un aspetto importante per migliorare le prestazioni ed evitare perdite di memoria nella tua applicazione è l'eliminazione delle entità della libreria non utilizzate.
- Ogni volta che viene creata un'istanza di un tipo *three.js*, viene allocata una certa quantità di memoria. Tuttavia, *three.js* crea per oggetti specifici
- come le geometrie o i materiali, entità correlate WebGL, come buffer o programmi shader, necessari per il rendering. È importante sottolineare che
- questi oggetti non vengono rilasciati automaticamente. Invece, l'applicazione utilizza una speciale API per liberare tali risorse. Questa guida fornisce
- una breve panoramica su come l'API viene utilizzata e quali oggetti sono rilevanti in questo contesto.
- </p>
- <h2>Geometrie</h2>
- <p>
- Una geometria solitamente rappresenta le informazioni sui vertici come una collezione di attributi. *three.js* internamente crea un oggetto di tipo [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLBuffer WebGLBuffer]
- per ogni attributo. Queste entità vengono cancellate solo se viene chiamato il metodo [page:BufferGeometry.dispose](). Se una geometria, nella tua applicazione,
- diventa obsoleta, esegui questo metodo per liberare tutte le risorse correlate.
- </p>
- <h2>Materiali</h2>
- <p>
- Un materiale definisce come sono visualizzati gli oggetti. *three.js* utilizza le informazioni di una definizione di materiale per costruire un programma shader per il rendering.
- I programmi shader possono essere cancellati solo se il respettivo materiale è eliminato. Per ragioni di prestazioni, *three.js* prova, se possibile, a riutilizzare
- il programma shader già esiste. Quindi un progamma di shader può essere cancellato solo se tutti i relativi materiali sono eliminati. Puoi eseguire l'eliminazione
- di un materiale eseguendo il metodo [page:Material.dispose]().
- </p>
- <h2>Texture</h2>
- <p>
- L'eliminazione di un materiale non ha effetti sulle texture. Queste vengono gestite separatamente, poiché una singola texture può essere usata da più materiali contemporaneamente.
- Ogni volta che crei un'istanza di [page:Texture], three.js internamente crea un'istanza di [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLTexture WebGLTexture].
- Come per i buffer, questo oggetto può essere eliminato solo chiamando il metodo[page:Texture.dispose]().
- </p>
- <p>
- Se stai usando `ImageBitmap` come origine dati della texture, devi chiamare il metodo [link:https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap/close ImageBitmap.close]() a livello applicativo per liberare le risorse lato CPU.
- Una chiamata automatica di `ImageBitmap.close()`in [page:Texture.dispose]() non è possibile, poiché il bitmap dell'immagine diventa inutilizzabile, e l'engine non ha modo di sapere se il bitmap dell'immagine è utilizzata da altre parti.
- </p>
- <h2>Render Target</h2>
- <p>
- Oggetti di tipo [page:WebGLRenderTarget] non allocano solo un'istanza di [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLTexture WebGLTexture] ma anche
- di [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLFramebuffer WebGLFramebuffer] e di [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderbuffer WebGLRenderbuffer]
- per realizzare destinazioni di rendering personalizzate. Questi oggetti vengono solo deallocati eseguendo il metodo [page:WebGLRenderTarget.dispose]().
- </p>
- <h2>Varie</h2>
- <p>
- Ci sono altre classi nella cartella degli esempi come i control o passaggi di post-processing che forniscono metodi `dispose()` per rimuovere i listener di eventi interni o
- renderizzare i target. In generale, viene raccomandato di controllare le API o la documentazione della classe e controllare il metodo `dispose()`. Se presente dovresti utilizzarlo per liberare le risorse.
- </p>
- <h2>FAQ</h2>
- <h3>Perché *three.js* non può eliminare gli oggetti automaticamente?</h3>
- <p>
- Questa domanda è stata fatta spesso dalla community, quindi è importante chiarire la questione. Il fatto è che *three.js* non conosce il ciclo di vita o lo scopo
- delle entità create dall'utente come le geometrie o i materiali, questa è una responsabilità dell'applicazione. Per esempio, anche se un materiale non è momentamenente utilizzato per il
- rendering, potrebbe essere necessario per il prossimo frame. Quindi se l'applicazione decide che un determianto oggetto può essere cancellato lo notifica all'engine tramite la chiamata
- al rispettivo metodo `dispose()`.
- </p>
- <h3>La rimozione di una mesh dalla scena elimina anche la sua geometria e il suo materiale?</h3>
- <p>
- No, devi eliminare esplicitamente la geometria e il materiale chiamando il metodo *dispose()*. Tieni a mente che le geometrie e i materiali possono essere condivisi tra oggetti 3D come le mesh.
- </p>
- <h3>*three.js* fornisce informazioni sulla quantità di oggetti memorizzati nella cache?</h3>
-
- <p>
- Si, è possibile consultare [page:WebGLRenderer.info]. Una proprietà speciale del renderer con una serie di informazioni statistiche sulla memoria della scheda grafica
- e il processo di rendering. Tra le altre cose, riporta anche quante texture, geometrie e programmi shader sono internamente memorizzati. Se noti che ci sono problemi
- di performance nell'applicazione, è una buona idea debuggare questa proprietà per identificare facilmente se c'è una perdita di memoria.
- </p>
- <h3>Che cosa succede quando il metodo `dispose()` viene chiamato su una texture ma l'immagine non è ancora stata caricata?</h3>
- <p>
- Le risorse interne di una texture vengono allocate solo se l'immagine è caricata con successo. Se elimini una texture prima che l'immagine venga caricata
- non succede niente. Nessuna risorsa è stata allocata, quindi niente deve essere pulito.
- </p>
- <h3>Cosa succede quando chiamo `dispose()` e poi utilizzo il rispettivo oggetto in un secondo momento?</h3>
- <p>
- Le risorse interne che sono state cancellate saranno ricreate dall'engine, in questo modo non ci saranno errori a runtime. Probabilmente, però, noterai un impatto negativo sulle performance nel
- frame corrente quando il programma shader sarà compilato.
- </p>
- <h3>Come devo gestire gli oggetti *three.js* nella mia app? Quando so che devo eliminare le risorse?</h3>
- <p>
- In generale non c'è una raccomandazione definitiva per questo. Dipende molto dal caso d'uso specifico. È importante sottolineare che non è sempre necessario
- eliminare oggetti tutto il tempo. Un buon esempio esemplificativo è un gioco a più livelli. Un buon momento per eliminare gli oggetti è quando viene cambiato il livello.
- L'applicazione può attraversare tutta la vecchia scena (livello) ed eliminare tutti i vecchi materiali, geometrie e texture. Come accennato nella sezione precedente,
- se viene cancellato un oggetto che è attualmente in uso non produce un errore a runtime. La cosa peggiore che può accadere è un calo delle prestazioni in un singolo frame.
- </p>
- <h2>Esempi che mostarno l'uso del metodo dispose()</h2>
- <p>
- [example:webgl_test_memory WebGL / test / memory]<br />
- [example:webgl_test_memory2 WebGL / test / memory2]<br />
- </p>
- </body>
- </html>
|