Utilizing Web Worker to Load Textures in Three.js

When a large texture image is applied to a Mesh in Three.js for a substantial amount of time, it causes the browser's main thread to freeze. Consider the following scenario:

var texLoader = new THREE.TextureLoader();

texLoader.load('someLargeTexture.jpg', function(texture) {
    var geometry = new THREE.SphereGeometry(10, 32, 32);
    var material = new THREE.MeshBasicMaterial({map: texture});
    var sphere = new THREE.Mesh(geometry, material);

    // adding the object to the scene results in main thread lock-up
    scene.add(sphere);
});

Upon observation, I found the following:

  • No thread lock-up occurs if the new object is not added to the scene
  • Changing the geometry of an object doesn't cause lock-up
  • Creating a new object with a material borrowed from an existing object (already in the scene) does not lead to lock-up
  • Assigning a new material to an existing object (already in the scene) causes lock-up

My deduction is that Three.js performs some operations on a material when it's added to the scene. The result is cached for later reuse.

The question arises: can this processing be offloaded to a web worker to prevent main thread lock-up?

The worker setup could be like this:

var texLoader = new THREE.TextureLoader();

texLoader.load('someLargeTexture.jpg', function(texture) {
    var material = new THREE.MeshBasicMaterial({map: texture});

    // ... lengthy operations go here ...

    // adding the object to the scene still locks up the main thread
    self.postMessage({
        msg: 'objectCreated',
        material: material.toJson(), // converting material to JSON
    });
});

Then in the main thread, we could implement:

var worker = new Worker('worker.js');

worker.addEventListener('message', function(ev) {
    var geometry = new THREE.SphereGeometry(10, 32, 32);

    // converting JSON back to material object
    var material = MaterialLoader.prototype.parse( ev.data.material );

    // this operation should not lock up the main thread
    var sphere = new THREE.Mesh(geometry, material);

    scene.add(sphere);
});

Is it possible to achieve something like this?

Answer №1

Encountered a challenge while attempting to load textures simultaneously using workers. The issue lies in THREE.Texture retaining a reference to the <img> (DOM element) containing the image data. Unfortunately, serializing an <img> is not feasible, even though webgl can use <img> as texture data, rendering THREE's involvement unnecessary.

One potential solution involves utilizing a THREE.DataTexture, which requires transforming potentially compressed images into uncompressed RGB format. However, employing a <canvas> drawImage() + getImageData() workaround is not viable due to workers being unable to interact with DOM elements.

Ultimately, the decision was made to postpone parallel texture loading until the-offscreen-canvas-interface becomes available.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for deactivating the highlight on a previously selected menu item when clicking on the next menu option in Angular.js

In my pages, I have a menu where the landing page menu is initially highlighted. However, when I move to the next menu, the previous landing page highlight remains instead of being removed while swapping the menu. I am using Angular.js and angular ui-route ...

Having issues with the script not functioning when placed in an HTML document or saved as a .js file

Even though the database insertion is working, my script doesn't seem to be functioning properly. The message "successfully inserted" appears on the saveclient.php page instead of the index.html. In my script (member_script.js), I have placed this in ...

What is the best way to update and add data with just one click using jQuery?

Trying to dynamically add text to textboxes by clicking an "add" button. The code allows for adding/removing textboxes that save values to and delete from a database. Upon page load, a function called showitem creates textboxes dynamically and populates th ...

Ways to invoke jQuery(this) within an anchor tag's onclick event handler

My task involves working with HTML code and I need to apply a class name to the parent li tag using jQuery. Here is the HTML code snippet: <ul> <li><a onclick="setSelectedTestPlan();" href="javascript:void(0);">New Test</ ...

Managing several items within one function

