如何使用 react 和 three.js 在網(wǎng)站渲染自己的3D模型

在本文中,我將介紹如何在 react 項(xiàng)目中使用 react-three-fiber 創(chuàng)建的一個(gè)3D 軟件程序,配置3D 參數(shù)(如Blender或Maya) 。在本文結(jié)束時(shí),您將能夠在您的網(wǎng)站上渲染一個(gè)3D模型 (gltf / glb)。
獲取自己的3D模型
為了獲得自己的 3D模型,我們使用 Ready Player Me 這個(gè)網(wǎng)站,一個(gè)免費(fèi)的3D形象創(chuàng)建器來自 Wolf3D,允許任何人在幾分鐘內(nèi)創(chuàng)建自己的外觀表現(xiàn),不需要3D建模經(jīng)驗(yàn),你需要做的只是快速自拍,然后等待程序根據(jù)你的肖像自動(dòng)生成自定義3D形象。
然后你可以自由地使用一系列合適的發(fā)型、膚色、面部特征、服裝選擇和其他可定制的屬性對(duì)自己的角色進(jìn)行調(diào)整。
登錄這個(gè)網(wǎng)站后 Ready Player Me,?你只需要遵循以下步驟,你就可以開始進(jìn)行。
選擇體型

上傳你自己的照片

定制您的外觀

下載您的模型

