Changing the color of a single mesh during rendering

My project consists of a grid with boxes, similar to the example seen at . I have implemented a hover state where the background turns gray when a box is hovered over. However, if there are multiple boxes on the grid and I try to change the background color of the hovered item, all boxes end up with a gray background.

Here is my current implementation:

var voxel = new THREE.Mesh( this.cubeGeometry, this.cubeMaterial );
voxel.position.copy( intersect.point ).add( intersect.face.normal );
voxel.position.divideScalar( 50 ).floor().multiplyScalar( 50 ).addScalar( 25 );
this.scene.add( voxel );
this.blocks.push( voxel );
var domEvents   = new THREEx.DomEvents(this.camera, this.renderer.domElement)
// DOM events for inside 3d rendering
domEvents.addEventListener(voxel, 'mouseover', this.onDocumentMouseOverCube.bind(this),false);
domEvents.addEventListener(voxel, 'mouseout', this.onDocumentMouseOutCube.bind(this),false);

We create the box and add event listeners specific to that mesh. When the mesh is hovered over, the mouseover function is executed:

this.mouse.x = ( event.origDomEvent.clientX / this.renderer.domElement.width ) * 2 - 1;
this.mouse.y = - ( event.origDomEvent.clientY / this.renderer.domElement.height ) * 2 + 1;

this.raycaster.setFromCamera( this.mouse, this.camera );
var intersects = this.raycaster.intersectObjects( this.blocks );
if ( intersects.length > 0 ) {

    var intersect = intersects[ 0 ];

    if ( intersect.object != this.plane ) {
        console.log(intersect.object);


        // update color on hover
        intersect.object.material.color.setHex(this.colorHover);
        console.log("hover color");
        this.render();
    }
}

While this functionality works correctly, the issue arises when render() is called (this.renderer.render(this.scene, this.camera)), as it changes the background color of every box instead of just the one that was hovered over. I have checked all objects and confirmed that only one box's color is being set, yet all boxes end up with the same color background. This leads me to believe that the problem lies in how the engine renders the scene.

Any suggestions on how to address this issue?

Answer №1

Each mesh shares a single instance of the material, but you can easily make each mesh have its own unique color by cloning the material:

var voxel = new THREE.Mesh( this.cubeGeometry, this.cubeMaterial.clone() );

This way, every box will display its individual color.


To possibly improve performance, consider using a custom shader material. By referencing the attributes and programs, you can share the ShaderMaterial between meshes with different uniform sets. Check out this post for more information: Three.js, sharing ShaderMaterial between meshes but with different uniform sets.

Here's an example code snippet:

var phongShader = THREE.ShaderLib.phong;
this.shaderMaterial = new THREE.ShaderMaterial({
    uniforms: phongShader.uniforms,
    vertexShader: phongShader.vertexShader,
    fragmentShader: phongShader.fragmentShader,
    lights:true
});
var voxel = new THREE.Mesh( this.cubeGeometry, this.shaderMaterial.clone() );

You can then modify the color using uniforms like this:

intersect.object.material.uniforms.diffuse.value.setHex( this.colorHover );

Based on Three.js r.71

PS: In my case, cloning the default Phong material in r.71 also resulted in only one program being displayed in the renderer info, suggesting that Three.js may be internally optimizing this.

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

Discover the proper technique to display an error message in cases where no data is detected during the filtering process

I'm currently working on a component that involves search filtering and dropdown filtering. The filtering functionality is working fine, but I'm struggling to determine where to display an error message if no data is found during the filtering pr ...

What is the best way to create a function that will only execute when the mouse is not hovering over a specific div?

My current code looks like this: function() { setInterval("getSearch()",10000); getSearch(); } ); However, I need to implement a functionality where the interval pauses if the mouse cursor hovers over a specific div on my ...

JavaScript - Automatic memory management following the execution of functions

