Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using webworkers in THREE.js

I have a larger model that freeze my scene. As I don't need this model from the beginning it would be cool to load this model in the background. Are webworkers a solution for this?

Can anyone guide me how to accomplish it , or is it possible at all ?

Thanks.

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

var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

var loader = new THREE.JSONLoader();
loader.load("models.js", function (smooth) {
    smooth.mergeVertices();
    smooth.computeFaceNormals();
    smooth.computeVertexNormals();
    var modifier = new THREE.SubdivisionModifier(1);
    modifier.modify(smooth);
    var mesh = new THREE.Mesh(smoothnew THREE.MeshBasicMaterial({
        color: 0x00ff00
    }));
    scene.add(mesh);
});

var render = function () {
    requestAnimationFrame(render);
    renderer.render(scene, camera);
};

render();
like image 561
Alexander Hein Avatar asked Nov 21 '22 23:11

Alexander Hein


1 Answers

JavaScript is single threaded and uses "cooperative" scheduling for its events, which means that if you have a function with a long loop that doesn't give up its execution nothing else will be able to be executed in the meantime.

Your method in the loader is essentially that, a single method that'll run its computations to completion before allowing other JavaScript code to run. So rather than using a worker you might be able to split it up a bit by making it more event driven and improve the experience that way, something like this:

loader.load("models.js", function (smooth) {
    smooth.mergeVertices();
    smooth.computeFaceNormals();
    smooth.computeVertexNormals();
    window.setTimeout( function() {
        var modifier = new THREE.SubdivisionModifier(1);
        modifier.modify(smooth);
        window.setTimeout( function() {
            var mesh = new THREE.Mesh(smoothnew THREE.MeshBasicMaterial({
                color: 0x00ff00
            }));
            scene.add(mesh);
        }, 100 );
    }, 100 );
});

(The points where I added setTimeout() are entirely arbitrary since I have no way of knowing where the biggest delays are without a jsfiddle to run your code + data).

This will only really work if none of these method calls themselves take up the majority of time. If e.g. mergeVertices() itself takes up most of the CPU time the only way to solve the freezing is by offloading that computation to a worker. The you'll need to pass the data around, compute it on the worker, and have the main code add it to the scene (the worker doesn't have access to the WebGL context). The complexity of that solution might not make the effort worth it however.

like image 111
Leeft Avatar answered Dec 25 '22 06:12

Leeft