Miloud Eloumri
Miloud Eloumri

Reputation: 839

Three.js texture / image update at runtime

I am trying to change a cube image at run time by selecting an option from Select Form element. When running the code, the image changes after selecting, but the previous cube and image stays in the scene.

How I clear / refresh / update the scene properly when changing the material / image / texture.

<div id = "container"></div>

<form id = "changesForm">
    Cube Image:
    <br>
    <select id = "cubeImage">
        <option value = "random">Random</option>
        <option value = "image1">First Image</option>
        <option value = "Image2">Second Image</option>
    </select>
    <br>
</form>

<script type = "text/javascript">

window.onload = windowLoaded;

function windowLoaded(){
    if (window.addEventListener){
        init();
        animate();
                             //document.getElementById('container').addEventListener('mousemove', containerMouseover, false);
    window.addEventListener( 'resize', onWindowResize, false );
    var cubeImage = document.getElementById('cubeImage');
    cubeImage.addEventListener("change", changeCubeImage, false);
    }
    else if (window.attachEvent){
        //init();
        //animate();
                  //document.getElementById('container').attachEvent('onmousemove', containerMouseover);
        //window.attachEvent( 'onresize', onWindowResize);
    }

function changeCubeImage(e){
    //e.preventDefault();
    var target = e.target;
    cubeImageCheck = target.value;      
    createCube();               
}

// rest code ..... 

function createCube(){
    //image
    var cubeImg;

    switch (cubeImageCheck){
        case 'random': {
           // should load the 2 images random - to do 
            cubeImg = new THREE.ImageUtils.loadTexture("img1.jpg");
           break;
        }
        case 'image1': {
            cubeImg = new THREE.ImageUtils.loadTexture("image1.jpg");
            break;
        }
        case 'image2': {
            cubeImg = new THREE.ImageUtils.loadTexture("image2.jpg");
            break;
       }
}

cubeImg.needsUpdate = true;


// geometry
var cubeGeometry = new THREE.CubeGeometry(200,200,200);;
// material
var cubeMaterial = new THREE.MeshPhongMaterial({
    map: cubeImg, 
    side:THREE.DoubleSide, 
    transparent: true, 
    opacity:1, 
    shading: THREE.SmoothShading, 
    shininess: 90, 
    specular: 0xFFFFFF
});

cubeMaterial.map.needsUpdate = true;

//mesh
cubeMesh = new THREE.Mesh(cubeGeometry, cubeMaterial);
cubeMesh.needsUpdate = true;
scene.add(cubeMesh);
}

// rest ....

Upvotes: 22

Views: 41882

Answers (2)

Hitesh Sahu
Hitesh Sahu

Reputation: 45042

Complete Example With Loader:

First, create your mesh and apply any material

//Add SPHERE
this.earthMesh = new THREE.Mesh(
  new THREE.SphereBufferGeometry(3, 35, 35),
  new THREE.MeshPhongMaterial()
);
this.scene.add(this.earthMesh);

Now Load your Texture image and apply it on the mesh material

//LOAD TEXTURE and on completion apply it on SPHERE
new THREE.TextureLoader().load(
  "https://images.pexels.com/photos/1089438/pexels-photo-1089438.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260",
  texture => {
    //Update Texture
    this.earthMesh.material.map = texture;
    this.earthMesh.material.needsUpdate = true;
  },
  xhr => {
    //Download Progress
    console.log((xhr.loaded / xhr.total) * 100 + "% loaded");
  },
  error => {
    //Error CallBack
    console.log("An error happened" + error);
  }
);

Progress and Error Callbacks are optional

Upvotes: 4

uhura
uhura

Reputation: 2683

On select change you can update your existing mesh texture, don't need to remove or create new mesh :

mesh.material.map = THREE.ImageUtils.loadTexture( src );
mesh.material.needsUpdate = true;

Upvotes: 39

Related Questions