簡體   English   中英

在ThreeJS中更新紋理貼圖

[英]Update texture map in ThreeJS

對於未來的觀眾 ,我能夠通過使用mesh.material.map.image.src = texture;來解決它mesh.material.map.image.src = texture;

原始問題:

作為我的ThreeJS項目的一部分,我需要更改網格上的紋理。 不幸的是,我無法讓Three更新到新紋理。

我已經嘗試了以下SO問題中提到的所有內容,但到目前為止還沒有任何工作:

我想要改變的紋理是scene.children[0].children[1].material.map.sourceFile ,結構如下所示:

  • 場景現場
    • 3DOBJECT橫幅
      • MESH標志
        • MESHBASICMATERIAL flag_M
          • TEXTURE flag_MT

flag_MT紋理是我想要更新的紋理,這些是我嘗試過的以下方法:

  • flag_M.needsUpdate = true;
  • flag_MT.needsUpdate = true;
  • flag_MT = THREE.ImageUtils.loadTexture(texture); 紋理是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);

app.setFlagTexture()

//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_MT = THREE.ImageUtils.loadTexture(texture); 然后執行flag_M.needsUpdate = true; 這應該工作。

但是如果你經常更改紋理,這個解決方案真的不是最好的,你應該考慮自己更新紋理對象中的圖像源,然后將needsUpdate標志置為true。

例如,在我的代碼中,我這樣做了:

mesh.material.materials[0].map.image = { data: array, width: 20, height: 20 };
mesh.material.materials[0].map.needsUpdate = true;

mesh是一個帶有FaceMaterial的立方體。 array是一個Uint8Array緩沖區,包含RGB格式的所有數據並完成了工作。 如果出於性能目的,可以避免刪除和創建只是為了更改它。 你的GPU和你的總線要比更新紋理緩沖區更昂貴。

並且,請發布你需要的代碼,看看它有什么問題,因為你的第一次嘗試應該做你想要的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM