javascript Three.js 更新纹理图片

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18436431/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 11:55:35  来源:igfitidea点击:

Three.js Update Texture image

javascriptthree.jstextures

提问by shaqb4

I'm using three.js to create a minecraft texture editor, similar to this. I'm just trying to get the basic click-and-paint functionality down, but I can't seem to figure it out. I currently have textures for each face of each cube and apply them by making shader materials with the following functions.

我正在使用three.js 来创建一个minecraft 纹理编辑器,类似于这个。我只是想降低基本的点击和绘制功能,但我似乎无法弄清楚。我目前为每个立方体的每个面都有纹理,并通过使用以下功能制作着色器材料来应用它们。

this.createBodyShaderTexture = function(part, update)
{
    sides = ['left', 'right', 'top', 'bottom', 'front', 'back'];
    images = [];
    for (i = 0; i < sides.length; i++)
    {
        images[i] = 'img/'+part+'/'+sides[i]+'.png'; 
    }
    texCube = new THREE.ImageUtils.loadTextureCube(images);
    texCube.magFilter = THREE.NearestFilter;
    texCube.minFilter = THREE.LinearMipMapLinearFilter;
    if (update)
    {
        texCube.needsUpdate = true;
        console.log(texCube);
    }
    return texCube;
}
this.createBodyShaderMaterial = function(part, update)
{

    shader = THREE.ShaderLib['cube'];
    shader.uniforms['tCube'].value = this.createBodyShaderTexture(part, update);
    shader.fragmentShader = document.getElementById("fshader").innerHTML;
    shader.vertexShader = document.getElementById("vshader").innerHTML;

    material = new THREE.ShaderMaterial({fragmentShader: shader.fragmentShader,  vertexShader: shader.vertexShader, uniforms: shader.uniforms});
    return material;
}

SkinApp.prototype.onClick = 
function(event)
{
    event.preventDefault();
        this.change(); //makes texture file a simple red square for testing
    this.avatar.remove(this.HEAD);

    this.HEAD = new THREE.Mesh(new THREE.CubeGeometry(8, 8, 8), this.createBodyShaderMaterial('head', false));
    this.HEAD.position.y = 10;
    this.avatar.add(this.HEAD);
    this.HEAD.material.needsUpdate = true;
        this.HEAD.dynamic = true;
}


Then, when the user clicks any where on the mesh, the texture file itself is update using canvas. The update occurs, but the change isn't showing up in the browser unless the page is refreshed. I've found plenty of examples of how to change the texture image to a new file, but not on how to show changes in the same texture file during runtime, or even if it's possible. Is this possible, and if not what alternatives are there?


然后,当用户单击网格上的任何位置时,纹理文件本身将使用画布进行更新。更新发生,但除非刷新页面,否则更改不会显示在浏览器中。我找到了很多关于如何将纹理图像更改为新文件的示例,但没有找到如何在运行时显示同一纹理文件中的更改,或者即使可能。这是可能的,如果不是,还有哪些替代方案?

回答by Jos Dirksen

When you update a texture, whether its based on canvas, video or loaded externally, you need to set the following property on the texture to true:

更新纹理时,无论是基于画布、视频还是外部加载,都需要将纹理的以下属性设置为 true:

If an object is created like this:

如果一个对象是这样创建的:

var canvas = document.createElement("canvas");
var canvasMap = new THREE.Texture(canvas)
var mat = new THREE.MeshPhongMaterial();
mat.map = canvasMap;
var mesh = new THREE.Mesh(geom,mat);

After the texture has been changed, set the following to true:

更改纹理后,将以下设置为 true:

cube.material.map.needsUpdate = true;

cube.material.map.needsUpdate = true;

And next time you render the scene it'll show the new texture.

下次渲染场景时,它将显示新纹理。

回答by Alex Under

Here is all the basics of what you have to know about "updating" stuff in three.js: https://threejs.org/docs/#manual/introduction/How-to-update-things

以下是您必须了解的有关three.js 中“更新”内容的所有基础知识:https://threejs.org/docs/#manual/introduction/How-to-update-things