在React中渲染模型
為了在react 程序中渲染這個(gè)模型,我們將使用 ?react-three-fiber?一個(gè)Threejs React 渲染器
項(xiàng)目開發(fā)
首先讓我們創(chuàng)建一個(gè)項(xiàng)目
npx create-react-app my-3d-model
#or
yarn create react-app my-3d-model
然后安裝 @react-three/fiber 和 @react-three/drei
npm install three @react-three/fiber @react-three/drei
#or
yarn add three @react-three/fiber @react-three/drei
將模型轉(zhuǎn)換為React組件
完成之后,繼續(xù)并運(yùn)行以下命令,使用 gltfjsx??轉(zhuǎn)換成?react?組件格式文件。
npx gltfjsx model.glb
轉(zhuǎn)換后的內(nèi)容類似于以下代碼
import React, { useRef } from 'react';
import { useGLTF } from '@react-three/drei';
export default function Model({ ...props }) {
const group = useRef();
const { nodes, materials } = useGLTF('/model.glb');
return (
<group ref={group} {...props} dispose={null}>
<primitive object={nodes.Hips} />
<skinnedMesh
geometry={nodes.Wolf3D_Body.geometry}
material={materials.Wolf3D_Body}
skeleton={nodes.Wolf3D_Body.skeleton}
/>
<skinnedMesh
geometry={nodes.Wolf3D_Glasses.geometry}
material={materials.Wolf3D_Glasses}
skeleton={nodes.Wolf3D_Glasses.skeleton}
/>
<skinnedMesh
geometry={nodes.Wolf3D_Hair.geometry}
material={materials.Wolf3D_Hair}
skeleton={nodes.Wolf3D_Hair.skeleton}
/>
<skinnedMesh
geometry={nodes.Wolf3D_Outfit_Bottom.geometry}
material={materials.Wolf3D_Outfit_Bottom}
skeleton={nodes.Wolf3D_Outfit_Bottom.skeleton}
/>
<skinnedMesh
geometry={nodes.Wolf3D_Outfit_Footwear.geometry}
material={materials.Wolf3D_Outfit_Footwear}
skeleton={nodes.Wolf3D_Outfit_Footwear.skeleton}
/>
<skinnedMesh
geometry={nodes.Wolf3D_Outfit_Top.geometry}
material={materials.Wolf3D_Outfit_Top}
skeleton={nodes.Wolf3D_Outfit_Top.skeleton}
/>
<skinnedMesh
name="EyeLeft"
geometry={nodes.EyeLeft.geometry}
material={nodes.EyeLeft.material}
skeleton={nodes.EyeLeft.skeleton}
morphTargetDictionary={nodes.EyeLeft.morphTargetDictionary}
morphTargetInfluences={nodes.EyeLeft.morphTargetInfluences}
/>
<skinnedMesh
name="EyeRight"
geometry={nodes.EyeRight.geometry}
material={nodes.EyeRight.material}
skeleton={nodes.EyeRight.skeleton}
morphTargetDictionary={nodes.EyeRight.morphTargetDictionary}
morphTargetInfluences={nodes.EyeRight.morphTargetInfluences}
/>
<skinnedMesh
name="Wolf3D_Head"
geometry={nodes.Wolf3D_Head.geometry}
material={materials.Wolf3D_Skin}
skeleton={nodes.Wolf3D_Head.skeleton}
morphTargetDictionary={nodes.Wolf3D_Head.morphTargetDictionary}
morphTargetInfluences={nodes.Wolf3D_Head.morphTargetInfluences}
/>
<skinnedMesh
name="Wolf3D_Teeth"
geometry={nodes.Wolf3D_Teeth.geometry}
material={materials.Wolf3D_Teeth}
skeleton={nodes.Wolf3D_Teeth.skeleton}
morphTargetDictionary={nodes.Wolf3D_Teeth.morphTargetDictionary}
morphTargetInfluences={nodes.Wolf3D_Teeth.morphTargetInfluences}
/>
group>
);
}
useGLTF.preload('/model.glb');
創(chuàng)建場景
import React, { Suspense } from 'react';
import { Canvas } from '@react-three/fiber';
import { OrbitControls } from '@react-three/drei';
export default function App() {
return (
<Canvas
camera={{ position: [2, 0, 12.25], fov: 15 }}
style={{
backgroundColor: '#111a21',
width: '100vw',
height: '100vh',
}}
>
<ambientLight intensity={1.25} />
<ambientLight intensity={0.1} />
<directionalLight intensity={0.4} />
<Suspense fallback={null}>
// your model here
Suspense>
<OrbitControls />
Canvas>
);
}
將模型添加到場景中
首先將模型 (glb文件) 添加到 **public **文件夾,使用 gltfjsx 生成的文件將其放入src 下的components 文件夾
import React, { Suspense } from 'react';
import { Canvas } from '@react-three/fiber';
import { OrbitControls } from '@react-three/drei';
import Model from './Model'; /* highlight-line */
export default function App() {
return (
<Canvas
camera={{ position: [2, 0, 12.25], fov: 15 }}
style={{
backgroundColor: '#111a21',
width: '100vw',
height: '100vh',
}}
>
<ambientLight intensity={1.25} />
<ambientLight intensity={0.1} />
<directionalLight intensity={0.4} />
<Suspense fallback={null}>
<Model position={[0.025, -0.9, 0]} /> /* highlight-line */
Suspense>
<OrbitControls />
Canvas>
);
}
修改 app.js
body {
margin: 0;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
}
添加 css
結(jié)果展示codesandbox.io
給模型添加動(dòng)畫
給3D模型添加動(dòng)畫,??需要在你的電腦上安裝?blender
將模型導(dǎo)入到 blender
Blender 是免費(fèi)的開源3D軟件.它支持整個(gè)3D管道建模、索具、動(dòng)畫、模擬、渲染、合成和運(yùn)動(dòng)跟蹤,甚至視頻編輯和游戲創(chuàng)作。了解更多信息
創(chuàng)建一個(gè)新的blender項(xiàng)目

刪除對(duì)象中的物體

將glb文件導(dǎo)入blender


選擇您的模型,然后單擊 Import glTF 2.0

將模型轉(zhuǎn)換為fbx格式
在任何動(dòng)畫添加到我們的模型之前,我們需要先將其轉(zhuǎn)換為FBX格式。
選擇模型
要在blender中選擇3D模型,只需單擊鍵盤a或者您可以使用鼠標(biāo)選擇。

將模型導(dǎo)出為FBX


確保選擇的 Path Mode 是 Copy, 然后點(diǎn)擊 Embed textures?這個(gè)選項(xiàng)。
添加動(dòng)畫 mixamo
Mixamo?是一項(xiàng)免費(fèi)的在線服務(wù),用于自動(dòng)裝配和動(dòng)畫3d角色,它由Mixamo公司開發(fā),??由Adobe于2015年收購。?Mixamo?允許用戶上傳FBX、OBJ或Zip文件,然后網(wǎng)站嘗試在兩分鐘內(nèi)自動(dòng)操縱角色。
將模型上傳到 mixamo


選擇動(dòng)畫并下載動(dòng)畫模型


