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.
 
 
 
 
 

120 lines
8.0 KiB

<!DOCTYPE html>
<html lang="ko">
<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>
애플리케이션에서 성능을 개선하고 메모리 누수를 방지하기 위한 중요한 한 가지는 사용되지 않는 라이브러리 개체를 폐기하는 것입니다.
*three.js* 유형의 인스턴스는 생성될 때마다 일정량의 메모리를 할당하게 됩니다. 하지만 *three.js*는 특정 개체에 대해 기하학적 구조나 WebGL 관련 재질(예: 버퍼 또는 쉐이더 프로그램) 개체의 렌더링에 필요한 것입니다.
이러한 오브젝트들은 자동으로 폐기되지 않는다는 점을 주의하세요. 대신, 애플리케이션에서는 메모리 자원을 확보하기 위해 특별한 API를 사용해야 합니다.
이 가이드에서는 이 API의 사용 방법과 이와 관련해서 어떤 오브젝트가 있는지에 대한 간략한 설명을 제공해 드립니다.
</p>
<h2>기하학</h2>
<p>
기하학은 속성 집합으로 정의된 꼭짓점 정보를 표시하는데, *three.js*는 속성마다 하나의 [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLBuffer WebGLBuffer] 유형의 대상을 만들어 내부에 저장합니다.
이러한 개체는 [page:BufferGeometry.dispose]를 호출할 때만 폐기됩니다.
만약 애플리케이션에서 기하학을 더이상 사용하지 않는다면, 이 방법을 실행하여 모든 관련 자원을 폐기하세요.
</p>
<h2>재질</h2>
<p>
재질은 오브젝트가 어떻게 렌더링되는지를 정의합니다. *three.js*는 재질에 정의된 정보를 사용하여 렌더링을 위한 하나의 셰이더 프로그램을 구축합니다.
셰이더 프로그램은 해당 재질이 폐기된 후에만 삭제할 수 있습니다. 성능상의 이유로 *three.js*는 가능하다면 활용 가능한 셰이더 프로그램을 재사용하게 되어 있습니다. 따라서 셰이더 프로그램은 모든 관련된 재질들이 사라진 후에야 삭제됩니다.
[page:Material.dispose]() 를 실행함으로써 재질을 폐기할 수 있습니다.
</p>
<h2>텍스쳐</h2>
<p>
재질의 폐기는 텍스쳐에 영향을 미치지 않습니다. 이들은 분리되어 있어 하나의 텍스쳐를 여러 재질로 동시에 사용할 수 있습니다.
[page:Texture] 인스턴스를 만들 때마다 three.js는 내부에서 [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLTexture WebGLTexture] 인스턴스를 만듭니다.
buffer와 비슷하게, 이 오브젝트는 [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>렌더링 대상</h2>
<p>
[page:WebGLRenderTarget] 타입의 오브젝트는 [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLTexture WebGLTexture]의 인스턴스가 할당되어 있을 뿐만 아니라,
[link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLFramebuffer WebGLFramebuffer]와 [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderbuffer WebGLRenderbuffer] 도 할당되어,
커스텀 렌더링 목표를 실체화합니다. 이러한 오브젝트는 [page:WebGLRenderTarget.dispose]()를 실행해야만 폐기할 수 있습니다.
</p>
<h2>그밖의 것들</h2>
<p>
컨트롤러나 후기 처리 프로세스처럼 *dispose()* 메서드가 제공되어 내부 이벤트리스너나 렌더링 대상을 폐기하는 examples 폴더에서 가져온 것들이 있습니다.
일반적으로 API나 파일을 열람하고 *dispose()* 를 확인하는 것이 좋습니다. 만약 이 메서드가 존재한다면 당연히 그 메서드를 폐기 시에 사용해야 합니다.e it when cleaning things up.
</p>
<h2>FAQ</h2>
<h3>*three.js*는 왜 자동으로 오브젝트를 폐기 못하나요?</h3>
<p>
이 문제가 커뮤니티에서 여러 차례 제기돼 온 만큼 확실한 대답을 해 드려야겠습니다. 사실, *three.js*는 사용자가 만든 개체(예를 들어 기하체 또는 재질)의 라이프사이클이나 역할 범위를 알지 못하며, 이는 애플리케이션의 책임입니다.
예를 들어, 만약 하나의 재질이 현재 렌더링에 사용되고 있지 않더라도, 바로 다음 프레임에 필수적인 재질일 수 있을 것입니다. 그래서 만약 애플리케이션에서 특정 오브젝트가 삭제되어도 된다고 하면,
해당하는 *dispose()* 메서드를 통해 엔진에 알려줘야 합니다.
</p>
<h3>화면에서 mesh를 지우는 것도 geometry와 material을 폐기시키나요?</h3>
<p>
아니요, *dispose()*를 통해 명시적으로 geometry와 material을 폐기해야합니다. geometry와 material은 mesh와 마찬가지로 3D 오브젝트에서 활용할 수 있다는 점을 명심하세요.
</p>
<h3>*three.js*에서 캐시화된 오브젝트의 수를 알 수 있나요?</h3>
<p>
네, 렌더러의 그래빅 보드와 렌더링 프로세스의 통계 정보를 담고 있는 특수 속성인 [page:WebGLRenderer.info]를 통해 확인할 수 있습니다.
다른 것 보다도, 이를 통해 내부적으로 많은 텍스쳐와 기하학, 셰이더 프로그램이 저장되어 있다는 것을 알 수 있습니다.
만약 애플리케이션에서 성능 문제를 발견했다면, 바로 이 속성을 조절하여 쉽게 메모리 누출을 확인할 수 있습니다.
</p>
<h3>이미지가 아직 로딩이 안 됐는데 텍스쳐에서 *dispose()*를 해버리면 어떻게 되나요?</h3>
<p>
텍스쳐와 관련된 내부 자원은 이미지가 완전히 로딩됐을때밖에 할당이 되지 않습니다. 만약 이미지 로딩 전에 텍스쳐를 폐기해버렸다면,
아무 일도 일어나지 않을 것입니다. 아무런 자원도 할당되지 않았고 지울 것도 없기 때문입니다.
</p>
<h3>*dispose()*를 하고 나서 나중에 다시 각각의 오브젝트를 사용하면 어떻게 되나요?</h3>
<p>
삭제된 내부 자원이 엔진에서 다시 생성될 것입니다. 런타임 에러는 발생하지 않겠지만 프레임에 부정적인 영향을 미치는 것을 확인할 수 있을 것이고
특히 셰이더 프로그램을 컴파일할 때 더 두드러질 것입니다.
</p>
<h3>*three.js* 오브젝트를 앱에서 어떻게 관리해야 할까요? 언제 폐기해야되는지 어떻게 알죠?</h3>
<p>
일반적으로 이 점에 대한 명확한 해답은 없습니다. *dispose()*는 구체적인 사용 방법에 따라 적절히 활용하는 방법이 좌우됩니다. 굳이 오브젝트를 자꾸 폐기할 필요는 없다는 것을 기억해 두세요.
다양한 레벨로 구성된 게임이 좋은 예가 될 수 있을 것입니다. 레벨이 바뀌면, 폐기를 할 때입니다. 애플리케이션은 오래된 화면을 지나가면서 오래된 재질, 기하학, 텍스쳐를 모두 폐기할 수 있습니다.
앞의 장에서 언급한 바와 같이 만약 여전히 사용하고 있는 오브젝트를 폐기해도 런타임 에러를 만들지는 않을 것입니다. 단일 프레임에서 퍼포먼스가 떨어지는 정도가 가장 안 좋은 정도일 것입니다.
</p>
<h2>dispose() 사용법 예제</h2>
<p>
[example:webgl_test_memory WebGL / test / memory]<br />
[example:webgl_test_memory2 WebGL / test / memory2]<br />
</p>
</body>
</html>