Javascript 在3JS中更新纹理贴图

Javascript 在3JS中更新纹理贴图,javascript,three.js,Javascript,Three.js,对于未来的观众,我可以使用mesh.material.map.image.src=texture来解决这个问题 原始问题: 作为ThreeJS项目的一部分,我需要更改网格上的纹理。不幸的是,我无法得到三个更新到新的纹理 我已经尝试了以下问题中提到的所有事情,但到目前为止没有任何效果: 还有更多 我尝试更改的纹理是场景。子对象[0]。子对象[1]。材质。贴图。源文件,结构如下所示: 场景 3DOBJECT横幅 网旗 MESHBASICMATERIAL flag_M 纹理标志

对于未来的观众,我可以使用
mesh.material.map.image.src=texture来解决这个问题

原始问题:

作为ThreeJS项目的一部分,我需要更改网格上的纹理。不幸的是,我无法得到三个更新到新的纹理

我已经尝试了以下问题中提到的所有事情,但到目前为止没有任何效果:

  • 还有更多
我尝试更改的纹理是
场景。子对象[0]。子对象[1]。材质。贴图。源文件
,结构如下所示:

  • 场景
    • 3DOBJECT横幅
      • 网旗
        • MESHBASICMATERIAL flag_M
          • 纹理标志
flag\u MT
纹理是我想要更新的纹理,以下是我尝试过的方法:

  • flag_M.needsUpdate=true
  • flag_MT.needsUpdate=true
  • flag\u MT=THREE.ImageUtils.loadTexture(纹理)纹理为base64数据字符串
  • 实际上重新生成整个对象并将其替换到场景中
谢谢

编辑:代码的重要部分:

init()

flag_MT = THREE.ImageUtils.loadTexture(app.setFlagTexture());
flag_MT.magFilter = THREE.NearestFilter;
flag_MT.minFilter = THREE.NearestFilter;

flag_M = new THREE.MeshBasicMaterial({map: flag_MT});
flag_M.needsUpdate = true;

flag_T = { //easyVectory64 just provides a clean function for making vector maps
    u: easyVector64(2, 62, 20, 1), //up face
    d: easyVector64(22, 62, 20, 1), //down face
    f: easyVector64(1, 23, 20, 40), //front face
    b: easyVector64(22, 23, 20, 40), //back face
    l: easyVector64(0, 23, 1, 40), //left face
    r: easyVector64(41, 23, 1, 40)}; //right face

flag_G.faceVertexUvs[0] = []; //Map texture to mesh
flag_G.faceVertexUvs[0][0] = [flag_T["r"][0], flag_T["r"][1], flag_T["r"][3]];
flag_G.faceVertexUvs[0][1] = [flag_T["r"][1], flag_T["r"][2], flag_T["r"][3]];
flag_G.faceVertexUvs[0][2] = [flag_T["l"][0], flag_T["l"][1], flag_T["l"][3]];
flag_G.faceVertexUvs[0][3] = [flag_T["l"][1], flag_T["l"][2], flag_T["l"][3]];
flag_G.faceVertexUvs[0][4] = [flag_T["u"][0], flag_T["u"][1], flag_T["u"][3]];
flag_G.faceVertexUvs[0][5] = [flag_T["u"][1], flag_T["u"][2], flag_T["u"][3]];
flag_G.faceVertexUvs[0][6] = [flag_T["d"][0], flag_T["d"][1], flag_T["d"][3]];
flag_G.faceVertexUvs[0][7] = [flag_T["d"][1], flag_T["d"][2], flag_T["d"][3]];
flag_G.faceVertexUvs[0][8] = [flag_T["f"][0], flag_T["f"][1], flag_T["f"][3]];
flag_G.faceVertexUvs[0][9] = [flag_T["f"][1], flag_T["f"][2], flag_T["f"][3]];
flag_G.faceVertexUvs[0][10] = [flag_T["b"][0], flag_T["b"][1], flag_T["b"][3]];
flag_G.faceVertexUvs[0][11] = [flag_T["b"][1], flag_T["b"][2], flag_T["b"][3]];

flag_G.applyMatrix(new THREE.Matrix4().makeTranslation(0, -20, 0));

flag = new THREE.Mesh(flag_G, flag_M);
//Bunch of code that pre-mixes several textures into a single texture
var texture = "data:image/png;base64,..."; //texture being a base64 png data string
flag_MT = THREE.ImageUtils.loadTexture(texture);
if(flag_M !== undefined){ //because flag_M is undefined on the first call
    flag_M.needsUpdate = true;
}
return texture;
app.setFlagTexture()

flag_MT = THREE.ImageUtils.loadTexture(app.setFlagTexture());
flag_MT.magFilter = THREE.NearestFilter;
flag_MT.minFilter = THREE.NearestFilter;

flag_M = new THREE.MeshBasicMaterial({map: flag_MT});
flag_M.needsUpdate = true;

flag_T = { //easyVectory64 just provides a clean function for making vector maps
    u: easyVector64(2, 62, 20, 1), //up face
    d: easyVector64(22, 62, 20, 1), //down face
    f: easyVector64(1, 23, 20, 40), //front face
    b: easyVector64(22, 23, 20, 40), //back face
    l: easyVector64(0, 23, 1, 40), //left face
    r: easyVector64(41, 23, 1, 40)}; //right face