After doing some research on garbage collection in JavaScript, I came across information stating that local variables of functions are collected once the function has returned (except for cyclical references which require breaking circles for the GC to fun ...

What is the mechanism behind flatMap executing code in a synchronous manner?

Currently, I am utilizing flatMap because it has the ability to process asynchronous code synchronously, allowing values from previous results to be handled one-by-one. However, I am unsure of how this functionality is achieved since the documentation does ...

The issue of Nodejs Messenger broadcast message functionality being inoperative

Trying to initiate a broadcast through my Facebook Messenger bot, I have implemented the following code: if (subscribe === true) { // Initiate HTTP request to Messenger Platform request({ "uri": "https://graph.facebook.com/v2.11/me/broadcast_messa ...

What are the steps to implement zone.js in your Angular application?

I am looking to utilize zone.js in my Angular project beyond just the runOutsideAngularZone function. My attempt to include it looked like this: import { zone } from 'zone.js'; Unfortunately, I encountered this error: error TS2306: File &apos ...

Having trouble getting HTML to render properly in React JS on localhost using Apache server

For the past week, I've been working on resolving an issue. I started by creating a React Application using: npm create react-app After that, I attempted to build it with: npm run build Everything seemed to go smoothly. I generated a build folder ...

Executing numerous queries in mongoDB

I need to query multiple collections in MongoDB. Here is an example of the data structure: Collection stops { { stop_id : 1, stop_name: 'a'}, { stop_id : 2, stop_name: 'b'}, ... Collection stop_time { { stop_id : 1, trip_i ...

Ways to add an emoji to my project similar to Facebook

How can I add a drop-down emoji menu to my website similar to Facebook's? ...

Revealing/disguising elements based on user input changes

I'm currently focused on implementing dynamic search functionality. My goal is to have the #Main div hidden and the #search_list div displayed whenever I type in the input field with the id #search. Also, if I use the keyboard shortcut Ctrl+A & B ...

Getting the value of a JSON object in CodeIgniter can be easily achieved by using the appropriate

My current project involves using the codeigniter framework to build a website. I am making an AJAX request with jQuery to retrieve data from the server. I have experimented with two different methods of receiving the data: one in a PHP associative array a ...

Ensure that you wait for the parent state to update before executing any additional functions

When calling a function that needs to perform two tasks: Execute a parent-level function to update the database by making a fetch request and then updating the state at the parent level Wait for the first function to complete updating the state, and then ...

What is the process by which a JavaScript Date object is converted to a string when you log it to the

Whenever I create objects in JavaScript and output them to the console, I typically see a JavaScript object displayed. For instance: var myObj = { bla: "foo" } console.log(myObj); This code will display: { bla: "foo" } However, whe ...

Incorporating External JavaScript and CSS specifically for a single component

In my Angular 4 application, I have a specific component that requires the use of a js and css file. While most guidelines suggest placing these files in the Index.html file, I prefer to only load them when this particular component is accessed, not on e ...

The function cannot be applied to the size of the map within the action payload

Is there a way to replace the for loop with the map method? The data structure for book.pages is in the format [{},{},{}] I tried using the size method and included this line console.log("book.pages.map.size();--->", book.pages.map.si ...

Generating an array of objects using Jquery from XML data

I need assistance with extracting data from XML text nodes stored in a variable and then creating an array of objects using jQuery. The XML data I have is as follows: var header = ['name', 'data1', 'data2']; var data = &apos ...

Error encountered: Unexpected syntax error found in jQuery ajax call

I am attempting to send a simple request to Instagram using the code snippet below: $.getJSON("https://www.instagram.com/kidsfromthe90sband/media/?callback=?", function(data) { alert(JSON.stringify(data)); }); http://jsfiddle.net/FPhcr/731/ ...

Use AJAX request to download file and handle errors in case the file is not found or cannot be downloaded

Trying to implement an ajax request for downloading a file. Here's the code snippet: const downloadFile = (element) => { $.ajax({ url: element.id, type: 'GET', success: (result) => { window.lo ...

Leveraging the content within <h4> tags in a React application

Child import React, {Component} from 'react' class Card extends Component { render() { let props = this.props; return( <div className="card-main"> <img src={`http://image.tmdb.org/t/p/w342/${props.path}`} alt="P ...

Separating ReactJS methods and useState functionality into their own files is a best practice for organizing

One of my components is called Invoice.js, which currently has over 1000 lines of code. I am looking to extract certain methods and their related useState functionality into a separate file. Within this component, there is an array named items that gets f ...