Search code examples
javascriptthree.jshtml5-canvas

Three JS Material Not Being Assigned To Mesh Object


this is my glass material

const glassMaterial = new THREE.MeshPhysicalMaterial( {
    // color: 0xffffff, metalness: 0.25, roughness: 0, transmission: 1.0
    color: 0xffffff,
    metalness: 0.25,
    roughness: 0,
    transmission: 1.0,
    transparent: true, // Enable transparency
    opacity: 0.8,
});

this is my code to set the glass material of an object in my model

loader.load('model/bentley.glb', (gltf) => {
    const carModel = gltf.scene.children[ 0 ]; 
    carModel.getObjectByName( 'glassclear_headlights' ).material = glassMaterial; 
    scene.add(carModel);
})

the issue i am facing is that the object i've assigned the glass material stays flat like i changed nothing about it

I logged out the object and it showed me it was updated but it wasn't showing in my canvas

Object { isObject3D: true, uuid: "eb2f4654-2800-408f-b829-7e49494fd212", name: "glassclear_headlights", type: "Object3D", parent: {…}, children: (1) […], up: {…}, position: {…}, rotation: {…}, quaternion: {…}, … }
​
animations: Array []
​
castShadow: false
​
children: Array [ {…} ]
​
frustumCulled: true
​
id: 51
​
isObject3D: true
​
layers: Object { mask: 1 }
​
material: Object { isMaterial: true, uuid: "91872851-53c4-4da9-b8d2-9540e481fcee", type: "MeshPhysicalMaterial", … }
​
matrix: Object { elements: (16) […] }
​
matrixAutoUpdate: true
​
matrixWorld: Object { elements: (16) […] }
​
matrixWorldAutoUpdate: true
​
matrixWorldNeedsUpdate: false
​
modelViewMatrix: Object { elements: (16) […] }
​
name: "glassclear_headlights"
​
normalMatrix: Object { elements: (9) […] }
​
parent: Object { isObject3D: true, uuid: "235263eb-be35-43af-b161-0ad43b80bbc5", name: "BentleyContinentalGT_2018", … }
​
position: Object { x: -0.00019347667694091797, y: 2000.848388671875, z: -623.6005249023438 }
​
quaternion: Object { isQuaternion: true, _x: 0, _y: 0, … }
​
receiveShadow: false
​
renderOrder: 0
​
rotation: Object { isEuler: true, _x: 0, _y: 0, … }
​
scale: Object { x: 1, y: 1, z: 1 }
​
type: "Object3D"
​
up: Object { x: 0, y: 1, z: 0 }
​
userData: Object { name: "glassclear_headlights" }
​
uuid: "eb2f4654-2800-408f-b829-7e49494fd212"
​
visible: true
​
<prototype>: Object { … }

this is my complete code

import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { RGBELoader } from 'three/addons/loaders/RGBELoader.js';
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';

let controls;
const wheels = [];

// Get a reference to the canvas element
const canvas = document.getElementById('configurator');
const scene = new THREE.Scene();
scene.background = new THREE.Color( 0x333333 );
scene.environment = new RGBELoader().load( 'hdr/fouriesburg_mountain_lookout_2_1k.hdr' );
scene.environment.mapping = THREE.EquirectangularReflectionMapping;
scene.fog = new THREE.Fog( 0x333333, 10, 15 );
const camera = new THREE.PerspectiveCamera(40, canvas.clientWidth / canvas.clientHeight, 0.1, 100);
camera.position.set(0, 0.2, 5.5);

const renderer = new THREE.WebGLRenderer({ canvas: canvas, antialias: true, alpha: true  });
renderer.setSize(canvas.clientWidth, canvas.clientHeight);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;


// Create a circle geometry
const circleGeometry = new THREE.CircleGeometry(3, 64); 
const circleMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 }); 
const circleMesh = new THREE.Mesh(circleGeometry, circleMaterial);
circleMesh.position.set(0, -0.75, 0); 
circleMesh.rotation.x = -Math.PI / 2; 
scene.add(circleMesh);

// materials
const bodyMaterial = new THREE.MeshPhysicalMaterial( {
    color: 0xff0000, metalness: 1.0, roughness: 0.5, clearcoat: 1.0, clearcoatRoughness: 0.03
});

const glassMaterial = new THREE.MeshPhysicalMaterial( { 
    color: 0xffffff,
    metalness: 0.25,
    roughness: 0,
    transmission: 1.0,
    transparent: true, // Enable transparency
    opacity: 0.8,
});

const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath( 'jsm/libs/draco/gltf/' );

const loader = new GLTFLoader();
loader.setDRACOLoader( dracoLoader );

loader.load('model/bentley.glb', (gltf) => {
    const carModel = gltf.scene.children[ 0 ]; 

    carModel.getObjectByName( 'glassclear_headlights' ).material = glassMaterial; 
carModel.getObjectByName( 'carpaint_body' ).material = bodyMaterial;

scene.add(carModel);
});
controls = new OrbitControls(camera, canvas);
controls.enableDamping = true;
controls.dampingFactor = 0.1; 
controls.enablePan = false; 
controls.maxDistance = 6;
controls.minDistance = 4;
controls.maxPolarAngle = THREE.MathUtils.degToRad(90);
controls.target.set(0, 0.3, 0);
controls.rotateSpeed = 1.3;
controls.update();


const animate = () => {
    requestAnimationFrame(animate);
    renderer.render(scene, camera);
};
animate();

window.addEventListener('resize', () => {
    const newWidth = canvas.clientWidth;
    const newHeight = canvas.clientHeight;
    camera.aspect = newWidth / newHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(newWidth, newHeight);
});

any help would be much appreciated


Solution

  • The three.js object named by "glassclear_headlights" is not a Mesh. More likely, it's a parent of one or more meshes. You can traverse everything under that node and modify them as shown below:

    loader.load('model/bentley.glb', (gltf) => {
        const carModel = gltf.scene;
        const headlights = carModel.getObjectByName( 'glassclear_headlights' );
    
        headlights.traverse((object) => {
          if (object.isMesh) {
            object.material = ...;
          }
        });
    
        scene.add(carModel);
    })