flag_G.faceVertexUvs[0] = []; //Map texture to mesh
flag_G.faceVertexUvs[0][0] = [flag_T["r"][0], flag_T["r"][1], flag_T["r"][3]];
flag_G.faceVertexUvs[0][1] = [flag_T["r"][1], flag_T["r"][2], flag_T["r"][3]];
flag_G.faceVertexUvs[0][2] = [flag_T["l"][0], flag_T["l"][1], flag_T["l"][3]];
flag_G.faceVertexUvs[0][3] = [flag_T["l"][1], flag_T["l"][2], flag_T["l"][3]];
flag_G.faceVertexUvs[0][4] = [flag_T["u"][0], flag_T["u"][1], flag_T["u"][3]];
flag_G.faceVertexUvs[0][5] = [flag_T["u"][1], flag_T["u"][2], flag_T["u"][3]];
flag_G.faceVertexUvs[0][6] = [flag_T["d"][0], flag_T["d"][1], flag_T["d"][3]];
flag_G.faceVertexUvs[0][7] = [flag_T["d"][1], flag_T["d"][2], flag_T["d"][3]];
flag_G.faceVertexUvs[0][8] = [flag_T["f"][0], flag_T["f"][1], flag_T["f"][3]];
flag_G.faceVertexUvs[0][9] = [flag_T["f"][1], flag_T["f"][2], flag_T["f"][3]];
flag_G.faceVertexUvs[0][10] = [flag_T["b"][0], flag_T["b"][1], flag_T["b"][3]];
flag_G.faceVertexUvs[0][11] = [flag_T["b"][1], flag_T["b"][2], flag_T["b"][3]];

flag_G.applyMatrix(new THREE.Matrix4().makeTranslation(0, -20, 0));

flag = new THREE.Mesh(flag_G, flag_M);
//Bunch of code that pre-mixes several textures into a single texture
var texture = "data:image/png;base64,..."; //texture being a base64 png data string
flag_MT = THREE.ImageUtils.loadTexture(texture);
if(flag_M !== undefined){ //because flag_M is undefined on the first call
    flag_M.needsUpdate = true;
}
return texture;

我在我的项目中遇到了类似的问题,您的第一次尝试应该已经成功了
flag\M.needsUpdate=true

可以使用ImageUtils重新创建纹理,
flag\u MT=THREE.ImageUtils.loadTexture(纹理)然后执行
标记\u M.needsUpdate=true
这应该是可行的

但是,如果您过于频繁地更改纹理,此解决方案实际上不是最好的,您应该考虑自己更新纹理对象中的图像源,然后设置
needsUpdate
标志

例如,在我的代码中,我这样做了:

mesh.material.materials[0].map.image = { data: array, width: 20, height: 20 };
mesh.material.materials[0].map.needsUpdate = true;
mesh
是一个带有面材质的立方体
array
是一个Uint8Array缓冲区,包含RGB格式的所有数据并完成了工作。 如果可以,出于性能目的,请避免删除和创建只是为了更改它的内容。对你的GPU和你的总线来说,这样做要比仅仅更新纹理缓冲区更昂贵


请发布代码,你必须看到其中的错误,因为你的第一次尝试应该已经完成了你想要的。

我在我的项目中遇到了类似的问题,你的第一次尝试应该已经成功了
flag\M.needsUpdate=true

可以使用ImageUtils重新创建纹理,
flag\u MT=THREE.ImageUtils.loadTexture(纹理)然后执行
标记\u M.needsUpdate=true
这应该是可行的

但是,如果您过于频繁地更改纹理,此解决方案实际上不是最好的,您应该考虑自己更新纹理对象中的图像源,然后设置
needsUpdate
标志

例如,在我的代码中,我这样做了:

mesh.material.materials[0].map.image = { data: array, width: 20, height: 20 };
mesh.material.materials[0].map.needsUpdate = true;
mesh
是一个带有面材质的立方体
array
是一个Uint8Array缓冲区,包含RGB格式的所有数据并完成了工作。 如果可以,出于性能目的,请避免删除和创建只是为了更改它的内容。对你的GPU和你的总线来说,这样做要比仅仅更新纹理缓冲区更昂贵


请发布代码,您必须查看其中的错误,因为您的第一次尝试应该已经完成了您想要的操作。

我已更新了上面的问题,以包含相关代码。我还尝试了你的
mesh.material.materials[0].map.image={data:array,width:20,height:20}
mesh.material.materials[0].map.needsUpdate=true但如何将图像数据字符串转换为数据数组?请使用
mesh.maeria.map.image.src=texture将其删除,我可以加载它。谢谢你的帮助我不知道Three.js到底是怎么做的,如果他只是保留一个指向画布的链接或者复制画布的内容。如果是这样的话,那就别担心了!但如果您需要更好的性能,请朝这个方向看。我已经更新了上面的问题,以包含相关代码。我还尝试了你的
mesh.material.materials[0].map.image={data:array,width:20,height:20}
mesh.material.materials[0].map.needsUpdate=true但如何将图像数据字符串转换为数据数组?请使用
mesh.maeria.map.image.src=texture将其删除,我可以加载它。谢谢你的帮助我不知道Three.js到底是怎么做的,如果他只是保留一个指向画布的链接或者复制画布的内容。如果是这样的话,那就别担心了!但是,如果您需要更好的性能,请朝这个方向看。