Is there a way to modify the material of individual objects in THREE.js without creating separate Meshes?

We have developed a unique PCB Viewer using THREE.js, but now we want to enhance it with selection functionality. While the task itself isn't complex and I have managed to make it work, I am encountering performance challenges. Our goal is to allow users to individually select and click on different features of the PCB layers, causing their colors to change. To achieve this, I decided to assign each shape its own THREE.js Mesh so we can control their Materials independently. The outcome was successful, but the drawback is the significant drop in performance due to having thousands of separate meshes instead of one combined mesh for all shapes on a layer.

I am aware that having numerous meshes impacts performance negatively. So, my question is, are there any suggestions on how to improve the efficiency of this process? Currently, our main focus is only on changing the colors of individual shapes when clicked. Initially, before modifying my code, all shapes were contained within the same geometry under a single THREE Mesh. Is there a way to maintain this simpler structure while still being able to manipulate individual shapes or objects separately? It may seem like a stretch, but as someone who lacks extensive experience in working with THREE.js, I am open to any insights or advice

Answer №1

The key factor in cost is not simply the number of meshes, but rather the number of draw calls. Each draw call includes a set of geometry (defined by THREE.Geometry) and a shader program (defined by THREE.Material). Even if three.js supports multiple materials per mesh, the draw call quantity remains constant, so that solution alone will not address your issue.

Perhaps what you truly require is to manipulate abstract 'objects' without needing distinct instances of THREE.Mesh and THREE.Material for each one. For instance, when knowing the range of selected vertices, you could alter the vertex colors to highlight an object or adjust their positions to move it.

Another approach could involve assigning an original object ID as a vertex attribute for each entity, enabling you to utilize a personalized shader material to implement specific modifications to the material for differing objects.

For reference, check out this example:

Answer №2

After some experimentation, I came up with this approach:

  • I decided to display "basic" meshes in my actual scene, where numerous objects share the same geometry (primarily those with the same Material).
  • In a separate "fictional scene," which I don't actually render, I perform raycasting and collision checks. Here, each object has its own distinct mesh.
  • If there's a collision in the fictional scene, I duplicate that particular mesh object and place it in the real scene using the "selection material." Additionally, I slightly enlarge it to avoid z-fighting issues.
  • When deselecting objects, I remove the selection duplicates from the actual scene based on unique attributes assigned to each one. Each duplicate also retains a reference to the original mesh from the fictional scene, making it easy to identify pre-existing selections.
  • To determine where in the real scene an object should be placed (considering our complex tree structure), I utilize a user attribute in the fictional scene that indicates the parent node in the real world to which the selection duplicate should be added if selected.

Hopefully, this explanation is clear and beneficial for others facing similar challenges.

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

Create a self-bot that can generate a new server

I am currently working on a discord.js self-bot and I need assistance in creating a server. Any guidance would be greatly appreciated. I have experimented with the client.user method, but did not achieve the desired result. If it is not possible to c ...

Issue with updating state in SideBar.js following button click in Layout.js

Layout.js - Inside this component, there's a button that triggers the sidebar to hide or show when clicked. 'use client' import { useRef } from 'react'; import './globals.css' import Menu from '@mui/icons-material/M ...

Encountering a lack of data in the request body when posting in Express.js

Here are my two attached files. I am encountering an empty response from req.body. Index.html file: <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQ ...

Sending information from the parent component to the child Bootstrap Modal in Angular 6

As a newcomer to Angular 6, I am facing challenges with passing data between components. I am trying to launch a child component bootstrap modal from the parent modal and need to pass a string parameter to the child modal component. Additionally, I want t ...

Having trouble loading HTML content from another file

Here is the code snippet in question: <script> var load = function load_home(){ document.getElementById("content").innerHTML='<object type="type/html" data="/linker/templates/button.html" ></object>'; } </script> ...

Enhance User Experience with a Responsive Website Dropdown Menu

