Three.js texture / image update at runtime
Asked Answered
C

2

21

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 ....
Cushitic answered 17/4, 2013 at 17:32 Comment(0)
P
39

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;
Poll answered 17/4, 2013 at 21:22 Comment(3)
This method apparently retrieves the browser-cached image, if you've previously preloaded all your textures into non-visible img elements. So no need to worry about reloading images from a server.Darindaring
Won't this result in a memory leak since the previous texture was not disposed?Idiomatic
Kahless - possibly? I'm not sure what it takes to "dispose" (aka get rid of all references) of a material map in THREEFirefly
S
4

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

Septima answered 13/4, 2020 at 19:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.