Three js destroy renderer [duplicate] - javascript

This question already has an answer here:
How can I destroy THREEJS Scene?
(1 answer)
Closed 5 months ago.
What's the best way to destroy a three js instance?
I'm finding that when I remove the canvas and re-add, my first renderer remains and I have two.
Currently I'm
Removing all the event listeners
cancelling requestAnimationFrame
deleting the renderer instance from it's parent

What about something like?
cancelAnimationFrame(this.id);// Stop the animation
this.renderer.domElement.addEventListener('dblclick', null, false); //remove listener to render
this.scene = null;
this.projector = null;
this.camera = null;
this.controls = null;
empty(this.modelContainer);
function empty(elem) {
while (elem.lastChild) elem.removeChild(elem.lastChild);
}
This was a reference to this old SO post: How can I destroy THREEJS Scene?

To destroy the scene, try:
scene = null;
To remove a mesh:
scene.remove( mesh );

Related

Three.JS instance can't be re-created

I'm trying to destroy (or destruct or dispose) an 'instance' of Three.JS using this:
Full example: https://jsfiddle.net/v7oLzs4m/58/
function kill() {
const rendererDomWas = renderer.domElement;
renderer.dispose();
controls.dispose();
renderer = scene = camera = controls = null;
document.body.removeChild( rendererDomWas );
shouldRender = false;
}
function animate() {
if(!shouldRender) {return} // no more requesting animation frames if 'shouldRender' is false
frameID = window.requestAnimationFrame( animate );
renderer.render( scene, camera );
}
(i.e. disposing, setting references to null, and stopping the draw loop from touching renderer while shouldRender is false)
It appears to work at first (The renderer content stops showing) but when I re-create the instance, it never comes back.
It's as if something is still... holding onto the GLContext which prevents it from being invoked again.
Why can't I re-create a new instance of Three.JS?
I'm not sure why this works (since I was already doing this in my Fiddle...)
But it turns out the secret ingredient (for me) to letting Three.JS get GC'd/disposed is this:
window.cancelAnimationFrame(frameID);
I suppose that this stops the render function from being stored in the hardware-level draw loop, which holds references to GLContext (and the chain)
The GC can't ever happen unless the 'loop is broken'
(Correct me if I'm wrong please)

Three.js Scene Switching Performance Issue

I have created a game in three.js which exists of 3 scenes the GameScene, MenuScene and the HighScoreScene. The user can switch between those scenes - When the player is changing the Scene e.g. from the MenuScene to the HighScoreScene I'm trying to clean up the resources from the old Scene.
But cleaning up the resources seems not to work.
So here is my code which is getting executed when the user is switching between scenes:
So in the old Scene I have this animation loop:
function cancelAnimation() {
cancelAnimationFrame(animationFrameId); // EXECUTING WHEN SWITCHING SCENE!!!
}
function animate() {
animationFrameId = requestAnimationFrame(animate); // Saving id
render();
}
function render() {
renderer.clear();
renderer.render(scene, camera);
}
So when switching the scene I unset all click listeners and I'm calling cancelAnimation.
Because I'm storing that code for each Scene in an object like var menuScene = new MenuScene() I'm also doing this menuScene = undefined when switching the scene.
I'm also passing the same instance of var renderer = new THREE.WebGLRenderer(); to the scenes.
This all seems not to help the game is executing more slowly.
What is the proper way to switch between those scenes and clearing up the resources? What am I doing wrong here?

THREE.Audio setRefDistance is not a function

I'm using three r73 and got stuck with a simple 3D audio example:
// ...
var listener = new THREE.AudioListener();
camera.add( listener );
var sound1 = new THREE.Audio( listener );
sound1.load( 'sounds/song.ogg' );
sound1.setVolume(1);
sound1.setRefDistance(10);
sound1.autoplay = true;
mesh.add(sound1);
I got setRefDistance is not a function.
If I remove this line sound1.setRefDistance(10);, the sound play but isn't "3D aware".
I don't know what is different from this simple example http://threejs.org/examples/misc_sound.html except I'm in an angular context + nodejs
Ok, my bad, I was in fact using r74dev and I needed to use THREE.PositionalAudio

How to remove and dispose of all child geometry and meshes from an Object3D?

In this project I am working on I have several Collada models being displayed and then removed when not needed anymore. There seems to be a memory leak somewhere in the project and I am looking for ways to get it to run as smooth as possible as time is not on my sideā€¦
I feel like I don't remove the meshes the right way and that this might cause some of the memory leakage I have.
I load the objects with LoadObject(level_1_character, "Assets/Level_1_Character.dae"); for example, where level_1_character is a Object3D. This calls the following function:
function LoadObject(name, url) {
var mesh, geometry, material, animation;
var loader = new THREE.ColladaLoader();
loader.options.convertUpAxis = true;
loader.load(url, function(col) {
mesh = col;
geometry = col.scene;
name.name = url.toString();
name.add(geometry);
});
}
I add the objects to the scene depending on the level through scene.add(level_1_character); and then remove it by doing the following:
level_1_character.traverse(function(child){
if (child instanceof THREE.Mesh) {
child.material.dispose();
child.geometry.dispose();
}
});
I am not sure if this actually fully removes the object though. It seems as though the objects still are present in memory. Any idea what I'm doing wrong here?

How can I destroy THREEJS Scene?

I created a Threejs Scene, adding camera, lights and various objects.
The question is simple: how can I destroy scene? Removing from scene all components?
I need to destroy scene because and I do not want to delegate the task to the garbage collector.
I used this:
cancelAnimationFrame(this.id);// Stop the animation
this.renderer.domElement.addEventListener('dblclick', null, false); //remove listener to render
this.scene = null;
this.projector = null;
this.camera = null;
this.controls = null;
empty(this.modelContainer);
The method empty is a substitute to jQuery empty, you can use it:
function empty(elem) {
while (elem.lastChild) elem.removeChild(elem.lastChild);
}

Categories