Tom Lecoz
Tom Lecoz

Reputation: 85

How to use Texture.clone in Three.js?

My problem is very basic : I have a texture object, I want to clone it but Texture.clone doesn't seem to work as expected

My code is as basic as my problem :

var canvas = document.createElement("canvas");
canvas.width = canvas.height = 512;
canvas.getContext("2d").fillStyle = "#ff0000";
canvas.getContext("2d").fillRect(0,0,512,512);

var texture = new THREE.Texture(canvas); 
texture.needsUpdate= true;

var material = new THREE.MeshBasicMaterial({map:texture}); 
var mesh = new THREE.Mesh(new THREE.PlaneGeometry(100,100), material); 
scene.add(mesh)

//please, don't focus on "scene" and the webglrenderer object,
//it's define on the top of my code but it's not important here.

This code works as expected.

BUT if I change the line containing the material definition by

var material = new THREE.MeshBasicMaterial({map:texture.clone() });

nothing appear on the screen ! Why ?!

EDIT : Thanks to "TheJim01" , I realized that I didn't apply the "needsUpdate = true" on my cloned-texture.

With

var cloneTexture = texture.clone();
cloneTexture.needsUpdate = true;
var material = new THREE.MeshBasicMaterial({map:cloneTexture });

Everything works as expected. Thank you

Upvotes: 0

Views: 3059

Answers (1)

TheJim01
TheJim01

Reputation: 8886

I haven't dug into the renderer code, so I don't know how it uses this information, but Texture.needsUpdate increments the "version" of the texture. CanvasTexture sets this right away, causing the version value to be 1 on the first render.

Texture.clone doesn't perpetuate the version information, and instead re-calls its constructor. Because you aren't setting needsUpdate after the clone, you are not following the same steps.

// from your code:
var texture = new THREE.Texture(canvas); 
texture.needsUpdate= true;
// texture.version === 1

// but...

var material = new THREE.MeshBasicMaterial({ map:texture.clone() });
//material.map.version === 0

So the clone you're passing into the new material has a version of 0, which is apparently no good if you're using a canvas as the source.

This should resolve the issue:

var material = new THREE.MeshBasicMaterial({ map:texture.clone() });
material.map.needsUpdate = true;

Upvotes: 5

Related Questions