Create a new design of a Three.js element

After reviewing this particular example involving three.js for drawing particles with images, I found it to work flawlessly. However, I am interested in replacing the image by toggling it with a switch upon clicking a button. Here is the function for this purpose:


        const changeImg = function(num) {

        switch (num)
        {
            case 0:
                imgData = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA....";
            break;

            case 1:
                imgData = "data:image/png;base64,iVBORw0KGgoAAAAN...";
            break;
        }

        img.src = imgData;

        }
    

Although this approach works, I noticed that the website slows down upon multiple clicks. How can I efficiently update just the image without causing performance issues?

EDIT 1

Upon modifying the code as shown below:

And the THREE.WebGLRenderer is only applied once but when I click to change the image, it does not update and also I still have the problem that the website slows down

it's my first time using three js and i don't know if i'm applying well what it says in the documentation

EDIT 2

When I click to change the image, it does not update and also I still have the problem that the website slows down. I cahaged vertcies.push to vertices.vertices.push()

Answer №1

Instead of disposing of objects, let's focus on reusing them in a new approach.

particles - Integrate it into the scene immediately upon creation.

material - Assign it to particles right away; no need to constantly reassign it.

geometry - Avoid creating it globally; let it function within particles.

Our goal now is to update the vertices and notify three.js about the new data to upload to the GPU.

var drawTheMap = function() {

    let vertices = particles.geometry; // this serves as a REFERENCE!
    vertices.length = 0; // clears the vertices array

    for (var y = 0, y2 = imagedata.height; y < y2; y += 2) {
        for (var x = 0, x2 = imagedata.width; x < x2; x += 2) {
            if (imagedata.data[(x * 4 + y * 4 * imagedata.width)] < 128) {

                var vertex = new THREE.Vector3();
                vertex.x = x - imagedata.width / 2;
                vertex.y = -y + imagedata.height / 2;
                vertex.z = -Math.random()*500;

                vertex.speed = Math.random() / speed + 0.015;

                vertices.push(vertex);
            }
        }
    }

    particles.geometry.verticesNeedUpdate = true; // Notify three.js of the update

    requestAnimationFrame(render);
};

The crucial step here (aside from updating the vertices) is setting

particles.geometry.verticesNeedUpdate = true;
. This action prompts three.js to replace the vertices on the GPU. By reusing instead of recreating, the process should run smoothly.

Answer №2

To solve the issue, simply replace THREE.geometry with THREE.BufferGeometry

var updateMap = function() {
    particles.geometry = new THREE.BufferGeometry();
    var positions = [];

    for (var row = 0, rowEnd = imagedata.height; row < rowEnd; row += 2) {
        for (var col = 0, colEnd = imagedata.width; col < colEnd; col += 2) {
            if (imagedata.data[(col * 4 + row * 4 * imagedata.width)] < 128)  {

                positions.push(col - imagedata.width / 2);
                positions.push(-row + imagedata.height / 2);
                positions.push(-Math.random()*500);

                particles.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) );

            }
        }
    }
    
      particles.geometry.verticesNeedUpdate = true;

    requestAnimationFrame(render);
};

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

Issue with Typescript Application not navigating into the node_modules directory

After attempting to load the app from the root directory of our server, it became clear that this was not a practical solution due to the way our application uses pretty URLs. For instance, trying to access a page with a URL like http://www.website.com/mod ...

Tips for Customizing the Appearance of Material UI Select Popups

My React select component is functioning properly, but I am struggling to apply different background colors and fonts to the select options. https://i.stack.imgur.com/kAJDe.png Select Code <TextField fullWidth select size="small" nam ...

Is it the correct method to query names within JavaScript arrays?

I am looking to create a dynamic list view using React JS without relying on any pre-built components. My goal is to incorporate a basic search function that can find users by their names, and I need to address this issue... For example, I have drafted th ...

Display the menu and submenus by making a request with $.get()

