What is the best method for incorporating two materials into a mesh that has already been rendered on the canvas?

I've been experimenting with adding both color and an image to a Three.js Mesh after it's already been rendered on the canvas. From what I understand, if I use the same material with both color and a map, they will blend together and there's no way to prevent that. For example, if I have a white image and add a yellow color, the color will tint the image yellow:

let material = new THREE.MeshLambertMaterial({
               map: canvasTexture,
               color: 0xCECECE
               });

To work around this issue, I'm attempting to apply two separate materials to the mesh. One for the color and one for the image:

let material0 = new THREE.MeshLambertMaterial({
                color: 0xCECECE
                });

let material1 = new THREE.MeshLambertMaterial({
                map: canvasTexture
              });

var materials = [material0, material1];

mesh.material = materials;

Currently, when I try to set the mesh material to the array of materials, the mesh appears blank as if it's not accepting the array as a parameter. Even though the Three.js documentation states that it accepts an array of materials

Another potential issue I foresee is the default white color that may be applied to the material with just an image, thereby hiding the color of the material underneath.

So, how can I apply both an image and a color to a mesh material without them blending together? Adding two materials seems overly complex to me and could be challenging to manage in the long run.

UPDATE I discovered that the issue was with the texture I was using, which was a canvas texture. I needed to set the fill style of the canvas used in the canvas texture to be opaque. Something like:

ctx.fillStyle = "rgba(255, 255, 255, 0)";

After making this change, I was able to successfully add multiple materials to the mesh. The material using the canvas texture as the map had to be set to transparent. I also had to set the map.minfilter to be THREE.LinearFilter. I'm not sure why, but at least it's now functioning as intended :)

let material0 = new THREE.MeshLambertMaterial({
    color: 0xf2f2f2
});

let material1 = new THREE.MeshLambertMaterial({
    map: canvasTexture,
    transparent: true
});
material1.map.minFilter = THREE.LinearFilter;

var materials = [material1, material0];
mesh.geometry.clearGroups();
mesh.geometry.addGroup( 0, 48, 0 ); 
mesh.geometry.addGroup( 0, 48, 1 ); 
mesh.material = materials;

I hope this explanation can be helpful to someone else facing a similar challenge.

Answer №1

When attempting to assign the mesh material as the materials array, it appears to go blank as if it does not accept the array as a parameter.

This issue may arise due to your geometry lacking any groups data, which is necessary for utilizing multiple materials.

For instance, if you have a white image and a yellow color, the color will tint the image yellow.

Such behavior is to be expected, as the material color is combined with the color value from the diffuse texture. An alternative default behavior would not be logical.

How can I set the image and color of a mesh material without them blending together?

If you wish to apply different materials to different parts of the mesh, define group data for the respective geometry and use multiple materials. Alternatively, you can duplicate the mesh and assign a different material to each copy. By adding the duplicate to the original mesh (mesh.add( copy )), you can keep both in the same position.

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

Error: Unexpected character 'o' encountered in AngularJS syntax

