Experience in creating multiple 3D scenes without page reloading (three.js)

What do i do



For a personal project, I needed to find a solution to work with a number of different gltf models.



I had a little experience with three.js, so after reading the GLTFLoader examples, this particular library was chosen.



Scene data is stored in a separate json file and contains information about the path to the scene, lighting, camera path, etc. but in this material they interest us to a lesser extent.



In theory, it was necessary to draw several scenes in a row. In practice, everything turned out to be somewhat more complicated.



How do I



Camera



The first difficulty was plotting a route for the camera to move. From the requirements for the

camera and movement:



  • The camera should move along the key points, completing the intermediate ones;
  • the camera should depend on the scroll of the mouse wheel (moving forward and backward, respectively);
  • the camera should smoothly "brake" and smooth out its movement.


To build and interpolate the path, CatmullRomCurve3 came up with the getPoint () method, which built a fairly smooth curve. The rest of the curve classes, such as Curve or CubicBezierCurve3, did not draw the intermediate points smoothly enough. This should be taken into account.



. , ( ). ( ). , , , ( ) . , , .



. TrackballControls (0, 0, 0). (W, S, D, A ), , , ( ).





, fps . , - . . . .







, . , . , , . , GPU , .



three.js SPA ( ) , .



for (let i = mScene.scene.children.length - 1; i >= 0; i--) {
    mScene.scene.remove(mScene.scene.children[i]); //  ,    
}


. . dispose() :



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.


, dispose. ? ( ):



dispose_scene() {
    let self = this;
    self.scroll_timer_stop();
    this.scene.traverse(function (object) {
    self.scroll_timer_stop();
        if (object.type === "Mesh" || object.type === "Group") {
            self.dispose_hierarchy(object, self.dispose_node);
            self.scene.remove(object);
            object = null;
       }
    });
}

dispose_hierarchy(node, callback) {
    for (var i = node.children.length - 1; i >= 0; i--) {
        var child = node.children[i];
        this.dispose_hierarchy(child, callback);
        callback(child);
    }
}

dispose_node(node) {
        if (node.constructor.name === "Mesh") {
            node.parent = undefined;
            if (node.geometry) {
                node.geometry.dispose();
            }
            if (node.geometry) {
                node.geometry.dispose();
            }
            let material = node.material;
            if (material) {
                if (material.map) {
                    material.map.dispose();
                }
                if (material.lightMap) {
                    material.lightMap.dispose();
                }
                ...
                material.dispose();
                material = undefined;
            }
        } else if (node.constructor.name === "Object3D") {
            node.parent.remove(node);
            node.parent = null;
        }
}

dispose_postprocessing() { 
        this.postprocessing.rtTextureColors.dispose();
        this.postprocessing.rtTextureDepth.dispose();
        ...
        this.postprocessing.materialGodraysDepthMask.dispose();
        this.postprocessing.materialGodraysGenerate.dispose();
        ...
}




, three.js . this.postprocessing.dispose() , , dispose() , , . , , . . . Geforce 2070 super , :







. . !




All Articles