Erfahrung in der Erstellung mehrerer 3D-Szenen ohne erneutes Laden von Seiten (three.js)

Was mache ich



Für ein persönliches Projekt musste ich eine Lösung finden, um mit einer Reihe verschiedener gltf-Modelle zu arbeiten.



Ich hatte ein wenig Erfahrung mit three.js, also wurde nach dem Lesen der GLTFLoader-Beispiele diese spezielle Bibliothek ausgewählt.



Szenendaten werden in einer separaten JSON-Datei gespeichert und enthalten Informationen zum Pfad zur Szene, zur Beleuchtung, zum Kamerapfad usw. aber in diesem Material interessieren sie uns in geringerem Maße.



Theoretisch war es notwendig, mehrere Szenen hintereinander zu zeichnen. In der Praxis stellte sich heraus, dass alles etwas komplizierter war.



Wie mache ich



Kamera



Die erste Schwierigkeit bestand darin, eine Route für die Bewegung der Kamera zu zeichnen. Aus den Anforderungen an

Kamera und Bewegung:



  • Die Kamera sollte sich entlang wichtiger Punkte bewegen und Zwischenpunkte vervollständigen.
  • Die Kamera sollte von der Rolle des Mausrads abhängen (vorwärts bzw. rückwärts bewegen).
  • Die Kamera sollte sanft "bremsen" und ihre Bewegung glätten.


Um den Pfad zu erstellen und zu interpolieren, hat CatmullRomCurve3 die Methode getPoint () entwickelt, mit der eine ziemlich glatte Kurve erstellt wurde. Die übrigen Kurvenklassen wie Curve oder CubicBezierCurve3 haben die Zwischenpunkte nicht reibungslos genug gezeichnet. Dies sollte berücksichtigt werden.



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



. 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