如何使用 react 和 three.js 在网站渲染自己的3D模型

sxkk20082年前知识分享145

哈喽,大家好,我是Ai知识分享,今天翻译一篇文章 《How to Use Three.js And React to Render a 3D Model of Your Self》,内容是当下最流行的 three.js,根据本文步骤,你将零基础学会在网页中渲染 3D 模型。

正文开始


在本文中,我将介绍如何在 react 项目中使用 react-three-fiber 创建的一个 3D 软件程序,配置 3D 参数(如 Blender 或 Maya ) 。在本文结束时,您将能够在您的网站上渲染一个 3D 模型 (gltf / glb)。

获取自己的 3D 模型

为了获得自己的 3D 模型,我们使用 Ready Player Me 这个网站,一个免费的 3D 形象创建器来自 Wolf3D,允许任何人在几分钟内创建自己的外观表现,不需要任何 3D 建模经验,你只需要做的是快速自拍,然后等待程序根据你的肖像自动生成自定义 3D 形象。

然后你可以自由地使用一系列合适的发型、肤色、面部特征、服装选择和其他可定制的属性对自己的角色进行调整。

登录这个网站后 Ready Player Me, 你只需要遵循以下步骤,你就可以开始进行。

选择体型

步骤一选择提醒截图

上传你自己的照片

步骤二上传你自己的照片截图

定制您的外观

步骤三定制您的外观截图

下载您的模型

下载您的模型截图

在 React 中渲染模型

为了在 react 程序中渲染这个模型,我们将使用 react-three-fiber** 一个**Threejs React 渲染器

项目开发

首先让我们创建一个项目

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

将模型转换为 React 组件

完成之后,继续并运行以下命令,使用 gltfjsx 转换成 react 组件格式。

npx gltfjsx model.glb

转换后的内容类似于以下代码

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

创建场景

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

结果展示 codesandbox.io

给模型添加动画

给 3D 模型添加动画, 需要在你的电脑上安装 blender

将模型导入到 blender

Blender 是免费的开源 3D 软件,它支持整个 3D 管道建模、索具、动画、模拟、渲染、合成和运动跟踪,甚至视频编辑和游戏创作,了解更多信息

创建一个新的 blender 项目

创建一个新的blender项目截图

删除所有对象中的物体

删除所有对象中的物体截图

将 glb 文件导入 blender

将 glb 文件导入 blender截图

将 glb 文件导入 blender第二步截图

选择您的模型,然后单击 Import glTF 2.0

选择模型导入截图

将模型转换为 fbx 格式

在将添加任何动画添加到我们的模型之前,我们需要首先将其转换为FBX格式。

选择模型

要在 blender 中选择 3D 模型,只需单击键盘a或者您可以使用鼠标选择。

选择 3D 模型

将模型导出为 FBX

将模型导出为FBX第一步

将模型导出为FBX第二步

确保选择的 Path ModeCopy, 然后点击 Embed textures 这个选项.

添加动画 mixamo

Mixamo 是一项免费的在线服务,用于自动装配和动画 3d 角色.它由 Mixamo 公司开发, 由 Adobe 于 2015 年收购。Mixamo 允许用户上传 FBX、OBJ 或 Zip 文件,然后网站尝试在两分钟内自动操纵角色。

将模型上传到 mixamo

将模型上传到 mixamo 截图

将模型上传到 mixamo 截图第二步

选择动画并下载动画模型

选择动画

下载动画模型

将动画模型转换回 glb 格式

为了能够在 react 中使用需要转换会 glb 格式。

将动画模型导入 blender

将动画模型导入 blender 截图

将动画模型导出为 glb

将动画模型导出为 glb

在 react 中渲染动画模型

在 public 文件夹下替换这个 model.glb 文件使用动画模型 ,然后在 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')

最终展示效果

最终展示效果.gif

源码链接

https://codesandbox.io/s/3d-model-animation-d41e9u


以上就是本文全部内容,希望这篇文章对大家有所帮助,也可以参考我往期的文章或者在评论区交流你的想法和心得,欢迎一起探索前端。

本文首发掘金平台,来源Ai知识分享博客

相关文章

