Changing the texture of GLFT creates Strange graphical effect

I have a three.js project where I would like to switch the materials of my gltf object i have created. But when I change it, I get a strange effect which looks like inverted normals (from my experience in blender)
You can see how it works here https://youtu.be/x0fslFtmON4

Also here is the

Any ideas? Heres is the code from my index.js file. Thanks

function main () {

        

    const renderer = new THREE.WebGLRenderer({antialias:true, alpha: true});

    renderer.setClearColor(0x000000, 0);

    renderer.setSize(window.innerWidth,window.innerHeight);

    renderer.gammaFactor = 2.2;

    document.body.appendChild(renderer.domElement);

    const fov = 75;

    const aspect = window.innerWidth/window.innerHeight;

    const near = 0.1;

    const far = 500;

    const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);

    camera.position.z = 5;

    const scene = new THREE.Scene();

    let ambient = new THREE.AmbientLight(0x656765)

    let light = new THREE.DirectionalLight(0xFFFFFFF, 1);

    light.position.set(10, 10, 5);

    

    scene.add(ambient);

    scene.add(light);

    let color = 0;

    let icecream

    const flavour = ["Strawberries and Cream", "Pistachio", "Mango", "Bubblegum", "Lemon"];

    let pistachioMaterial;

    let currentFlavour = 4;

    loadIceCream ();

    loadTextures();

    function loadTextures () {

        const loader = new THREE.TextureLoader();

        const url = './assets/images/ice-cream_pistachio.png'

        //const color = new THREE.Color(0xBAEBAEy);

    

        const texture = loader.load(url, () => {

            pistachioMaterial = new THREE.MeshPhongMaterial({map: texture, shininess:1 });

            texture.flipY = false;

            

        },

            (xhr) => {console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' )},

            function(error){console.log(error)}

            );

    }

    function loadIceCream () {

        const gltfloader = new THREE.GLTFLoader();

        const url = './assets/meshes/ice_cream_2.glb'

        const color = new THREE.Color( 0xBAEBAE );

        const gltf = gltfloader.load (url, moveIceCream, (xhr) => {console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );}, function(error){console.log(error)});

                

    }

    function moveIceCream (gltf) {

        icecream = gltf.scene.children[0];

        icecream.material.specular= 0x000000;

        icecream.material.needsUpdate = true

        scene.add( icecream );

        icecream.position.y = 8;

        

        icecream.rotation.z = 0.2;

        console.log(icecream.material);

        }

    function render () {//loop causes the renderer to draw the scene every time the screen is refreshed.

        

        if (icecream) {

            icecream.rotation.y += 0.01;

            if (color === 1) {

                

            }

        }

        
        

        requestAnimationFrame(render);//prevents the mesh from becoming distorted when resizing 

        renderer.render(scene, camera);//redrawing the renderer every time

    }

    requestAnimationFrame(render);

    document.getElementById("toggle").addEventListener('click', toggleIceCream)

    window.addEventListener('click', screenClick)

    window.addEventListener('resize', () => {

        renderer.setSize(window.innerWidth,window.innerHeight);

        camera.aspect = window.innerWidth / window.innerHeight;

        camera.updateProjectionMatrix();

    })

    

    function toggleIceCream () {

        icecream.position.y = 8;

        currentFlavour = currentFlavour + 1;

        

        if (currentFlavour === 1) {

            //pistachioMaterial.encoding = THREE.sRGBEncoding;

            

                    icecream.material = pistachioMaterial;

                    pistachioMaterial.flipY = false;

                    pistachioMaterial.needsUpdate = true;

                    console.log(icecream.material);

            

        }

        if (currentFlavour ===! flavour.length) {

            currentFlavour = currentFlavour + 1;

        } else if (currentFlavour === flavour.length) {

            currentFlavour = 0;

        }

        document.getElementById('toggle').innerHTML = flavour[currentFlavour];

        gsap.to(icecream.position, {y: -2,duration: 1, ease:"elastic"} )

        

    }

    function screenClick () {

        //gsap.to(icecream.position, {y: -3,duration: 3, ease:"elastic"} )

    }

    function changeSize () {

        

    }

}

var raycaster = new THREE.Raycaster();

var mouse = new THREE.Vector2();

function onMouseMove (event) {

    event.preventDefault();

    mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;

    mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;

    

    raycaster.setFromCamera(mouse, camera);

    var intersects = raycaster.intersectObjects(scene.children, true);

    for (i=0; i < intersects.length; i++) {

        }

}

window.addEventListener('mousemove', () => {

})

main();

If you’re replacing the default material that GLTFLoader provides (not just a texture) then be sure to compare the settings of that material to the one you are providing. Look for things like…

  • .flatShading
  • .vertexTangents
  • .normalScale
  • .skinning
  • .morphTargets
1 Like

Ah, thank you.I realised it doesn’t need changing the whole material to change the diffuse map and just changed the texture instead + texture.flipY = false; and i got the intended result. thanks