通过 dat.gui 下拉菜单更新 three.js 纹理

Updating three.js texture throughthe dat.gui dropdown

我已经使用 textureLoader 加载了不同的纹理,我正在尝试使用 dat.gui 控件更新它们。

为什么下面的代码不起作用?

gui.add(mesh.position, "y", -1, 1, 0.1);
gui.add(mesh.material, "map", { alpha: alphaTexture, color: colorTexture, normal: normalTexture })
    .onChange(() => {
        mesh.material.needsUpdate = true;
        console.log("updated");
    });

它给出了这个错误:

"Uncaught TypeError: m is undefined" [error][1]

经过一些调整,我发现第三个参数中的对象(或数组)的值只支持 string 类型,因此将对象作为值传递是行不通的。

这是我能想到的最接近的解决方法..

/* GUI options */
const guiOptions = {
    mesh_material_map: "color",
};

/* Textures */
const textureLoader = new THREE.TextureLoader(loadingManager);
const colorTexture = textureLoader.load("/textures/door/color.jpg");
const alphaTexture = textureLoader.load("/textures/door/alpha.jpg");
const normalTexture = textureLoader.load("/textures/door/normal.jpg");

const guiTextureHash = {
    color: colorTexture,
    alpha: alphaTexture,
    normal: normalTexture,
};

/* Add to gui */
gui.add(guiOptions, "mesh_material_map", Object.keys(guiTextureHash)).onChange((value) => {
    mesh.material.map = guiTextureHash[value];
    mesh.needsUpdate = true;
    console.log("updated", value);
});

我发现你的主题是寻找纹理选择器。它可能离你的起点有点远,但可以帮助其他人。我终于用 dat.gui 的下拉选择键制作了一个简单的纹理选择器。目标是能够动态更改我的 matcap 纹理,通过加载的纹理数组。

const gui = new dat.GUI()
const textureLoader = new THREE.TextureLoader()
const myMatCap = [
    textureLoader.load('./textures/matcaps/1.png'),
    textureLoader.load('./textures/matcaps/2.png'),
    textureLoader.load('./textures/matcaps/3.png')
]

const parameters = {
    color: 0xff0000,
    matCapTexture: 0
}
const updateAllMaterials = () => {
    scene.traverse( (child)=>{
        if(child instanceof THREE.Mesh && child.material instanceof THREE.MeshMatcapMaterial) {
            child.material.matcap = myMatCap[ parameters.matCapTexture]
            child.material.needsUpdate = true
        }
    })
}
gui.add(parameters, 'matCapTexture', {
    terracotta: 0,
    grey: 1,
    chrome: 2,
}).onFinishChange(()=>{
    updateAllMaterials()
})

let mesh = new THREE.Mesh( 
    geometry, 
    new THREE.MeshMatcapMaterial({ 
        side: THREE.DoubleSide, 
        matcap: myMatCap[ parameters.matCapTexture ]
    })
);
scene.add(mesh)