My menu with submenu is generated in JSON format, but I am facing issues displaying it on an HTML page using the provided code. Can someone please assist me in identifying what mistakes I might be making? let HandleClass = function() { ...

Finding the distance between two points in JavaScript requires a simple formula

Here is a code snippet that generates two TRACER points and displays them on a map, as well as shows the union between the two points. <?php $latitudInicio = $_GET['latitudInicio']; $longitudInicio = $_GET['longitudInicio']; $latit ...

Uninterrupted jQuery AJAX calls

I have a scenario where I need to periodically update an image on my view using ajax every 10 seconds. Any suggestions on how I can achieve this? Appreciate the help. ...

Proper method for positioning text in a line

Trying to recreate the image below, but facing alignment issues with the text in my code. How can I vertically align the text so that they are aligned like in the photo? Flexbox hasn't helped due to varying text lengths causing misalignment. const ...

What is the best method to close a polygon infowindow when hovering over a map marker?

I am currently working on integrating Google Maps which includes a set of polygons representing state boundaries and markers representing cities within each polygon. I want to display information when hovering over a polygon/state. My question is: how can ...

Exploring the Module System of TypeScript

I am working with a TypeScript module structured like this: let function test(){ //... } export default test; My goal is for tsc to compile it in the following way: let function test(){ //... } module.exports = test; However, upon compilation, ...

Troubleshooting problem with resizing and links in IE11 for iframe-resizer

When using the iframe-resizer from https://github.com/davidjbradshaw/iframe-resizer, I have encountered a few issues. Upon resizing the browser window, I noticed that if I first restore down and then manually resize, some extra padding appears. The paddin ...

React NextJS: Unable to retrieve cookies or properties post redirection

Within my nextJS application, when a user logs in on the login page, a cookie is created with a token and then they are redirected to the main page which utilizes the main component. However, within the Main component, I am encountering an issue where the ...

Delay in loading Jquery accordion due to value binding

I've noticed that my jquery accordion takes a significant amount of time to collapse when the page initially loads. After some investigation, I realized that the issue lies in the fact that there are numerous multiselect listboxes within the accordio ...

Delivering a Logo to a Remote Website Based on Specific Conditions

I am in the process of creating a code snippet for a specific user group that has earned the privilege to display our seal on their website. The concept initially appeared straightforward, but when I attempted to implement it on a different site for testin ...

A collection of asynchronous requests stemming from a sole request

I am facing a unique ajax scenario that is proving to be quite challenging for me. Here is the specific sequence of events that I need to coordinate: An initial request returns an array of ID numbers. A separate request needs to be sent for each ID in ...

Vue alert: Issue with rendering - TypeError: Unable to access property 'NomeStr' as it is undefined

I'm having trouble displaying the 'NameSrt' item array value in my template, and I keep encountering this issue: vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in render: "TypeError: Cannot read property 'NomeStr' of undefined" The ...

Invoke the JavaScript function on the HTML button click event, sending the ASP parameter

Currently, I am working with node and passing a parameter in the following manner: res.render('page.ejs',{"product" : product }); The paramter 'product' is in JSON format. Within the 'page.ejs' file, I am attempting to call ...

Encountered difficulties sending JSON data to a REST endpoint using Node.js

Is there a way to bulk insert JSON data into MongoDB using Mongoose? I am aware of the insertMany method, but I'm encountering difficulties with extracting the correct req.body. Below is an image of my setup in Postman. https://i.sstatic.net/xFznd.pn ...

Guide to creating a unit test for canActivate guard in Angular routing

Seeking guidance on writing a unit test for angular routing with the canActivate guard. Encountering an error when using the guard on routes, but no error is thrown without it. Would appreciate a suitable example along with an explanation. app-routing.mod ...

Utilizing Array.from with a XPathResult: A Comprehensive Guide

In my sample document, I found 138 nodes with the tag td using querySelectorAll. Array.from(document.querySelectorAll('td')).length 138 However, when I tried to do the same using XPath, I did not get any result: Array.from(document.evaluate(". ...

Similar to LINQ's Enumerable.First(predicate) method but with a slightly different syntax, this

When working with JavaScript, we often encounter situations where we need to find the first matching element based on certain conditions. Take for example this code snippet: function process() { var firstMatch = ['a', 'b', 'c&ap ...