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.
		
		
		
		
			
				
					125 lines
				
				6.6 KiB
			
		
		
			
		
	
	
					125 lines
				
				6.6 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								<!DOCTYPE html>
							 | 
						||
| 
								 | 
							
								<html lang="en">
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<head>
							 | 
						||
| 
								 | 
							
									<meta charset="utf-8">
							 | 
						||
| 
								 | 
							
									<base href="../../../" />
							 | 
						||
| 
								 | 
							
									<script src="page.js"></script>
							 | 
						||
| 
								 | 
							
									<link type="text/css" rel="stylesheet" href="page.css" />
							 | 
						||
| 
								 | 
							
								</head>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<body>
							 | 
						||
| 
								 | 
							
									<h1>[name]</h1>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									<p>
							 | 
						||
| 
								 | 
							
										One important aspect in order to improve performance and avoid memory leaks in your application is the disposal of unused library entities.
							 | 
						||
| 
								 | 
							
										Whenever you create an instance of a *three.js* type, you allocate a certain amount of memory. However, *three.js* creates for specific objects
							 | 
						||
| 
								 | 
							
										like geometries or materials WebGL related entities like buffers or shader programs which are necessary for rendering. It's important to
							 | 
						||
| 
								 | 
							
										highlight that these objects are not released automatically. Instead, the application has to use a special API in order to free such resources.
							 | 
						||
| 
								 | 
							
										This guide provides a brief overview about how this API is used and what objects are relevant in this context.
							 | 
						||
| 
								 | 
							
									</p>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									<h2>Geometries</h2>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									<p>
							 | 
						||
| 
								 | 
							
										A geometry usually represents vertex information defined as a collection of attributes. *three.js* internally creates an object of type [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLBuffer WebGLBuffer]
							 | 
						||
| 
								 | 
							
										for each attribute. These entities are only deleted if you call [page:BufferGeometry.dispose](). If a geometry becomes obsolete in your application,
							 | 
						||
| 
								 | 
							
										execute the method to free all related resources.
							 | 
						||
| 
								 | 
							
									</p>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									<h2>Materials</h2>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									<p>
							 | 
						||
| 
								 | 
							
										A material defines how objects are rendered. *three.js* uses the information of a material definition in order to construct a shader program for rendering.
							 | 
						||
| 
								 | 
							
										Shader programs can only be deleted if the respective material is disposed. For performance reasons, *three.js* tries to reuse existing
							 | 
						||
| 
								 | 
							
										shader programs if possible. So a shader program is only deleted if all related materials are disposed. You can indicate the disposal of a material by
							 | 
						||
| 
								 | 
							
										executing [page:Material.dispose]().
							 | 
						||
| 
								 | 
							
									</p>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									<h2>Textures</h2>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									<p>
							 | 
						||
| 
								 | 
							
										The disposal of a material has no effect on textures. They are handled separately since a single texture can be used by multiple materials at the same time.
							 | 
						||
| 
								 | 
							
										Whenever you create an instance of [page:Texture], three.js internally creates an instance of [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLTexture WebGLTexture].
							 | 
						||
| 
								 | 
							
										Similar to buffers, this object can only be deleted by calling [page:Texture.dispose]().
							 | 
						||
| 
								 | 
							
									</p>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									<p>
							 | 
						||
| 
								 | 
							
										If you use an `ImageBitmap` as the texture's data source, you have to call [link:https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap/close ImageBitmap.close]() at the application level to dispose of all CPU-side resources.
							 | 
						||
| 
								 | 
							
										An automated call of `ImageBitmap.close()` in [page:Texture.dispose]() is not possible, since the image bitmap becomes unusable, and the engine has no way of knowing if the image bitmap is used elsewhere.
							 | 
						||
| 
								 | 
							
									</p>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									<h2>Render Targets</h2>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									<p>
							 | 
						||
| 
								 | 
							
										Objects of type [page:WebGLRenderTarget] not only allocate an instance of [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLTexture WebGLTexture] but also
							 | 
						||
| 
								 | 
							
										[link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLFramebuffer WebGLFramebuffer]s and [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderbuffer WebGLRenderbuffer]s
							 | 
						||
| 
								 | 
							
										for realizing custom rendering destinations. These objects are only deallocated by executing [page:WebGLRenderTarget.dispose]().
							 | 
						||
