You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
124 lines
7.3 KiB
124 lines
7.3 KiB
<!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>
|
|
|