I am working with a json file that contains similar data sets but different objects. { "AP": [{ "name": "Autogen Program" }, { "status": "Completed" }, { "start": "2014-05-05" }, { ...

Adjust the appearance of a div according to the input value

When a user inputs the correct value (a number) into an input of type "number," I want a button to appear. I attempted var check=document.getElementById("buttonID").value == "1" followed by an if statement, but it seems I made a mistake somewhere. Here&ap ...

Async functions in Node.js are not executing in the expected sequence

I have a specific challenge of sending a POST request to my backend. This particular POST request necessitates the use of multipart/form-data. To facilitate this, I am in the process of converting image locations into Buffers before sending them all as par ...

Implementing Jquery after async ajax refresh in an asp.net application

My ASP.net page is heavily reliant on jQuery. Within this page, I have a GridView placed inside an UpdatePanel to allow for asynchronous updates. <asp:GridView ID="gvMail" runat="server" GridLines="None" AutoGenerateColumns="false" ...

The value from the textbox is not being received by the JavaScript and PHP

I'm encountering an issue with my codes where they are not properly passing the value of the verification code from the textbox to JavaScript and then to PHP. I need assistance in resolving this issue. Below is the snippet of code: HTML: /* HTML c ...

Experiencing issues with creating HTML using JavaScript?

I'm a JavaScript novice and struggling to figure out what's wrong with my code. Here is the snippet: var postCount = 0; function generatePost(title, time, text) { var div = document.createElement("div"); div.className = "content"; d ...

Error: JSON parsing error encountered for token < at position 0 within the context of Google Sheets Apps Script Tutorial

I'm currently working through a Google Sheets Apps Scripts editor tutorial and I've reached module 4. Unfortunately, I've encountered an issue with the code I copied directly from the module. The error message I'm seeing is: SyntaxError ...

Enable the server to accept requests from localhost containing parameters

I am facing an issue with my application running locally on my computer, trying to connect to a remote nodeJS/Express server. The headers have been set on the remote server. Main inquiry: How can I configure my remote server to accept requests from my loc ...

Unprocessed Promise Rejection Alert: The function res.status is not recognized as a valid function (NEXT JS)

When I console.log(response), I see the result in the terminal. However, when I use res.status(200).json(response), I encounter an error in my Next.js project: Not Found in the browser. router.get("/api/backendData", async (req, res) => { dbConne ...

Displaying an array of JSON objects in ReactJS by parsing them

Recently, I've encountered an odd issue with my React App. I am attempting to parse a JSON object that includes arrays of data. The structure of the data looks something like this: {"Place":"San Francisco","Country":"USA", "Author":{"Name":"xyz", "Ti ...

Hide the content within a table row by setting the display to

I need to hide the div with the id "NoveMeses" if all h3 elements display "N.A." Is there a way to achieve this? If both h3 elements in row1 and row2 contain the text "N.A.", I want the div NoveMeses to be hidden. Below is the code snippet using AngularJ ...

I am experiencing an issue where tapping on the Status Bar in MobileSafari is not functioning correctly on a specific

I am struggling to troubleshoot this problem with no success so far. The HTML5 JavaScript library I'm developing has a test page that can display a large amount of output by piping console.log and exceptions into the DOM for easy inspection on mobile ...

Disappearances of sliding jQuery divs

I am currently working on a website using jQuery, and I have implemented a slide in and out div to display share buttons. The issue I am facing is that the code works perfectly on the first page, but on every other page, the div slides out momentarily and ...

The server at localhost responds with a CANNOT GET/ error message

This is the code snippet I've been working on: const express = require('express'); const app = express(); const bodyparser = require('body-parser'); app.use(bodyparser.urlencoded({extended: false})); app.use(bodyparser.json()); c ...

Utilizing dynamic props JSON object to modify the state

Within my component, I am working with a json object passed in as a prop from the parent component, where the API call to populate this json object is made in the parent component itself. My current challenge is figuring out how to properly define the sta ...

How do I go about showing every character on a separate line using a for loop?

var input = prompt("What is Lance attempting to convey?"); //user enters any text for (var i = 0; i <= input.length; i++) { var output = input.charAt(i); if (output == "e" || output == "o" || output == "a" || output == "u") { outp ...