Utilizing multiple materials with a single mesh in three.js: A comprehensive guide

I am facing a major issue with three.js:

My goal is to create a simple cube with different colors on each face. I attempted to achieve this using the following code snippet:

// set the scene size
    var WIDTH = jQuery('#showcase').width() - 20, HEIGHT = jQuery('#showcase').height();

    // set some camera attributes
    var VIEW_ANGLE = 45, ASPECT = WIDTH / HEIGHT, NEAR = 0.1, FAR = 10000000;

    this.container = jQuery('#showcase');

    this.renderer = new THREE.WebGLRenderer();
    this.camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR);
    this.scene = new THREE.Scene();
    this.scene.add(this.camera);

    // camera start position
    this.camera.position.z = this.model.radius;
    this.camera.position.y = this.model.cameraY;
    this.camera.position.x = 0;
    this.camera.lookAt(this.scene.position);

    this.renderer.setSize(WIDTH, HEIGHT);
    this.container.append(this.renderer.domElement);

    //Multiple Colors
    var materials = [new THREE.MeshBasicMaterial({
        color : 0xFF0000
    }), new THREE.MeshBasicMaterial({
        color : 0x00FF00
    }), new THREE.MeshBasicMaterial({
        color : 0x0000FF
    }), new THREE.MeshBasicMaterial({
        color : 0xAA0000
    }), new THREE.MeshBasicMaterial({
        color : 0x00AA00
    }), new THREE.MeshBasicMaterial({
        color : 0x0000AA
    })];

    this.geometry = new THREE.CubeGeometry(100, 100, 100, materials);

    this.mesh = new THREE.Mesh(this.geometry,  new THREE.MeshFaceMaterial());

    this.scene.add(this.mesh);

    // create a point light
    this.pointLight = new THREE.PointLight(0xFFFFFF);
    this.pointLight.position = this.scene.position;
    this.scene.add(this.pointLight);

    this.renderer.render(this.scene, this.camera);

Unfortunately, I encountered the following error message: "Uncaught TypeError: Cannot read property 'map' of undefined" from line 19152 in three.js.

It appears to be an issue related to the WebGL renderer. Most resources I found suggested using the canvas renderer instead. However, I prefer to use the webgl renderer.

Does anyone have any insights or suggestions to resolve this problem? Thank you:-)

Answer №1

Here is a suggested solution

this.geometry = createCubeGeometry(100, 100, 100);
this.mesh = addMeshToScene(this.geometry, new Material());

Answer №2

Perhaps consider utilizing an array in your code.

In my experience with three.js version 49 (not sure if it applies to version 57), I successfully implemented this script for creating a skybox with multiple materials:

var axes = new THREE.AxisHelper();
scene.add(axes);

var materialArray = [];
materialArray.push(new THREE.MeshBasicMaterial({ map: THREE.ImageUtils.loadTexture('textures/himmel.jpg') }));
materialArray.push(new THREE.MeshBasicMaterial({ map: THREE.ImageUtils.loadTexture('textures/himmel.jpg') }));
materialArray.push(new THREE.MeshBasicMaterial({ map: THREE.ImageUtils.loadTexture('textures/himmel.jpg') }));
materialArray.push(new THREE.MeshBasicMaterial({ map: THREE.ImageUtils.loadTexture('textures/himmel.jpg') }));
materialArray.push(new THREE.MeshBasicMaterial({ map: THREE.ImageUtils.loadTexture('textures/himmel.jpg') }));
materialArray.push(new THREE.MeshBasicMaterial({ map: THREE.ImageUtils.loadTexture('textures/himmel.jpg') }));
var skyboxGeom = new THREE.CubeGeometry(5000, 5000, 5000, 1, 1, 1, materialArray);
var skybox = new THREE.Mesh(skyboxGeom, new THREE.MeshFaceMaterial());
skybox.flipSided = true;
scene.add(skybox);

Answer №3

Here is another method to try, utilizing the vertex colors feature.

let geometry = new THREE.BoxGeometry(20, 20, 20);
let faceIndices = ['a', 'b', 'c'];
let vertexIndex, point;
material = new THREE.MeshBasicMaterial({
vertexColors: THREE.VertexColors
});
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
geometry.faces.forEach(function (face) { // iterate through faces
for (let i = 0; i < 3; i++) {
vertexIndex = face[ faceIndices]; 
point = geometry.vertices[vertexIndex]; 
color = new THREE.Color(
point.x + 0.5, 
point.y + 0.5,
point.z + 0.5
);
face.vertexColors[ i ] = color; 
}
});

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 combine the average hours, minutes, seconds, and milliseconds in JavaScript?

I am seeking guidance on how to calculate the average of three different times in JavaScript. In the scenario presented below, the average of the three times is calculated as 01:42:22:566. <form action="/action_page.php"> <label for= ...

Traverse through an array or object using recursive render functions in JavaScript