Whenever I try to call this controller, it gives me an error. hiren.controller('hirenz' , function($scope , $http , $location , $routeParams){ $http.post((rootURL + "music") , {'alpha' : $routeParams.alpha , 'name' : $rou ...

Tips for conducting remote testing with the help of WebARonARKit and three.ar.js

Currently working on creating an iPad app using WebARonARKit in combination with three.ar.js. Successfully managed to get the demo projects up and running on my iPad. Seeking advice on how to test my personalized code on my desktop browser while actively ...

Tips for creating fonts that adjust depending on the length of characters

Is there a way to adjust the font size of a paragraph based on the space available in its containing div, depending on the length of characters? For instance: p{ font-size:15px; } <div class="caption"> <p>Lorem ipsum dolor sit amet, consect ...

What is the process for retrieving data on the server side using node.js that has been sent from the frontend via the post method

After diving into learning node.js with the express framework, I encountered a roadblock. I'm experimenting with a basic query search webapp and trying to send some data (a boolean named all) from front-end plain javascript via ajax to the server sid ...

What is the process for accessing the mesh in Aframe when a 3D object is loaded dynamically?

Is there a way to access mesh information of a 3D object loaded at runtime in Aframe? My method for loading the 3D model is as follows: targetObj = document.createElement('a-obj-model'); targetObj.setAttribute('gltf-model', '#wha ...

How can I make a drop-down field in AngularJS show the current value after populating options in a select control using ng-options?

This conversation centers around an app that can be visualized as, https://i.stack.imgur.com/Y1Nvv.png When a user clicks on one of the stories on the left side, the corresponding content is displayed on the right-hand side. Each story includes a title ...

What is the best way to animate a three.js object to the right using GSAP without obstructing the surrounding HTML text?

As a newcomer to web design, I seek forgiveness if my question appears basic. I am working on an animated object in three.js that I want to move to the left side of the screen using GSAP. Additionally, I have a text "Hello" on the left side of the screen. ...

From where does the require.js file originate?

Currently, I am learning Angular 2 from the tutorial available at https://github.com/pkaul/maven-typescript-example. Once I proceed with the 3rd step (mvn jetty:run), a runnable war folder is generated in the example-webapp/target directory. However, I ha ...

Validation of form inputs does not occur during typing, only when the input is blurred

Currently, I have implemented a combobox with input data validation using Vuelidate: <template> <v-combobox clearable v-model="surname" :items="commonSurnames" label="Surname" ...

ReactJS Modal popping up repeatedly while inside a loop

Hey there, I've been experimenting with ReactJS and came across this amazing Modal Component for opening videos in a modal. However, I encountered an issue when placing the Modal inside a loop with multiple links - it opens multiple times correspondin ...

No data appears to be populating the Javascript data list, yet no errors are being displayed in

I'm facing an issue where I have data that I'm using to create two arrays, but they both end up empty without any errors in the console. Below is the data: mydata = { "id": "661", "name": "some name", "description": "some desc", ...

Understanding the sequence of operations in Javascript using setTimeout()

If I have the following code: function testA { setTimeout('testB()', 1000); doLong(); } function testB { doSomething(); } function doLong() { //takes a few seconds to do something } When I run testA(), what happens after 1000 mill ...

Implementing Ajax Like Button functionality in a Ruby on Rails application

I have a Ruby on Rails project that includes a User model and a Content model, among others. I recently implemented a feature where users can "like" content using the acts_as_votable gem. Currently, the liking functionality works as expected but it requir ...

Managing array elements in React: removing and duplicating items

One of my tasks is to incorporate a copy and delete button within a table. My goal is to pass the index from the map to the delete and copy onclick functions, however, I am encountering an issue where copying a row results in it having the same index as th ...

The Safari 7.1+ browser seems to be having trouble with the spotlight effect

Why is the CodePen not functioning properly in Safari? Despite working well in Chrome and Firefox, it completely fails to work in Safari 7.1+. Can anyone provide some insights? http://codepen.io/cchambers/pen/Dyldj $(document).on("mousemove", function( ...

Exploring the power of Selenium Webdriver in combination with JavaScript

Can someone help me figure out why I'm getting this error message: "Exception in thread "main" java.lang.ClassCastException: java.lang.Long cannot be cast to org.openqa.selenium.WebElement at canvasdrag.Canvas.main(Canvas.java:57)" WebElement elemen ...

Duplicate the LI element in a way that it is inserted after the original LI instead of at the end

I am looking for a way to clone an item immediately after clicking on it instead of cloning it at the end of the list. Currently, it always clones to the END and adds it after the last LI in the list. Here is a link to the jsFiddle I created jsfiddle test ...

Encountering issues with proper function of history.listen within React Router

I am struggling to get my function to work every time React detects a change in the URL. The history.listen method is not triggering (the console.log statement is not showing up). I have read that this issue may be related to using BrowserRouter, but when ...

Utilize the data storage API within Next.js or directly in the user's

Struggling to store this ini file on either the server or client, any help would be greatly appreciated. Additionally, I would like to display the ini info in the browser so that clients can easily copy and paste the information. However, I seem to be fac ...

Issue with swal() not triggering in Internet Explorer 11

Looking for some assistance here, I believe I might be missing a small detail. The _layout.cshtml file includes all the necessary scripts to ensure that sweetheart works on IE: (this used to work in previous versions, but we haven't had to support I ...