Currently, I am focused on enhancing the responsiveness of my website and I realized that having a well-designed menu for mobile view is essential. To address this need, I added a button that only appears when the screen size is 480px or lower, which seems ...

Encountering the error message "Uncaught Error: [vuex] Getters must be functions, but 'getters.getters' is {}. This occurred while splitting the Vuex store into modules in Vue.js."

As a beginner in VUEX, I am experimenting with building a test application to dive deeper into the world of VUEX. I have organized my VUEX store into modules, where each module has its own getter.js file. Getters, actions, and mutations are imported into i ...

Provide the option to assign values on select options in order to choose specific JSON data

When working with JSON data from an API, I am creating a dynamic select element. The goal is to change some content (text and image src) based on the option selected from this select element. I have successfully populated the select options with names usi ...

Displaying checkbox values with JavaScript

How can I display multiple checkbox values when checked in HTML code? Whenever I check a checkbox, I want its value to be shown alongside the previously checked values. Right now, my code only displays one value at a time. Any suggestions on how to achie ...

When working with data in Angular, make sure to use any[] instead of any in app.component.html and app.component.ts to avoid causing overload errors

I'm new to working with Angular, specifically using Angular 15. I have a Rest API response that I need to parse and display in the UI using Angular. To achieve this, I employed the use of HttpClient for making GET requests and parsing the responses. ...

Monitoring the usage of a specific component's screen time in a React Application

Is it possible to accurately track the time a specific component is rendered with certain props and while being on an active screen in React? I've had trouble finding a suitable library for this task. What would be the most effective approach to tackl ...

The POST method functions properly in the local environment, however, it encounters a 405 (Method Not Allowed) error in the

After testing my code locally and encountering no issues, I uploaded it to Vercel only to run into the error 405 (Method Not Allowed) during the POST method. Despite checking everything thoroughly, I'm unable to find a solution on my own. Your assista ...

Tips for transmitting an array of Objects to AngularJS

Summary I'm curious about how I can successfully send the following array of objects from NodeJS to an AngularJS app. var players = [ Footer: { username: 'Footer', hp: 200, exp: 1 }, Barter: { username: 'Barter', hp: 200, e ...

Animating Divs with jQuery to Expand their Size

I am currently designing a services page for my portfolio website. The layout consists of three columns, with the central column containing a large box and the left and right columns each containing three smaller boxes. These smaller boxes function as clic ...

Ways to navigate through a webpage without encountering any overflow issues

My window is too small to scroll, but I still need the ability to do so. Is it possible to scroll even when the height of the container is not large enough to display the scrollbar? Below is the code I am using to achieve scrolling: setTimeout(function() ...

How to retrieve the chosen option from a drop-down menu in WebDriver using JavaScript without relying on the Select Class

Currently, I am in the process of utilizing Webdriver with Java. My goal is to retrieve the selected value from a combobox without relying on the Select class provided by Webdriver. The specific markup that I am dealing with is as follows: <select nam ...

Automatically navigate to the bottom of the page by applying the overflow auto feature

I've been working on a chat application using Vue.js. I have set the overflow property to auto for my div element. My goal is to automatically scroll to the bottom of the div so that users won't have to manually click the scrollbar to view the la ...

Examining REST API functionality through the use of a Console, requiring an integer list as a parameter

Currently, I am in the process of testing a REST API to perform an action that requires a list of integers. I am uncertain about how to correctly handle the parameters required for this test. In my request payload, I have included the following: idAttac ...

The video on Videojs fails to show up on the screen

Currently utilizing the most recent version of videojs. Referencing this example http://jsfiddle.net/swinginsam/NWbUG/#share Access source code Having trouble identifying the issue. <!DOCTYPE html> <html> <head> <title>Video.j ...

Enhancing Your Model with Additional Details using Angular Formly

I have been utilizing Angular Formly to display forms generated from the JSON response received from services. However, I have a few inquiries. Is it feasible to retrieve data in a field (templateOptions.label, for instance) to include in the model? ...