Three.js 更新纹理图像

13

我正在使用three.js创建一个类似于这个的《我的世界》纹理编辑器。我只想实现基本的点击和绘制功能,但我似乎无法弄清楚。目前我已经为每个方块面都准备了纹理,并通过以下函数创建着色器材料来应用它们。

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;
}


当用户在网格上的任何位置进行点击时,将使用画布更新纹理文件本身。 更新已经发生,但是除非刷新页面,否则更改不会显示在浏览器中。 我找到了许多示例,说明如何将纹理图像更改为新文件,但没有关于如何在运行时显示同一纹理文件中的更改的示例,甚至不确定是否可能。 是否可以实现这一点?如果不能,有什么替代方案?

2个回答

24

当您更新一个基于画布、视频或外部加载的纹理时,需要将纹理的以下属性设置为true:

如果对象是这样创建的:

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);

在更改纹理之后,将以下内容设置为true:

cube.material.map.needsUpdate = true;

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


1
谢谢,这个完美地解决了问题!我想这可能与我使用ShaderMaterial有关,但是使用MeshBasicMaterial可以正常工作。 - shaqb4
8
我实际上需要执行这两个操作:material.map.needsUpdate = true; material.needsUpdate = true - Peter Ehrlich
4
如果您希望采纳这个答案并为它点赞,请点击上方的箭头图标和接受按钮!这是我们在 Stack Overflow 上的常规做法。 - Engineer
哇,我没意识到我还没有接受这个。谢谢你提醒我! - shaqb4

4

我之前看过那个页面,但是似乎没有一个方法能够奏效。当我尝试点击时,我创建了一个全新的网格、材质和着色器材质,但即使更新标志被设置为 true,屏幕上也没有显示出变化。 - shaqb4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接