W3Cschool
恭喜您成為首批注冊(cè)用戶(hù)
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
為了提高性能,并避免應(yīng)用程序中的內(nèi)存泄露,一個(gè)重要的方面是廢置未使用的類(lèi)庫(kù)實(shí)體。 每當(dāng)你創(chuàng)建一個(gè)three.js中的實(shí)例時(shí),都會(huì)分配一定數(shù)量的內(nèi)存。然而,three.js會(huì)創(chuàng)建在渲染中所必需的特定對(duì)象, 例如幾何體或材質(zhì),以及與WebGL相關(guān)的實(shí)體,例如buffers或著色器程序。 非常值得注意的是,這些對(duì)象并不會(huì)被自動(dòng)釋放;相反,應(yīng)用程序必須使用特殊的API來(lái)釋放這些資源。 本指南簡(jiǎn)要概述了這一API是如何使用的,以及哪些對(duì)象是和這一環(huán)境相關(guān)的。
幾何體常用來(lái)表示定義為屬性集合的頂點(diǎn)信息,three.js在內(nèi)部為每一個(gè)屬性創(chuàng)建一個(gè)WebGLBuffer類(lèi)型的對(duì)象。 這些實(shí)體僅有在調(diào)用BufferGeometry.dispose()的時(shí)候才會(huì)被刪除。 如果應(yīng)用程序中的幾何體已廢棄,請(qǐng)執(zhí)行該方法以釋放所有相關(guān)資源。
材質(zhì)定義了物體將如何被渲染。three.js使用材質(zhì)所定義的信息來(lái)構(gòu)造一個(gè)著色器程序,以用于渲染。 著色器程序只有在相應(yīng)材質(zhì)被廢置后才能被刪除。由于性能的原因,three.js盡可能?chē)L試復(fù)用已存在的著色器程序。 因此,著色器程序只有在所有相關(guān)材質(zhì)被廢置后才被刪除。 你可以通過(guò)執(zhí)行Material.dispose()方法來(lái)廢置材質(zhì)。
對(duì)材質(zhì)的廢置不會(huì)對(duì)紋理造成影響。它們是分離的,因此一個(gè)紋理可以同時(shí)被多個(gè)材質(zhì)所使用。 每當(dāng)你創(chuàng)建一個(gè)Texture實(shí)例的時(shí)候,three.js在內(nèi)部會(huì)創(chuàng)建一個(gè)WebGLTexture實(shí)例。 和buffer相似,該對(duì)象只能通過(guò)調(diào)用Texture.dispose()來(lái)刪除。
如果您使用 ImageBitmap 作為紋理的數(shù)據(jù)源,則必須在應(yīng)用程序級(jí)別調(diào)用 ImageBitmap.close() 以處理所有 CPU 端資源。在 Texture.dispose() 中自動(dòng)調(diào)用 ImageBitmap.close() 是不可能的,因?yàn)閳D像位圖變得不可用,并且引擎無(wú)法知道圖像位圖是否在別處使用。
WebGLRenderTarget類(lèi)型的對(duì)象不僅分配了WebGLTexture的實(shí)例, 還分配了WebGLFramebuffer和WebGLRenderbuffer來(lái)實(shí)現(xiàn)自定義渲染目標(biāo)。 這些對(duì)象僅能通過(guò)執(zhí)行WebGLRenderTarget.dispose()來(lái)解除分配。
有一些來(lái)自examples目錄的類(lèi),例如控制器或者后期處理過(guò)程,提供了dispose()方法以用于移除內(nèi)部事件監(jiān)聽(tīng)器或渲染目標(biāo)。 通常來(lái)講,非常建議查閱類(lèi)的API或者文檔,并注意dispose()函數(shù)。如果該函數(shù)存在的話,你應(yīng)當(dāng)在清理時(shí)使用它。
這一問(wèn)題在社區(qū)中多次被問(wèn)到,因此澄清這件事情是十分有必要的。事實(shí)是,three.js并不知道用戶(hù)所創(chuàng)建的實(shí)體(例如幾何體或者材質(zhì))的生命周期或作用范圍,這些是應(yīng)用程序的責(zé)任。 比如說(shuō),即使一個(gè)材質(zhì)當(dāng)前沒(méi)有被用于渲染,但它也可能是下一幀所必需的。 因此,如果應(yīng)用程序決定某個(gè)對(duì)象可以被刪除,則它必須通過(guò)調(diào)用對(duì)應(yīng)的dispose()方法來(lái)通知引擎。
并不會(huì),你必須通過(guò)dispose()來(lái)明確地廢置geometry(幾何體)或material(材質(zhì))。 請(qǐng)記住,geometry(幾何體)或material(材質(zhì))可以在3D物體之間(例如mesh(網(wǎng)格))被共享。
是的,可以評(píng)估WebGLRenderer.info —— 渲染器中的一個(gè)特殊屬性,具有一系列關(guān)于顯存和渲染過(guò)程的統(tǒng)計(jì)信息。 除此之外,它還告訴你有多少紋理、幾何體和著色器程序在內(nèi)部存儲(chǔ)。 如果你在你的應(yīng)用程序中注意到了性能問(wèn)題,一個(gè)較好的方法便是調(diào)試該屬性,以便輕松識(shí)別內(nèi)存泄漏。
對(duì)于紋理的內(nèi)部資源僅在圖像完全被加載后才會(huì)分配。如果你在圖像被加載之前廢置紋理,什么都不會(huì)發(fā)生。 沒(méi)有資源被分配,因此也沒(méi)有必要進(jìn)行清理。
被刪除掉的內(nèi)部資源會(huì)被引擎重新創(chuàng)建,因此不會(huì)有運(yùn)行時(shí)錯(cuò)誤發(fā)生,但你可能會(huì)注意到這會(huì)對(duì)當(dāng)前幀的性能有一些影響,特別是當(dāng)著色器程序被編譯的時(shí)候。
一般來(lái)說(shuō),對(duì)此并沒(méi)有明確的建議。調(diào)用dispose()什么時(shí)候合適,很大程度上取決于具體的用例。 必須指出的是,沒(méi)有必要總是廢置對(duì)象。一個(gè)較好的例子便是一個(gè)由多個(gè)關(guān)卡所組成的游戲。使用到對(duì)象廢置的地方就是當(dāng)切換關(guān)卡的時(shí)候。 應(yīng)用程序可以通過(guò)較老的場(chǎng)景,并廢置所有過(guò)時(shí)的材質(zhì)、幾何體和紋理貼圖。 正如在前面的章節(jié)中所提到,如果你廢置一個(gè)仍然在使用的對(duì)象,并不會(huì)導(dǎo)致運(yùn)行時(shí)錯(cuò)誤??赡馨l(fā)生的最糟糕的事情便是單幀的性能會(huì)下降。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: