Completely destroy scene and recreate new one

Hello guys,
I’m struggling with the issue to “destroy” existing scene (scene, renderer, objects, materials…) and create new, “fresh one”.
Which entities to dispose, delete, set to null ? I’ve tried to cancelAnimationFrame, dispose all objects and materials, dispose renderer, set scene to null. Despise that, after 3-4 attempts of destroying and recreating, application crashes with the Error (THREE.WebGLProgram: Shader Error 0 - VALIDATE_STATUS false) .

Thanks in advance!

Reload Page.

Without reloading page.

Then provide something: ( code, link , console log, … )

Okay. I use THREE JS library in Angular application, and 3D scene is created when the lifecycle hook “ngAfterViewInit” is called. In that lifecycle hook, 4 methods are defined.

this._scene = new THREE.Scene();

this.load3dObjects();
this.addLights();
this.addCamera();
this.startRenderingLoop();

3D objects are loaded from the obj.file and added to the scene. Then I add lights and postion camera, it is quite simple configuration. I think that the problem lies with the startRenderingLoop.

private startRenderingLoop() {

    // *** Renderer
    this.createRenderer();

    const component: DigitalTwinComponent = this;

    (function render()  {
      cancelAnimationFrame(component.digitalTwinService.rendererID)
      component.digitalTwinService.rendererID = requestAnimationFrame(render);
      component.autoRotateCamera();
      component._controls.update();

      component._raycaster.setFromCamera(component._mouse, component._camera);
      const intersects = component._raycaster.intersectObjects(component._scene.children);

      // *** Highlight 3D object on hover
      if (intersects.length > 0) {
        if (component.intersected !== intersects[0].object) {
          if (component.intersected) {
            component.intersected.material.color.setHex(component.intersected.currentHex);
          }
          let i = intersects.length

          if (intersects[0].object.visible === true)
            component.intersected = intersects[0].object;
          else
            component.intersected = intersects[i-1].object;
          component.intersected.currentHex = component.intersected.material.color.getHex();
          component.intersected.material.color.setHex(0xff0000);
        }
      } else {
        if (component.intersected) {
          component.intersected.material.color.setHex(component.intersected.currentHex);
        }
        component.intersected = null;
      }

      component._renderer.clear();
      component._renderer.render(component._scene, component._camera);
    }());
  }
private createRenderer() {
    this._renderer = new THREE.WebGLRenderer({ canvas: this._canvasRef.nativeElement, antialias: true });
    this._renderer.shadowMap.enabled = true;
    this._renderer.shadowMap.type = THREE.PCFSoftShadowMap;
    this._renderer.setPixelRatio(devicePixelRatio);
    this._renderer.setSize(this._canvasRef.nativeElement.clientWidth, this._canvasRef.nativeElement.clientHeight);

    this._controls = new OrbitControls(this._camera, this._renderer.domElement);
    this._controls.update();
  }

So whenever this component is initialized, these methods are called. So I’ve tried to clean the scene and renderer (if they exist) before these methods are called. I’ve used this code.

clear(){
    this._renderer.dispose()
    this.stopAnimation()

    this._scene.traverse(object => {
      if (!object.isMesh) return
      
      this.deleteObject(object)
    })
  }

private deleteObject(object: THREE.Object){
    object.geometry.dispose()

    if (object.material instanceof Array) {
      object.material.forEach(material => material.dispose());
    } else {
        object.material.dispose();
    }
    object.removeFromParent()
    this._scene.remove(object)
  }

For reference — How to Dispose of Objects.

Could you share a demo? The code looks reasonable but is missing chunks and isn’t enough to reproduce the error.

Hello, You can find demo here: Angular 11 New (forked) - StackBlitz.

It’s not the same as the application, but it implements similar logic. There you can find, 3D simulation, and two buttons, one to “clear scene” and other to “create new one”.
I know there is an option to clear all the objects from the scene and add new ones, but I don’t want to do that !

As I’ve mentioned above, in the application, 3D setup is created on component load. Every time component loads, variables defined in component are reinitialized again, and procedure for creating 3D setup begins. The problem is that I can’t clear “previous setup” on load, and that causes application to crash.

I m also wondering what happens with 3D setup (scene, render) when user goes to other page in the same application?

So what is my goal here?

So when user clicks button “Clear Everything”, scene, objects, render should be destroyed or set to undefined (same as when application builds for the first time). After user has clicked “Clear Everything”, and it clicks “Start new Scene”, a new Scene should emerge.

This seems pretty simple request, create 3D setup, destroy it, and recreate it.

Thanks in advance guys !

Important notice.

Application (not one displayed in Demo) works properly while using Mozilla Firefox, it doesn’t crash or create errors. On the other hand, application crashes while using Chrome and Edge.