智能智慧系统:打造智能化社会和智慧行业

智能智慧系统:打造智能化社会和智慧行业

  智能智慧系统是利用人工智能技术开发的智能化管理系统的核心机构。通过集成各类传感器、数据分析技术和自动控制系统,实现对智能设备及系统的智能化管理和优化。在智能智慧系统,我们...

如果你会 TailwindCSS 我推荐 VSCODE 安装 这个插件tailwind-snippets 可以快速帮我们来发出一个常用的代码片段,大家可以在 https://www.tailwindsnippets.ml/snippets 查看效果,快速实现我们的 html 页面

tailwind-snippets 预览

部署

Vercel

Next.js 开发商 Vercel 获得最近 1.5 亿美元 D 轮融资。Vercel 注册什么的我就不讲了,建议使用GitHub 登录, 点击new project创建一个项目,这个项目可以从自己的 GitHub 库导入或者选择 Vercel 给的模板,Vercel 给的模板(下图)首先也会导入进自己的 GitHub 库,总之要先把内容导入进 GitHub 库才行。

Vercel 支持的框架

Vercel 为个人用户提供了

  1. 自动 HTTPS/SSL
  2. 带宽 100 GB
  3. 并发构建,每天 10 万次调用
  4. Serverless Function

所以 Vercel 不光支持静态网站也支持 nodejs 动态网站,如果想要其他后端语言

可以选择 heroku

heroku

Heroku 是一个支持多种编程语言的云平台,并且提供了 Heroku PostgresHeroku RedisApache Kafka on Heroku

Heroku 支持的语言

Heroku 虽然提供了比较全面的编程语言和数据库支持,免费用户还支持

  1. 使用 Git 和 Docker 部署
  2. 自定义二级域名
  3. 容器编排
  4. 自动操作系统补丁

但 heroku 对国内用户支持不是很友好,第一点访问国内速度比不上 Vercel, 第二点 163 和 QQ 邮箱都不能注册,想要注册得要其他邮箱, 第三没有免费的 ssl。第四项目源代码只能有 500M。

数据库选择

MongoDB

选择 https://cloud.mongodb.com/

mongodb 首页截图

创建 database 的时候选择 free;

选择免费截图 地域可以选择日本或者新加坡。

接着创建一个用户 创建一个用户 密码是自动生成的,要把密码拷贝下来

接着要创建一个允许链接的 IP 地址

在 mongodb.com 设置允许链接的IP

如何白嫖一个动态网站

前言我们知道,想要搭建一个网站往往需要一下几个步骤:域名注册服务器购买数据库购买或部署网站设计网站开发网站备案网站上线在国内上线一个网站,域名还必须得备案,光是域名备案的话还的几个星期,整个流程下来,...

人脸融合:探索虚拟与现实的交汇之道

人脸融合:探索虚拟与现实的交汇之道

  随着科技的不断进步和人工智能的发展,人脸融合作为一种热门的技术引起了广泛关注。它通过将两张或多张不同的人脸合成,创造出一个全新的面容,引发了人们对于虚拟与现实交汇的思考。...

AI绘画:探索人工智能与艺术的融合

AI绘画:探索人工智能与艺术的融合

   随着人工智能技术的不断进步,越来越多的领域开始应用AI技术。其中,艺术界也开始加入了这场革命。AI绘画作为其中的一部分,以其独特的艺术风格受到了广泛的关注。  AI绘画...

AI人工智能排名揭晓:探索现实与潜力之间的较量

AI人工智能排名揭晓:探索现实与潜力之间的较量

  随着科技的不断进步与创新,人工智能已经成为当今世界的热门话题。从自动化工具到智能助手,AI已渗透到我们的日常生活中的方方面面。无论是在医疗保健、金融、制造业还是其他行业,...

天翼智慧社区:领航智能生活,引领未来社区生态

天翼智慧社区:领航智能生活,引领未来社区生态

  随着科技的不断发展,智能生活已经成为当今社会的一大潮流。天翼智慧社区作为中国电信旗下的智慧社区品牌,以其先进的技术和全面的服务,成为了引领智能社区发展的领军者。从智能家居...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。