Tips for implementing a distinct texture on child elements through traversal techniques

My current dilemma involves working with an object that I've loaded using THREE.ObjectLoader(). This object consists of various elements, resembling a simple box made up of panels and sticks.

My goal is to assign different textures to specific child objects within this loaded object.

However, I'm encountering a problem where all the textures of the object (material.map) are being overwritten by the last texture set in the loop. Here's an example of the code:

var objectLoader = new THREE.ObjectLoader();
objectLoader.load("carport-scene-nocolor.json", function ( object ) {

    var textureLoader = new THREE.TextureLoader();
    var glass = textureLoader.load('glass2.jpg');
    var crate = textureLoader.load('crate.gif');

    object.traverse( function ( child )
    {
        child.receiveShadow = true;
        child.castShadow = true;

        if ( child instanceof THREE.Mesh ) { 
            console.log(child.name);

            child.material.shininess = 100;
            child.material.wireframe = false;
            child.material.normalScale = new THREE.Vector2( 1, 1 );

            if( child.name === 'wooden_slats3' ) {
                child.material.map = glass;
                child.material.needsUpdate = true;
            } else {
                child.material.map = crate;
                child.material.needsUpdate = true;
            }
        }
    });
    object.position.y = -1;
    object.position.x = 0;
    object.receiveShadow = true;
    object.castShadow = true;

    scene.add( object );
    scene.fog = new THREE.Fog( 0xffffff, 50, 100 );
} );

Upon inspecting the console output, I noticed that the last element in the traverse loop is named 'wooden_slats4'. Despite expecting 'wooden_slats3' to have a 'glass' texture, all elements end up with the 'crate' texture map.

Attempting to modify the if statement to child.name === 'wooden_slats4' only results in all objects being assigned that texture, as it's the last child in the object.

While I initially suspected an issue with how object.traverse functions, my research indicates that my approach is sound.

For your reference, the console output shows:

pCube1
pCube2
pCube3
pCube4
wooden_slats2
wooden_slats3
wooden_slats4

Any assistance would be greatly appreciated.

Answer №1

It seems that when you edit child.material, you are actually editing the global material and not just that specific child/JS object.

To solve this issue, I had to clone the child's material and apply the cloned version instead:

var objectLoader = new THREE.ObjectLoader();
objectLoader.load("carport-scene-nocolor.json", function ( object ) {

    var textureLoader = new THREE.TextureLoader();
    var glass = textureLoader.load('glass2.jpg');
    var crate = textureLoader.load('crate.gif');

    object.traverse( function ( child )
    {
        if ( child instanceof THREE.Mesh ) { 
            console.log(child.name);

            var material = child.material.clone();

            material.shininess = 100;
            material.wireframe = false;
            material.normalScale = new THREE.Vector2( 1, 1 );

            if( child.name === 'wooden_slats3' ) {
                material.map = glass;
            } else {
                material.map = crate;
            }
            child.material = material;
        }
    });
    object.position.y = -1;
    object.position.x = 0;
    object.receiveShadow = true;
    object.castShadow = true;

    scene.add( object );
    scene.fog = new THREE.Fog( 0xffffff, 50, 100 );
} );

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

"Implementing the Three.js OBJloader feature with the enhanced functionality of

