【问题标题】:How to fix three.js loading more than 2 minutes and it's crashing如何修复加载超过 2 分钟并且崩溃的three.js
【发布时间】:2019-07-07 11:21:58
【问题描述】:

我正在创建一个 3D 游戏,而我才刚刚开始。但是,我很快遇到了一个问题,即 localhost GET 耗时超过 2 分钟,并且在 15-45 秒后,画布变成白色,在控制台中,我收到一条警告,表明 WebGL 上下文已丢失。此外,在任务管理器中,游戏占用 30% 的 CPU 和 100% 的 GPU。

这是一款新的在线 3D 多人游戏。我试图在新帧之后处理内存,但这没有用。我也尝试过预加载所有纹理以使用更少的 CPU,但 30% 的 CPU 保持不变。这是我的代码:(客户端)

    var scene = new THREE.Scene();
    var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000)

    var renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);
    scene.autoUpdate = false;
    var preLoad = new THREE.TextureLoader();
    var sunTexture = preLoad.load("/static/sun-texture.jpg");
    var mercuryTexture = preLoad.load("/static/mercury-texture.jpg");
    var socketio = io();
    var Geometries = [];
    socketio.on("TX2", function (data) {
        Geometries = [];
        var collectedEntities = [];
        data.objects.forEach(obj => {
            collectedEntities.push(obj);
        });
        DisplayAllEntities(collectedEntities);
    });
    function DisplayAllEntities(objects) {
        var loader;
        objects.forEach(obj => {
            if (obj.geometry == "sphere") {
                if (obj.type != "ordinary_sphere") {
                    switch (obj.type) {
                        case "sun":
                            var material = new THREE.MeshBasicMaterial({ map: sunTexture });
                            break;
                        case "mercury":
                            var material = new THREE.MeshBasicMaterial({ map: mercuryTexture });
                            camera.position.z = obj.z + 500;
                            break;
                    }
                }
                loader = new THREE.TextureLoader();
                var texture = loader.load(obj.texture)
                var geometry = new THREE.SphereGeometry(obj.radius, 50, 50, 0, Math.PI * 2, 0, Math.PI * 2);

                var mesh = new THREE.Mesh(geometry, material);
                Geometries.push(mesh);

            } else if (obj.geometry == "cube") {
                loader = new THREE.TextureLoader();
                var texture = loader.load(obj.texture)
                var geometry = new THREE.CubeGeometry(obj.width, obj.height, obj.depth);

                var material = new THREE.MeshBasicMaterial({ map: texture });
                var mesh = new THREE.Mesh(geometry, material);
                mesh.position = {"x": obj.x, "y": obj.y, "z": obj.z}
                Geometries.push(mesh);

            }
            loader = null;
        });

        scene.children = [];
        scene.dispose();
        Geometries.forEach(obj => {
            scene.add(obj);
        });
        render();
    }
    function render() {
        requestAnimationFrame(render);
        renderer.render(scene, camera);
    } 

服务器只是对位置进行计算,然后将它们发送给客户端进行渲染。

我希望获得更低的 CPU 和 GPU 使用率以及更短的加载时间,但性能仍然保持不变。

【问题讨论】:

  • TX2 是用于初始化函数还是游戏循环?
  • 这是一个服务器端代码发射,每秒执行 60 次。它为所有实体的位置发送数据包。

标签: javascript node.js three.js webgl


【解决方案1】:

每次需要渲染时都创建每个对象,尤其是加载相应的纹理,效率非常低。更好的解决方案是预先设置对象,然后不断更新这些对象。这需要

  • 用于初始化(设置对象、加载纹理等)的服务器发射
  • 用于游戏状态更新的服务器发出(根据需要添加/删除项目)
  • 服务器发出来更新位置。 (这是每秒执行 60 次的那个)
  • 每个对象都有一个由服务器在创建时提供的唯一 ID,以便客户端知道服务器引用了哪些对象。

这需要更多的努力,但会大大提高性能

【讨论】:

  • 谢谢!我试试看。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-07
  • 1970-01-01
  • 2019-10-07
  • 2018-01-18
  • 1970-01-01
  • 2019-06-08
  • 2019-12-31
相关资源
最近更新 更多