Using `texture.needsUpdate = true` in Three.js can cause significant performance issues due to its slow execution

I am currently working on a project involving a Three.js scene where I need to update textures after a certain period of time. However, I have noticed that updating the textures is causing a significant slowdown in the FPS, dropping it to 1-2 FPS for several seconds, especially when updating just a single texture.

Does anyone have any tips or tricks to speed up the process of updating textures? Any advice or insights on this matter would be greatly appreciated.

If you want to observe this behavior, simply click on the window in the example below. This will trigger the first texture update (another click will initiate the second texture update). If you attempt to zoom in after one of these clicks, you will notice that the screen freezes and the FPS drops significantly. Does anyone have a solution to address this issue?

<html>
<head>
  <style>
  html, body { width: 100%; height: 100%; background: #000; }
  body { margin: 0; overflow: hidden; }
  canvas { width: 100%; height: 100%; }
  </style>
</head>
<body>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/three.js/88/three.min.js'></script>
  <script src='https://rawgit.com/YaleDHLab/pix-plot/master/assets/js/trackball-controls.js'></script>
  <script src='https://rawgit.com/mrdoob/stats.js/master/build/stats.min.js'></script>

    <script type='x-shader/x-vertex' id='vertex-shader'>
    precision highp float;

    uniform mat4 modelViewMatrix;
    uniform mat4 projectionMatrix;

    uniform vec3 cameraPosition;

    attribute vec3 position;
    attribute vec3 translation;
    attribute float texIdx;

    varying float vTexIdx;

    void main() {
      vec3 pos = position + translation;
      vec4 projected = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
      gl_Position = projected;

      vTexIdx = texIdx;

      float xDelta = pow(projected[0] - cameraPosition[0], 2.0);
      float yDelta = pow(projected[1] - cameraPosition[1], 2.0);
      float zDelta = pow(projected[2] - cameraPosition[2], 2.0);
      float delta  = pow(xDelta + yDelta + zDelta, 0.5);
      gl_PointSize = 40000.0 / delta;
    }
    </script>

    <script type='x-shader/x-fragment' id='fragment-shader'>
    precision highp float;

    uniform sampler2D a;
    uniform sampler2D b;

    varying float vTexIdx;

    void main() {
      int textureIndex = int(vTexIdx);
      vec2 uv = vec2(gl_PointCoord.x, gl_PointCoord.y);
      if (textureIndex == 0) {
        gl_FragColor = texture2D(a, uv);
      } else if (textureIndex == 1) {
        gl_FragColor = texture2D(b, uv);
      }
    }
    </script>

  <script>
  // Remaining JavaScript code...
</script>
</body>
</html>

Answer №1

Wow, your canvases are really huge at 16384 by 16384. That size is definitely on the insanely large side.

When it comes to RGBA format, that amounts to a whopping 1073741824 bytes... that's a whole gigabyte of texture data being transferred from the CPU to the GPU when you update that texture with texture.needsUpdate = true.

The impact of this upload on your GPU performance will surely be noticeable.

If your specific use case truly demands textures of this size, you might need to think about implementing incremental updates through methods like gl.texSubImage2D. Alternatively, consider using multiple smaller textures and updating just one per frame, or doing a one-time update of textures at the beginning of your application.

Just for perspective, the need for textures larger than 4k on each side is quite rare in my experience.

In fact, that's only about 1/16th of the size of your current textures.

This performance issue is not unique to three.js; it's a basic aspect of how the GPU and CPU interact. Transfer and state changes can be slow and require careful management and monitoring.

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

What is the best way to display an international phone number using Angular Material V6?

I've been working on a project that utilizes Angular Material V6. My goal is to display international phone numbers with flags in a Material component text box. After some research online, I came across an npm module that achieved this but it was tail ...

Retrieving the object ID of an Open Graph from a page's URL

Is there a way to obtain the Facebook Object ID associated with a page directly from the page itself? For instance, if I requested the Object ID 325186347604922, this is what I received: <pre> { "url": ".../ricetta-bigne_salati.htm", "type": " ...

Utilizing ng-repeat to iterate over a nested array

I need help figuring out how to properly loop through a JSON array and its ingredients/directions array using ng-repeat. The current method I have attempted is not working as expected. Any suggestions or advice would be greatly appreciated! Thank you. Con ...

Arranging a list based on the child property in a React component

Within my application, I have an array mapped to a map that generates a div with a data-date attribute as shown below: It's worth noting that the array cannot be sorted here since there are no dates available for comparison, only the element ID cons ...

Using AngularJS ng-repeat to pass href links

I am facing an issue with displaying hyperlinks in a list of messages obtained from server response using AngularJS. $scope.messages = [] When a button is clicked, the content of a text area is added to the array using ng-click method. This message is th ...

Updating Vue component with mismatched props

I am looking to optimize the Vue component where data is received in varying structures. Take for example Appointment.vue component: <template> <div> <div v-if="config.data.user.user_id"> {{ config.data.user.user_id ...

What is the reason behind these sinon stubs returning undefined values?

I have created a unit test for this code snippet and used Sinon to stub the browser methods (specifically with sinon-chrome, an older but still functional library that suits my needs). /** * Returns an array of languages based on getAcceptLanguages and ge ...

Retrieving the output from a nested function within a function in a Node.js application connected to a

I'm currently working on a basic web application that interacts with a database by performing INSERT and SELECT operations on a single table. While I have utilized a function from various tutorials, I am struggling to retrieve the results from the SEL ...

Ajax cannot seem to come to a resolution

After completing my learning on Ajax, I decided to work on a simple project - a port scanner. However, I am facing issues with it as it is not working properly. The only message that pops up is 'Scan started' and I can't figure out what the ...

Effectively encoding and decoding AJAX and JSON objects with PHP scripting

I've successfully set up a basic HTML file with a fixed JSON object. My goal is to transfer this object to a PHP file named text.php, encode it, decode it, display it in the PHP file, and then showcase it back in the HTML file. <!DOCTYPE html> ...

The reason why setting height to 0 is ineffective in a CSS definition

Within my current project, I am utilizing vue.js 2 and have implemented an img component. Below is the code for this component: <template> <div class="banner"> <img class="banner-img" :src="bannerImg"/> </div> </template> ...

Using either Canvas.toBlob or Canvas.toDataURL results in me obtaining an image with a transparent

Hey there! I'm currently working on a project that requires the user to crop and upload images. For cropping, I am utilizing react-cropper. My challenge lies in dealing with Chrome's limitation on dataURL to 65529 pixels as mentioned in this M ...

Keep track of the user's email address as they complete the form

I currently use a Google Form to gather information from employees who work in remote locations Emp No * Punch * Customer details / mode or travel All the data collected is stored in a Google spreadsheet structured as follows: Timestamp Emp No Punch ...

Collaborate on React-Native components together!

As a newcomer to the world of react, react-native, and nodejs, I embarked on creating my own node module using npm init. Within this module, I developed a component for styling buttons, packaging it with npm pack and linking it in my application's pac ...

Error: Unable to locate module - Invalid generator instance detected. The Asset Modules Plugin has been started with a generator object that does not adhere to the API standards

Encountering an issue in nextjs when utilizing the 'asset/inline' Asset Module Type within a custom webpack configuration while running yarn dev. I attempted to utilize the 'asset/inline' asset module type to output the URI of the impor ...

Enlarging and cutting video footage

I have developed an app that features a code enabling users to capture photos using their computer-connected camera. How it Works: A webcam is utilized to display a video element with the camera as its source: function onSuccess (stream) { this.video.s ...

Having trouble with the JavaScript code for a basic GPA calculator?

I am having issues with my code for a basic grade calculator. Even though I can input numbers, the final grade is not displayed on the screen. Can someone please help me identify what mistake I might be making? Please ignore the Japanese text, as it's ...

What are the steps to making a textfield editable with JavaScript and HTML?

My textfield is currently populated with values from the database and is functioning perfectly. I would like to implement a checkbox feature that, when clicked, will clear the textfield of the database values, allowing the user to input new values. If t ...

Navigating AJAX Pages - Maximize the Potential of #home and Other Sections

I am working on creating AJAX pages using a tutorial I found on Tutorialzine. The script I am using loads pages using AJAX but it requires specifying the page number in the URL like http://example.com/#page1 or http://example.com/#page2. Is there a way t ...

Experience the latest HTML5 features directly within a Java desktop GUI, with seamless communication through

This Java desktop GUI utilizes a Java-based web services communication layer along with an HTML library to provide powerful charting and interactivity. I am looking to integrate an HTML5 view within the Java GUI. Can someone assist me in managing JavaScri ...