Reputation: 85
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
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