Three.js 如何在 AR 应用程序上触摸按钮时更改一个对象的两种材质

Three.js How to change two materials of the one object when touching a button on a AR application

我最近第一次接触 Three.js,我需要一些帮助来做一些测试。

目前我正在尝试创建一个 AR 应用程序,其中使用单元格 phone 的摄像头将对象插入到真实环境中。最初,该对象以蓝色显示在屏幕上,但在顶部我想放置三个具有三种不同颜色的按钮,例如蓝色、红色和绿色,当触摸其中一个按钮时,对象只会改变其颜色。

我在 Blender 上创建了对象及其 materials。对象的一个​​面有一个 material 和 UV 纹理,对象的其余部分有第二个 material,没有纹理,只有一个 material 和初始节点(创建于搅拌机循环)。所以我创建了 6 个 material,其中 3 个用于纹理,每个 1 个,3 个用于颜色,每个也一个。在 Blender 上,我将此对象导出为具有 materials 和纹理的 .glb。

现在我在 Three.js 上导入这个对象,我已经了解如何将这个对象添加到场景并渲染它,以便它出现在 phone 的屏幕上。包括对象附带的第一个 materials 正常工作(来自 .glb),我没有在 Three.js 中创建任何关于 materials 的东西,一切都显示在场景中到目前为止来自我在搅拌机中导出并刚刚加载到 three.js.

的 .glb

现在我需要创建应用程序的第二部分,即:当我触摸一种颜色的按钮时,对象必须改变颜色,以及“纹理”。正是在这里我需要帮助。

我该怎么做? 我需要三个不同的对象吗?或者只有一个对象包含所有 6 个 material?如何在 three.js 上执行此功能?我需要有关 Blender 和 Three.js.

的帮助

有人可以指点一下吗?或 link 视频或有关此主题的精彩对话。

提前致谢。

基本上您需要做的是更改 .glb 文件中相关网格的 material。

当你用 GLTFLoader 加载 .glb 文件时,你给它一个 'onLoad' 函数参数,你可以在其中首先访问文件的内容(文件本身就是它自己的迷你场景) - 这个是您可以遍历场景、定位网格并将其保存为变量以便稍后对其进行操作的点。

现在,假设文件中有多个网格,您怎么知道哪个是正确的?最好的方法是按名称。由于您是从 Blender 创建的对象,您可以为每个网格指定一个唯一的名称,以便稍后在 three.js.

中识别

现在您可以在 onLoad 函数中插入一些逻辑来确认正确的网格是您存储为变量的网格,请考虑以下代码:

let meshFromGLTF;
const meshName = "MESH_0" // assuming this is the name you gave it on blender

...
loader = new GLTFLoader();
loader.load( "path/to/gltf", ( gltf ) => {
    const scene = gltf.scene;
    scene.traverse( ( child ) => {
        if ( child.isMesh && child.name === meshName ) { // to confirm it is a mesh
            meshFromGLTF = child;
            // this may also be a good point to store the original material as a variable
        }
    }
})

现在,由于您将网格存储为变量,因此很容易通过按钮更改它的 material 和纹理。单击按钮时只需提供一个 onClick 函数,您可以在该函数中执行以下操作:

const texture = textureLoader.load( 'path/to/texture.png' );
const materialBlue = new MeshBasicMaterial ( { map: texture, color: 'blue' } );

function onClickBlue () {
   meshFromGLTF.material = materialBlue;
}

关于为网格创建 materials,这是一个相当广泛的主题,您可以查看 documentation 并查看您可能需要哪种 materials ,您在包含单词 'map'.

的参数上应用于 material 本身的纹理

我创建了一个执行此方法的小示例 here