Cannot update texture successfully

I want to change texture on a cube, but I cannot watch the texture update when I load the image and set the needsUpdate=true.

let geometry=new THREE.BoxGeometry(2,2,2);
let material = new THREE.MeshBasicMaterial();
let cube =new THREE.Mesh(geometry,material);
scene.add(cube);
let loader = new THREE.TextureLoader();
loader.load(url, function(tex){
            material.map = tex;
            material.map.needsUpdate=true
}};

these code cannot update the texture on the cube, how to change the cube textures dynamically, thank you!

The following example changes the texture after 1 second:

https://jsfiddle.net/osdmwevn/

Use it as a template for your code.

2 Likes

From your code, there is no texture on the box initially.

Try
material.needsUpdate = true;
instead of
material.map.needsUpdate = true;

2 Likes

yes, I try your code, but the texture will not be update. do you have any other way to update texture dynamically?

Thanks, but setTimeout is not a good way to implement the function, do you know if 3js offer some offcial codes to update texture dynamically?

Do you mean you want to change the context of an existing texture?

Slightly changed @Mugen87’s example: https://jsfiddle.net/o91pz0xe/
works as expected with material.needsUpdate = true;

As far as I can understand, there are two things, happening in your code: 1. Loading of a texture is asynchronous operation, 2. Compiling of shaders happens before your texture is loaded.

When you create material without map property, it compiles shaders without #define USE_MAP and many other things, and there is no uniform for that texture. And you have exactly this thing, as your texture was not loaded yet, but shaders are already compiled.
Then your texture is loaded, but shader doesn’t have the respect uniform and define's. That’s why you need to set material.needsUpdate = true, so shader will be recompiled with all the features to use the texture as a map.
Pheww… I hope you got what I mean. Anybody can correct me, if I’m wrong :slight_smile:

3 Likes

Yes, I change my code below:

let material = new THREE.MeshBasicMaterial({map: new THREE.Texture()});

and the texture can be update after textureloader load it successfully.
Thank you for your explanation!

I just want to update the texture if the texture load completely. And @prisoner849 said that I create the material without ‘map:xxxx’, this behavior will cause 3js compiles shaders without #define USE_MAP.

So it works successfully when I add the missing code. thank you two.

1 Like

Thanks man, you helped me