| 
								 | 
							
									</p>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									<h2>Miscellaneous</h2>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									<p>
							 | 
						||
| 
								 | 
							
										There are other classes from the examples directory like controls or post processing passes which provide `dispose()` methods in order to remove internal event listeners
							 | 
						||
| 
								 | 
							
										or render targets. In general, it's recommended to check the API or documentation of a class and watch for `dispose()`. If present, you should use it when cleaning things up.
							 | 
						||
| 
								 | 
							
									</p>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									<h2>FAQ</h2>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									<h3>Why can't *three.js* dispose objects automatically?</h3>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									<p>
							 | 
						||
| 
								 | 
							
										This question was asked many times by the community so it's important to clarify this matter. Fact is that *three.js* does not know the lifetime or scope
							 | 
						||
| 
								 | 
							
										of user-created entities like geometries or materials. This is the responsibility of the application. For example even if a material is currently not used for rendering,
							 | 
						||
| 
								 | 
							
										it might be necessary for the next frame. So if the application decides that a certain object can be deleted, it has to	notify the engine via calling the respective
							 | 
						||
| 
								 | 
							
										`dispose()` method.
							 | 
						||
| 
								 | 
							
									</p>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									<h3>Does removing a mesh from the scene also dispose its geometry and material?</h3>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									<p>
							 | 
						||
| 
								 | 
							
										No, you have to explicitly dispose the geometry and material via *dispose()*. Keep in mind that geometries and materials can be shared among 3D objects like meshes.
							 | 
						||
| 
								 | 
							
									</p>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									<h3>Does *three.js* provide information about the amount of cached objects?</h3>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									<p>
							 | 
						||
| 
								 | 
							
										Yes. It's possible to evaluate [page:WebGLRenderer.info], a special property of the renderer with a series of statistical information about the graphics board memory
							 | 
						||
| 
								 | 
							
										and the rendering process. Among other things, it tells you how many textures, geometries and shader programs are internally stored. If you notice performance problems
							 | 
						||
| 
								 | 
							
										in your application, it's a good idea to debug this property in order to easily identify a memory leak.
							 | 
						||
| 
								 | 
							
									</p>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									<h3>What happens when you call `dispose()` on a texture but the image is not loaded yet?</h3>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									<p>
							 | 
						||
| 
								 | 
							
										Internal resources for a texture are only allocated if the image has fully loaded. If you dispose a texture before the image was loaded,
							 | 
						||
| 
								 | 
							
										nothing happens. No resources were allocated so there is also no need for clean up.
							 | 
						||
| 
								 | 
							
									</p>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									<h3>What happens when I call `dispose()` and then use the respective object at a later point?</h3>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									<p>
							 | 
						||
| 
								 | 
							
										The deleted internal resources will be created again by the engine. So no runtime error will occur but you might notice a negative performance impact for the current frame,
							 | 
						||
| 
								 | 
							
										especially when shader programs have to be compiled.
							 | 
						||
| 
								 | 
							
									</p>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									<h3>How should I manage *three.js* objects in my app? When do I know how to dispose things?</h3>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									<p>
							 | 
						||
| 
								 | 
							
										In general, there is no definite recommendation for this. It highly depends on the specific use case when calling `dispose()` is appropriate. It's important to highlight that
							 | 
						||
| 
								 | 
							
										it's not always necessary to dispose objects all the time. A good example for this is a game which consists of multiple levels. A good place for object disposal is when
							 | 
						||
| 
								 | 
							
										switching the level. The app could traverse through the old scene and dispose all obsolete materials, geometries and textures. As mentioned in the previous section, it does not
							 | 
						||
| 
								 | 
							
										produce a runtime error if you dispose an object that is actually still in use. The worst thing that can happen is performance drop for a single frame.
							 | 
						||
| 
								 | 
							
									</p>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									<h2>Examples that demonstrate the usage of dispose()</h2>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									<p>
							 | 
						||
| 
								 | 
							
										[example:webgl_test_memory WebGL / test / memory]<br />
							 | 
						||
| 
								 | 
							
										[example:webgl_test_memory2 WebGL / test / memory2]<br />
							 | 
						||
| 
								 | 
							
									</p>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								</body>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								</html>
							 |