我是Three.js的新手,我正在使用React-three-fiber构建一个3D产品配置器。我遵循了一些教程,能够实时渲染和编辑纹理/颜色,但仍然无法找到一种方法来动态加载任何3D对象并在移动中编辑它。现在一切都是硬编码的。任何一段代码,或者如果有人可以指出我在正确的方向,我怎么能使它动态,所以它可以处理任何产品和用户可以修改任何元素的3D对象从网站。我现在就是这样做的。
const Franklin = () => {
const group = useRef();
const { nodes, materials } = useGLTF('/wes/franklin/franklin.glb');
const [
backMap,
backEmissiveMap,
backDisplacementMap,
backMetalnessMap,
backNormalMap,
backRoughnessMap,
] = useLoader(TextureLoader, [
'/wes/franklin/textures/Franklin_back_BaseColor.png',
'/wes/franklin/textures/Franklin_back_Emissive.png',
'/wes/franklin/textures/Franklin_back_Height.png',
'/wes/franklin/textures/Franklin_back_Metallic.png',
'/wes/franklin/textures/Franklin_back_Normal.png',
'/wes/franklin/textures/Franklin_back_Roughness.png',
]);
const [
frameMap,
frameEmissiveMap,
frameDisplacementMap,
frameMetalnessMap,
frameNormalMap,
frameRoughnessMap,
] = useLoader(TextureLoader, [
'/wes/franklin/textures/Franklin_frame_BaseColor.png',
'/wes/franklin/textures/Franklin_frame_Emissive.png',
'/wes/franklin/textures/Franklin_frame_Height.png',
'/wes/franklin/textures/Franklin_frame_Metallic.png',
'/wes/franklin/textures/Franklin_frame_Normal.png',
'/wes/franklin/textures/Franklin_frame_Roughness.png',
]);
const [
capMap,
capEmissiveMap,
capDisplacementMap,
capMetalnessMap,
capNormalMap,
capRoughnessMap,
] = useLoader(TextureLoader, [
'/wes/franklin/textures/Franklin_cap_BaseColor.png',
'/wes/franklin/textures/Franklin_cap_Emissive.png',
'/wes/franklin/textures/Franklin_cap_Height.png',
'/wes/franklin/textures/Franklin_cap_Metallic.png',
'/wes/franklin/textures/Franklin_cap_Normal.png',
'/wes/franklin/textures/Franklin_cap_Roughness.png',
]);
const [
seatMap,
seatEmissiveMap,
seatDisplacementMap,
seatMetalnessMap,
seatNormalMap,
seatRoughnessMap,
] = useLoader(TextureLoader, [
'/wes/franklin/textures/Franklin_seat_BaseColor.png',
'/wes/franklin/textures/Franklin_seat_Emissive.png',
'/wes/franklin/textures/Franklin_seat_Height.png',
'/wes/franklin/textures/Franklin_seat_Metallic.png',
'/wes/franklin/textures/Franklin_seat_Normal.png',
'/wes/franklin/textures/Franklin_seat_Roughness.png',
]);
return (
<group ref={group} dispose={null}>
<mesh
geometry={nodes.Bottom_Bars001.geometry}
material={nodes.Bottom_Bars001.material}
>
<meshStandardMaterial
map={frameMap}
emissiveMap={frameEmissiveMap}
displacementMap={frameDisplacementMap}
metalnessMap={frameMetalnessMap}
normalMap={frameNormalMap}
roughnessMap={frameRoughnessMap}
/>
</mesh>
<mesh
geometry={nodes.Back_Seat002.geometry}
material={nodes.Back_Seat002.material}
>
<meshStandardMaterial
map={backMap}
emissiveMap={backEmissiveMap}
displacementMap={backDisplacementMap}
metalnessMap={backMetalnessMap}
normalMap={backNormalMap}
roughnessMap={backRoughnessMap}
/>
</mesh>
<mesh geometry={nodes.Base001.geometry} material={nodes.Base001.material}>
<meshStandardMaterial
map={frameMap}
emissiveMap={frameEmissiveMap}
displacementMap={frameDisplacementMap}
metalnessMap={frameMetalnessMap}
normalMap={frameNormalMap}
roughnessMap={frameRoughnessMap}
/>
</mesh>
<mesh geometry={nodes.Seat001.geometry} material={nodes.Seat001.material}>
<meshStandardMaterial
map={seatMap}
emissiveMap={seatEmissiveMap}
displacementMap={seatDisplacementMap}
metalnessMap={seatMetalnessMap}
normalMap={seatNormalMap}
roughnessMap={seatRoughnessMap}
/>
</mesh>
<mesh geometry={nodes.Caps003.geometry} material={nodes.Caps003.material}>
<meshStandardMaterial
map={capMap}
emissiveMap={capEmissiveMap}
displacementMap={capDisplacementMap}
metalnessMap={capMetalnessMap}
normalMap={capNormalMap}
roughnessMap={capRoughnessMap}
/>
</mesh>
</group>
);
};
我是这样做的,从GLTFLoader中取出场景,遍历它,将纹理应用到特定的节点上,最后将这个场景传递给primitive作为对象。
scene.traverse((node) => {
if (node.isMesh) {
const checkItem = selectedItems.find((itm) =>
node.name.includes(itm.value)
);
if (checkItem) {
const fabric = items.filter(
(item) => item.name.value === checkItem.value
);
var tempMaterial = new MeshStandardMaterial({
...node.material,
map: loadTexture(fabric[0].texture),
});
node.material = tempMaterial;
}
}
});