Experiência na criação de várias cenas 3D sem recarregar a página (three.js)

O que eu faço



Para um projeto pessoal, eu precisava encontrar uma solução para trabalhar com vários modelos gltf diferentes.



Eu tive um pouco de experiência com three.js, então depois de ler os exemplos do GLTFLoader, esta biblioteca em particular foi escolhida.



Os dados da cena são armazenados em um arquivo json separado e contém informações sobre o caminho para a cena, iluminação, caminho da câmera, etc. mas neste material eles nos interessam em menor grau.



Em teoria, era necessário desenhar várias cenas seguidas. Na prática, tudo acabou sendo um pouco mais complicado.



Como é que eu



Câmera



A primeira dificuldade foi traçar uma rota para a câmera se mover. Dos requisitos para a

câmera e movimento:



  • A câmera deve se mover ao longo dos pontos-chave, completando os intermediários;
  • a câmera deve depender da rolagem da roda do mouse (para frente e para trás, respectivamente);
  • a câmera deve "travar" suavemente e suavizar seu movimento.


Para construir e interpolar o caminho, CatmullRomCurve3 veio com o método getPoint (), que construiu uma curva bastante suave. O resto das classes de curva, como Curve ou CubicBezierCurve3, não desenharam os pontos intermediários com suavidade suficiente. Isso deve ser levado em consideração.



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



. 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