在ThreeJS中更新纹理贴图
Update texture map in ThreeJS
对于未来的观众,我可以通过使用mesh.material.map.image.src = texture;
作为我的ThreeJS项目的一部分,我需要改变网格上的纹理。不幸的是,我不能让Three更新到新的纹理。
我已经尝试了以下问题中提到的所有事情,但到目前为止都没有效果:
- three.js改变材质的纹理
- 如何在加载图像数据的ThreeJS中更新纹理?
- Three.js更新纹理图像
- 更改Three.js collada对象的纹理和颜色
- 和更多…
我想改变的纹理是scene.children[0].children[1].material.map.sourceFile
,结构看起来像这样:
- 场景的场景
- 3 dobject横幅
- 网国旗
- MESHBASICMATERIAL flag_M
- 纹理flag_MT
- MESHBASICMATERIAL flag_M
- 网国旗
- 3 dobject横幅
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
标志为真。
例如,在我的代码中我这样做:
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和你的总线来说更昂贵,而不仅仅是更新纹理缓冲区。
和请,张贴代码,你必须看到什么是错误的,因为你的第一次尝试应该做你想要的。
- Javascript循环不会自我更新
- 添加文字和评论功能更新Div
- AngularJS:ng之后,重复$scope值未按预期更新
- 如何通过数组更新角度子范围
- Ajax聊天消息重复而不仅仅是更新
- 通过CSV文件上载更新数据库表
- 平均值:无法将数据更新到数据库
- $rootScope未使用forEach进行更新
- d3基于用户选择动态更新节点
- 有条件更新d3.js力图中节点的最佳方法
- 更新纹理的正确方法(三.JS)
- 相位器更新精灵纹理
- WebGL纹理图像源更新
- 更新Three.js版本时未显示纹理
- Three.js:在运行时使用r59更新立方体纹理时运气不佳
- 如何在ThreeJs中更新纹理
- 在ThreeJS中更新纹理贴图
- 动态更新X3DOM模型中的纹理
- 如何在加载图像数据的ThreeJS中更新纹理
- THREE js 更新纹理生成 Canvas 的最佳性能方式