我的问题非常基本:我有一个纹理对象,我想克隆它,但 Texture.clone 似乎没有按预期工作
我的代码和我的问题一样基本:
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.
Run Code Online (Sandbox Code Playgroud)
这段代码按预期工作。
但是如果我更改包含材料定义的行
var material = new THREE.MeshBasicMaterial({map:texture.clone() });
Run Code Online (Sandbox Code Playgroud)
屏幕上什么也没有出现!为什么 ?!
编辑:感谢“TheJim01”,我意识到我没有在我的克隆纹理上应用“needsUpdate = true”。
和
var cloneTexture = texture.clone();
cloneTexture.needsUpdate = true;
var material = new THREE.MeshBasicMaterial({map:cloneTexture });
Run Code Online (Sandbox Code Playgroud)
一切都按预期进行。谢谢
我还没有深入研究渲染器代码,所以我不知道它如何使用这些信息,而是Texture.needsUpdate
增加纹理的“版本”。CanvasTexture
立即设置它,导致版本值出现1
在第一次渲染上。
Texture.clone
不会永久保留版本信息,而是重新调用其构造函数。因为您没有needsUpdate
在克隆后进行设置,所以您没有遵循相同的步骤。
// 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
Run Code Online (Sandbox Code Playgroud)
因此,您传递给新材料的克隆具有 a version
of 0
,如果您使用 acanvas
作为源,这显然没有好处。
这应该可以解决问题:
var material = new THREE.MeshBasicMaterial({ map:texture.clone() });
material.map.needsUpdate = true;
Run Code Online (Sandbox Code Playgroud)