將動(dòng)畫模型轉(zhuǎn)換回glb格式
為了能夠在react中使用需要轉(zhuǎn)換回?glb 格式.
將動(dòng)畫模型導(dǎo)入blender

將動(dòng)畫模型導(dǎo)出為glb

在react中渲染動(dòng)畫模型
在public 文件夾下替換這個(gè) model.glb?文件,使用動(dòng)畫模型?,然后在?src/Model.js 修改以下代碼
import React, { useRef, useEffect } from 'react'; /* highlight-line */
import { useGLTF, useAnimations } from '@react-three/drei'; /* highlight-line */
export default function Model({ ...props }) {
const group = useRef();
const { nodes, materials, animations } = useGLTF('/model.glb');
const { actions } = useAnimations(animations, group); /* highlight-line */
// 'Armature|mixamo.com|Layer0' is the name of the animation we need to run.
// console.log(actions);
useEffect(() => {/* highlight-line */
actions['Armature|mixamo.com|Layer0'].play(); /* highlight-line */
}); /* highlight-line */
return (
<group ref={group} {...props} dispose={null}>
<primitive object={nodes.Hips} />
<skinnedMesh
geometry={nodes.Wolf3D_Body.geometry}
material={materials.Wolf3D_Body}
skeleton={nodes.Wolf3D_Body.skeleton}
/>
<skinnedMesh
geometry={nodes.Wolf3D_Glasses.geometry}
material={materials.Wolf3D_Glasses}
skeleton={nodes.Wolf3D_Glasses.skeleton}
/>
<skinnedMesh
geometry={nodes.Wolf3D_Hair.geometry}
material={materials.Wolf3D_Hair}
skeleton={nodes.Wolf3D_Hair.skeleton}
/>
<skinnedMesh
geometry={nodes.Wolf3D_Outfit_Bottom.geometry}
material={materials.Wolf3D_Outfit_Bottom}
skeleton={nodes.Wolf3D_Outfit_Bottom.skeleton}
/>
<skinnedMesh
geometry={nodes.Wolf3D_Outfit_Footwear.geometry}
material={materials.Wolf3D_Outfit_Footwear}
skeleton={nodes.Wolf3D_Outfit_Footwear.skeleton}
/>
<skinnedMesh
geometry={nodes.Wolf3D_Outfit_Top.geometry}
material={materials.Wolf3D_Outfit_Top}
skeleton={nodes.Wolf3D_Outfit_Top.skeleton}
/>
<skinnedMesh
name="EyeLeft"
geometry={nodes.EyeLeft.geometry}
material={nodes.EyeLeft.material}
skeleton={nodes.EyeLeft.skeleton}
morphTargetDictionary={nodes.EyeLeft.morphTargetDictionary}
morphTargetInfluences={nodes.EyeLeft.morphTargetInfluences}
/>
<skinnedMesh
name="EyeRight"
geometry={nodes.EyeRight.geometry}
material={nodes.EyeRight.material}
skeleton={nodes.EyeRight.skeleton}
morphTargetDictionary={nodes.EyeRight.morphTargetDictionary}
morphTargetInfluences={nodes.EyeRight.morphTargetInfluences}
/>
<skinnedMesh
name="Wolf3D_Head"
geometry={nodes.Wolf3D_Head.geometry}
material={materials.Wolf3D_Skin}
skeleton={nodes.Wolf3D_Head.skeleton}
morphTargetDictionary={nodes.Wolf3D_Head.morphTargetDictionary}
morphTargetInfluences={nodes.Wolf3D_Head.morphTargetInfluences}
/>
<skinnedMesh
name="Wolf3D_Teeth"
geometry={nodes.Wolf3D_Teeth.geometry}
material={materials.Wolf3D_Teeth}
skeleton={nodes.Wolf3D_Teeth.skeleton}
morphTargetDictionary={nodes.Wolf3D_Teeth.morphTargetDictionary}
morphTargetInfluences={nodes.Wolf3D_Teeth.morphTargetInfluences}
/>
group>
);
}
useGLTF.preload('/model.glb');
最終展示效果

源碼地址:
https://codesandbox.io/s/3d-model-animation-d41e9u?file=/src/Model.js:271-281
原文地址:https://dev.to/nourdinedev/how-to-use-threejs-and-react-to-render-a-3d-model-of-your-self-4kkf