I'm looking to create a simple 3D model viewer with rotation capabilities, but I've run into an issue. When I add OrbitControls to my code, the page just shows up as blank: controls = new THREE.OrbitControls( camera ); controls.addEventListener( ...

The function of hasClass within an if statement appears to be malfunctioning

I'm struggling to figure out why my .hasClass function is not functioning correctly. I've implemented the Quick Search jQuery plugin, and below is the code I am using: <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.mi ...

Tips for adding text to your d3 force layout

Looking to incorporate text into a force layout using SVG. I've created an svg group and added a circle successfully, but having trouble with the text. Here's the code snippet: var node = svg.selectAll("g") .data(measures.nod ...

Improving functions in vue.js

Currently working on my personal project, which is an HTML website containing tables generated through vue.js. I believe that my code could be simplified by refactoring it, but I am unsure about where and what changes to make. Below is the section of the c ...

When using Asp.Net TextBox, the focus is lost after inputting the first character

I have created an Asp.Net web form (aspx) that includes a TextBox: <div id="field"> <asp:TextBox Id="Name" runat="server" MaxLength="50"/> </div> Whenever I type characters into the TextBox, I t ...

Utilizing Prototype in Node.js Modules

Currently, I am working on a project involving multiple vendor-specific files in node. These files all follow a similar controller pattern, so it would be more efficient for me to extract them and consolidate them into a single common file. If you're ...

Changing the tooltip background color in FullCalendar 6 and Bootstrap 5: A step-by-step guide

My FullCalendar agenda displays events with colored backgrounds. However, I want the tooltips for these events to have matching background colors as well. Currently, the tooltips always show up with a black background. Is there a way to dynamically change ...

What is the best way to refresh the script located within the head tag of an index.html file in an Angular

I've been looking for solutions, but I can't seem to find one. In my index.html file, I've placed some script within the head tag (even above the </body> tag) and included a $(document).ready function. The issue I'm facing is th ...

beforeunload event confirmation prompt

I am currently working with Laravel and Vue.js to create a multi-step wizard. Within this wizard, I have implemented the onbeforeunload event to prevent any unwanted actions by displaying a confirmation message. However, I am encountering an issue where th ...

Angular.js: automatically select default option based on ID

In my angular.js single page application, I am retrieving initial data from a rest endpoint. The data consists of a list of IDs representing saved models and a tree of options for cascading dropdowns. How can I automatically set the default path in the t ...

Deactivating Cluetip tool tips and adjusting the height limit in JQuery

How can I momentarily turn off the hints? I have seen references to being able to do so on the website and in this forum, but I am having trouble locating the command to disable them. I just need to temporarily deactivate them and then enable them again. ...

Why Changing the Width of a Flexbox Container Doesn't Impact Its Children?

Attempting to use TweenLite to animate the width of the blue sidebar down to zero, however facing an issue where the content breaks outside the parent's bounds. https://i.stack.imgur.com/4rEVr.png It is unusual for this to happen with Flexbox, given ...

When working with a JavaScript array of class objects, it may appear as though the array is empty when it

Currently puzzled by the behavior of this array. Despite my efforts to find an answer, I haven't had any luck so far. I initialize var allMenuItems = []; at the top and then in getMenuItems(), I push multiple new class objects. However, when I call co ...

When using AngularJS $http to send an object as a JSON key to a Spring controller, the returned value

I am attempting to transmit a json object from javascript to the Spring controller. My method of choice is using angularJs $http post for this. The issue arises when I send the key as object, with the lastName showing up as null. Strangely, if I send the s ...

What could be causing the HTML5 canvas not to show up on the screen?

<!doctype html> <html> <head> <title>Canvas test</title> </head> <body> <script type="text/javascript"> c = getElementById('canvas'); ctx = c.getContext("2d")' ctx.fillRect(10,10,10,10); </s ...

What is the best way to send file data using the form-data format in Postman with React?

When I first started working with React, I encountered the need to transmit data from the frontend to the backend using an API. The data was in the form of form-data from POSTMAN, as shown in the image below. https://i.sstatic.net/U9QMe.png I opted to us ...

Establish validation parameters for uploading multiple files

I need to implement client-side validation for my FileUpload control to ensure that users can only select up to 10 images. While I already have the server-side code in place, I now want to add client-side validation as well. Sample Code: <asp:FileUplo ...

What is the reason for requiring shaders to reside in an HTML file for a WebGL program?

In a recent forum thread, an individual posed the question about how to eliminate shaders from html. The discussion revolved around finding alternatives to embedding shaders in webGL code: WebGL - is there an alternative to embedding shaders in HTML? The ...

If there are multiple instances of the component, it may not function properly

I have implemented a Vue component as shown below: <script setup lang="ts"> import { PropType } from "nuxt/dist/app/compat/capi"; interface Star { id: string; value: number; } const stars: Star[] = [ { id: &qu ...

Swap out the old nested array for a fresh array

Currently, I am dealing with an array nested inside another array. The structure looks like this: Structure: First Array [ { Second Array [ { } ] } ] I am attempting to replace all instances of Second Array with a new array that I have cr ...