Here is an example of the issue I am currently trying to solve: https://codepen.io/wombsplitter/pen/KyWKod This is the structure of my array: [{ //obj 1 link: [{ //obj 2 link: [{ //obj 3 }] }] }] The ...

Monitoring and recording every server-side interaction within the AngularJS user interface

Is there a way to efficiently display all server side REST actions on the angular js UI of my application? For example, how can I immediately show a message on the GUI when a user is created or when an action fails? I currently store all such actions in a ...

Issue with Angular and Karma: HTTP GET request not running

Currently, I am working on an AngularJS project that utilizes Karma to execute some unit tests directly in the browser. To conduct these tests, I have opted for mocha as the test framework. The challenge I am facing lies in running specification tests tha ...

Extract the JSESSIONID and generate a new Cookie using AngularJS

Currently, I am utilizing a Web RESTful API from my client within AngularJS. app.controller('LoginController', [ '$http', '$cookies', function($http, $cookies) { this.credentials = {}; this.http = $ ...

Guide to effectively utilizing jQuery Deferred within a loop

I have been working on a function that needs to loop through a dataset, updating values as it goes along using data from an asynchronous function. It is crucial for me to know when this function finishes running the loop and completes all updates. Here is ...

Convert the JSON data received from a jQuery AJAX call into a visually appealing HTML table

Utilizing AJAX as the action, I have created a search form. In the success of the AJAX request, I am seeking a way to update a specific div without refreshing the entire page. Below is my form: <?php $properties = array('id' => &ap ...

Innovative ways to design a responsive carousel with Bootstrap

My goal was to create a slider with divisions inside a bootsrap carousel, and here is what I did. However, I am looking for guidance on how to adjust it so that on screens smaller than sm (of bootstrap), there are only two divisions in one carousel, and a ...

The error message states: "change is not defined"

I am encountering an issue where I have 4 input boxes triggering a function on keyup using the onkeyup event. Strangely, I keep receiving an error stating that "change" (the function's name) is not defined. Despite correctly defining the function, I c ...

Implementing dynamic data binding in JavaScript templates

I've been experimenting with jQuery and templates, and I managed to create a basic template binding system: <script type="text/template" id="Template"> <div>{0}</div> </script> Furthermore... var buffer = ''; v ...

Is there a way to retrieve the filename from a callback in gulp-contains?

Currently, I am utilizing gulp-contains to scan for a specific string. If the target string is found, I intend to trigger an error message stating "String found in file abc." The 'file' parameter holds the entire object comprising filename + Buff ...

What are some tips for utilizing the "bottom-row" slot within the "b-table" component in bootstrap-vue?

I am working on a component that utilizes the bootstrap-vue b-table component. My goal is to create a bottom row that displays the sum of each column in the table. However, I encountered an issue where the bottom-row only fills the first column, leaving ...

Updating Documents in CouchDB

Can you please confirm if this is the correct method for updating a document in couchDB? To update a document (let's call it fooDoc), I must pass "_rev". First, I need to retrieve that document using the following code (foo.get). Then, in the callbac ...

Presentation - hyperlink only functioning for final slide

I have a question about Lean Slider, which you can check out at My goal is to link each slide to a different URL. However, I'm facing an issue where only the code in the last slide seems to be executed and applied to all other slides. For example, if ...

Storing information in a PHP database

I have created two pop-up divs on my website. Initially, the first div - div1, is displayed and it contains dropdown menus. Inside this div1, there is a button called Next which, when clicked, closes the first div and opens the second div; div2. Div2 consi ...

Tips for preventing the ng-click event of a table row from being triggered when you specifically want to activate the ng-click event of a checkbox

So, I've got this situation where when clicking on a Table Row, it opens a modal thanks to ng-click. <tr ng-repeat="cpPortfolioItem in cpPortfolioTitles" ng-click="viewIndividualDetailsByTitle(cpPortfolioItem)"> But now, there&apos ...

Utilize Autocomplete component from Material UI to sift through distinct option values

Looking to implement unique options in the dropdown menu of an Autocomplete component from Material UI based on a specific property within a list of objects. The current issue is that duplicate values are appearing in the dropdown, like ['Color1&apos ...

How can AngularJS handle multiple views sharing the same controller and ensure that the controller is executed only once?

Currently, I am facing a situation where I have two separate views that I would like to control within a single controller. The issue is, the controller is being executed twice. Is there a way to link multiple views to the same controller without the cont ...

Tips on adjusting the flexibility of videojs markers for sliding or moving

I need assistance in making my markers movable along with the seek bar. I want them to be as slideable as the jqueryui-slider. Question: How can I make both of my markers movable like the jqueryui-range slider shown below the video in the example code? ...

Displaying HTML content from a Vuejs response within a Dialog box

After receiving a response from the server via a REST request in HTML format, I have saved it in a data:[] variable. When I log this data on the console, it appears as raw HTML code. This reply is currently stored as a String, and my challenge now is to co ...