Danilo Vukovic
Danilo Vukovic

Reputation: 13

Can't change color of my 3D model with three.js

I have a 3D gltf model of a building which I'm trying to put on a Mapbox Map, but when using MeshPhongMaterial or any other variation it just won't change the color.

Everything else works except the color.

Here's my code:

        var modelOrigin = [17.1956,44.7871];
        var modelAltitude = 0;
        var modelRotate = [Math.PI / 2, 0, 0];
         
        var modelAsMercatorCoordinate = mapboxgl.MercatorCoordinate.fromLngLat(
        modelOrigin,
        modelAltitude
        );
         
        // transformation parameters to position, rotate and scale the 3D model onto the map
        var modelTransform = {
        translateX: modelAsMercatorCoordinate.x,
        translateY: modelAsMercatorCoordinate.y,
        translateZ: modelAsMercatorCoordinate.z,
        rotateX: modelRotate[0],
        rotateY: modelRotate[1],
        rotateZ: modelRotate[2],
        /* Since our 3D model is in real world meters, a scale transform needs to be
        * applied since the CustomLayerInterface expects units in MercatorCoordinates.
        */
        scale: modelAsMercatorCoordinate.meterInMercatorCoordinateUnits()
        };
         
        var THREE = window.THREE;
         
        // configuration of the custom layer for a 3D model per the CustomLayerInterface
        var customLayer = {
        id: '3d-model',
        type: 'custom',
        renderingMode: '3d',
        onAdd: function (map, gl) {
        this.camera = new THREE.Camera();
        this.scene = new THREE.Scene();
         
        // create two three.js lights to illuminate the model
        var directionalLight = new THREE.DirectionalLight(0xffffff);
        directionalLight.position.set(0, -70, 100).normalize();
        this.scene.add(directionalLight);
         
        var directionalLight2 = new THREE.DirectionalLight(0xffffff);
        directionalLight2.position.set(0, 70, 100).normalize();
        this.scene.add(directionalLight2);
         
        // use the three.js GLTF loader to add the 3D model to the three.js scene
        var loader = new THREE.GLTFLoader();
        loader.load(
        'Apartment Building_17_gltf.gltf',
        function (gltf) {
        this.scene.add(gltf.scene);
        }.bind(this)
        );
        this.map = map;


         
        // use the Mapbox GL JS map canvas for three.js
        this.renderer = new THREE.WebGLRenderer({
        canvas: map.getCanvas(),
        context: gl,
        antialias: true
        });
         
        this.renderer.autoClear = false;
        },
        render: function (gl, matrix) {

        var material = new THREE.MeshStandardMaterial({color: 0x5da8de}); 
        material.needsUpdate = true;
        material.colorsNeedUpdate=true;

        var rotationX = new THREE.Matrix4().makeRotationAxis(
        new THREE.Vector3(1, 0, 0),
        modelTransform.rotateX
        );
        var rotationY = new THREE.Matrix4().makeRotationAxis(
        new THREE.Vector3(0, 1, 0),
        modelTransform.rotateY
        );
        var rotationZ = new THREE.Matrix4().makeRotationAxis(
        new THREE.Vector3(0, 0, 1),
        modelTransform.rotateZ
        );
         
        var m = new THREE.Matrix4().fromArray(matrix);
        var l = new THREE.Matrix4()
        .makeTranslation(
        modelTransform.translateX,
        modelTransform.translateY,
        modelTransform.translateZ
        )
        .scale(
        new THREE.Vector3(
        modelTransform.scale/9,
        -modelTransform.scale/9,
        modelTransform.scale/9
        )
        )
        .multiply(rotationX)
        .multiply(rotationY)
        .multiply(rotationZ);

        //var pink = new THREE.Color(0xfca4c5);
        
        
        //gltf.scene.Color = pink;

        //var boja = 

        //var vel = new THREE.Matrix4.scale(new THREE.Vector3(0.5,0.5,0.5));
         
        this.camera.projectionMatrix = m.multiply(l);
        this.renderer.state.reset();
        this.renderer.render(this.scene, this.camera);
        this.map.triggerRepaint();
        }
        };

        
        map.on('style.load', function () {
        map.addLayer(customLayer, 'waterway-label');
        

Upvotes: 1

Views: 658

Answers (1)

Mugen87
Mugen87

Reputation: 31036

If you want to change the material of a loaded glTF asset, do it like so:

gltf.scene.traverse( ( object ) => {

    if ( object.isMesh ) object.material = newMaterial;

} );

Upvotes: 2

Related Questions