React Three Fiber动画入门
使用静态对象和形状构建 3D 场景非常酷,但是当你可以使用动画使场景栩栩如生时,它会更酷。
在 3D 世界中,有一个称为角色装配的过程,它允许你创建称为骨架的特殊对象,其作用类似于骨骼和关节系统。 这些骨架连接到一块 3D 几何体上,例如人、动物或其他任何物体,并允许你弯曲和移动关节以使连接的几何体变形。 你可以使用此过程通过在骨架的不同姿势之间创建关键帧来创建动画。
推荐:用 NSDT场景设计器 快速搭建3D场景。
本教程不会教你如何创建这些装配角色之一,但会教你如何使用已在 React Three Fiber 中创建的角色。
本教程由三个主要部分组成。 从 Mixamo 服务获取一个预装配的 3D 模型和一组动画,准备该模型以用于 Blender 中的 WebGL,然后在 React Three Fiber 中使用该模型。 为什么我们要费心去学习 React 教程的前两部分? 好吧,如果你想重复这个过程来准备一些其他的绑定动画,你就可以做到。 让我们开始吧。
1、寻找免费角色和动画
首先让我们找到一个角色和一组要使用的动画。 为此,我们可以使用 Mixamo,这是一个由 Adobe 提供的免费角色模型和动画库。 如果没有帐户,则需要先创建一个。
第 1 步登录 Mixamo(或创建一个免费帐户)
第 2 步查找要下载的角色。 如果想使用与教程相同的角色,请使用 Michelle 角色。
第 3 步 下载 Capoeira 动画包。 如果需要,你可以选择另一个动画包,但使用相同的动画包可以更轻松地学习本教程。 这是因为动画的名称会有所不同,并可能导致与教程出现一些重大差异。
第 4 步将压缩的资源文件下载为 FBX。 下载时你可以使用所有默认选项。
第 5 步将下载的 .zip 文件的内容解压缩到您稍后可以找到的某个文件夹中。
2、安装Blender
你需要 Blender 将 Mixamo Rig 转换为适合 WebGL 的 GLTF 文件。 可以在此处下载最新版本。
3、在 Blender 中导入角色模型
在启动并运行 Blender 之后,就可以导入模型了。
第 1 步从 Blender 欢迎菜单打开一个新项目。 你可以只选择“常规”项目模板。
第 2 步从默认的 Blender 场景中删除所有内容,通过删除所有对象使其完全为空。 完成后,右上角的场景树中应该看不到任何东西。
第 3 步在 Blender 的文件菜单下找到导入菜单,然后选择 FBX (.fbx)。
第 4 步导航到从 Mixamo 中提取的 zip 文件的内容。 它看起来像这样。
Step 5 找到文件大小最大的fbx文件,这个文件包含人物几何体和默认的T-POSE。 如果你使用 Michelle 角色,则此文件的名称应为 Ch03_nonPBR.fbx。其他文件将包含 Mixamo 包中的所有不同动画。 我们稍后会回来导入这些。
第 6 步确保你在导入对话框中选择了“自动骨骼定向”选项。 你可以在屏幕截图中看到它的位置。 你现在应该可以在 Blender 中看到角色,但具有默认的 T-Pose 动画。
4、在 Blender 中导入动画数据
动画可以用与模型文件完全相同的方式导入,重复上一步的过程,但这次选择名为 armada.fbx 的 FBX 文件。该文件仅包含一个特定动作的动画数据。 由于此动画的名称是 armada,从现在开始我们将经常使用该名称来命名。
5、将动画附加到角色
现在动画已导入并存在于你的 Blender 场景中,但仍需要将其链接到模型。 在继续之前,请确保 3D 场景的内容看起来像这样。 它应该有两个骨骼。 一个带有 T 型姿势的模型称为 Armature,另一个带有动画但没有附加模型称为 Armature.001。 请注意,我将 Armature.001 下的动画名称从默认名称重命名为 Armada,这只是为了方便以后查找。 默认名称将是一些大而长的随机名称,我建议也更改它。
第 1 步在视口中选择第一个骨架(带有模型的骨架)后,通过选择视口顶部的动画选项卡切换到 Blender 中的动画布局。 你的视图应该更改为如下面的屏幕截图所示。
第 2 步切换到摄影表面板(底部)中的动作编辑器视图。
第 3 步将活动动作更改为导入的第二个动作,我们将其重命名为 Armada。
如果这有效,你应该会看到角色立即将其姿势更改为踢球动画的开始。 要尝试它,请点击摄影表上的播放按钮以查看动画播放。 如果由于某种原因它不起作用,你可能需要使用新的 Blender 重新开始并重新导入你的 .fbx 文件。 确保选中了“自动骨骼定向”选项。
第 3 步按下 Dope Sheet Action Editor 中的 Stash 按钮以确保动画保持与模型的关联。 点击存储后,动画将与工作对象的附件一起存储,以便稍后可以找到它,现在可以导入另一个模型并重复到此为止的步骤以附加另一个动画动作。
第 4 步 最后删除第二个骨架,即只有动画的那个。 不是上面有模型的那个。 这只是为了在导出前清理场景,因此导出文件中没有多余的对象。 拥有这些有时会使 GLFTJSX 感到困惑,所以这是一件好事。
6、将模型导出为 GLTF 文件
现在是时候从 Blender 导出到我们可以在 react-three-fiber 中使用的 .gltf 文件了。 GLTF 是你要导出到 WebGl 的任何 3d 数据的标准文件格式。
步骤 1 导出为 .gltf 文件。 .gltf 格式在导出后将保持人类可读性。 如果你想查看导出文件的结构,这有时会很有帮助。 你也可以导出为 .glb,它代表 GLTF 二进制文件。 它是一种用于表示 GLTF 的更节省空间的文件格式,但一旦导出,你就无法再轻松打开和检查文件的内容。
将文件命名为什么并不重要,但我将在我们要导出的动画名称之后将其命名为 armada.gltf。 你将在本教程的其余部分看到引用此名称。
7、生成 React Component Wrapper
当我们在 React 中使用导出的 gltf 文件时,我们需要访问导出场景的某些部分,例如我们需要提取几何体、骨架和动画。
你可以通过不手动操作来节省大量时间,而是使用由 react-three-fiber 团队创建的名为 GLFTJSX 的有用工具。 这是一个命令行工具,你可以将 gltf 或 glb 文件作为输入运行,它将创建一个结构良好的 React 组件包装器作为输出。
第 1 步 使用 npm 全局安装 GLTFJSX,以便您可以在命令行上使用它。
npm i -g gltfjsx
第 2 步以 armada.gltf 文件作为输入运行 GLTFJSX。 确保在与 .gltf 文件相同的目录中运行该命令。
gltfjsx armada.gltf
运行后你应该看到一个名为 Armada.js 的新文件,记住你保存这个文件的位置,以便我们稍后可以将它添加到我们的 React 项目中。
这就是为我们的 armada.gltf 文件生成的组件的样子。
/*
Auto-generated by: https://github.com/pmndrs/gltfjsx
*/import * as THREE from "three";
import React, { useRef, useState } from "react";
import { useGLTF } from "@react-three/drei";import { useAnimations } from "@react-three/drei";export default function Model(props) {const group = useRef();const { nodes, materials, animations } = useGLTF("/armada.gltf");const { actions } = useAnimations(animations, group);return (<group ref={group} {...props} dispose={null}><group rotation={[Math.PI / 2, 0, 0]} scale={[0.01, 0.01, 0.01]}><primitive object={nodes.mixamorigHips} /><skinnedMeshmaterial={materials.Ch03_Body}geometry={nodes.Ch03.geometry}skeleton={nodes.Ch03.skeleton}/></group></group>);
}useGLTF.preload("/armada.gltf");
8、创建React-three-fiber场景
我们已经创建了使用动画角色所需的资产。 现在让我们进入 React。
步骤 1 创建一个新的 React 应用程序
npx create-react-app armada
步骤2 添加Three.js、React Three Fiber、drei依赖
yarn add three react-three-fiber @react-three/drei
第 3 步将 .gltf 文件和 Armada.js 组件包装器复制到 React 项目中。 Armada.js组件放在src目录下,armada.gltf文件放在public目录下。
第 4 步将 index.css 替换为以下内容,使 React Three Fiber 画布填充整个视口。
/*index.css*/
* {box-sizing: border-box;
}html,
body,
#root {width: 100%;height: 100%;margin: 0;padding: 0;
}body {background: #000000;font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, helveticaneue, helvetica, ubuntu, roboto, noto, segoe ui, arial, sans-serif;
}
第 5 步创建一个空的 React Three Fiber 场景。 用以下代码替换 App.js 文件的内容。 这将创建一个带有 OrbitControls 和一些简单照明的空场景。
import React from "react";
import { Canvas } from "react-three-fiber";import { OrbitControls } from "@react-three/drei";
import "./index.css";export default function App() {return (<Canvas><OrbitControls /><ambientLight intensity={0.6} /><directionalLight intensity={0.5} /></Canvas>);
}
9、将导入的角色添加到 React Three Fiber场景
现在是时候使用我们用 GLTFJSX 创建的 Armada.js 文件了。
步骤 1 将 Armada.js 文件导入到 App.js 文件中。
第 2 步从“react”中导入 Suspense,并从我们之前创建的 Armada 组件中导入 Armada。
步骤 3 在 Canvas 组件内添加一个 Suspense 组件。
步骤 4 在 Suspense 组件中添加 Armada 组件。
import React, { Suspense } from "react"; //highlight-line
import { Canvas } from "react-three-fiber";
import Armada from "./Armada.js";import { OrbitControls } from "@react-three/drei";
import "./index.css";export default function App() {return (<Canvas><OrbitControls /><ambientLight intensity={0.6} /><directionalLight intensity={0.5} />// highlight-start<Suspense fallback={null}><Armada /></Suspense>// highlight-end</Canvas>);
}
你现在应该会在 Armada 动画的开头看到该角色,但它还没有移动。 我们将在下一步也是最后一步中解决这个问题。
10、警告
如果你看到有关无法从 drei 导入的错误,可能是因为导入路径在最新版本中发生了变化。 看起来像这样的导入将不再有效:
import { useAnimations } from "@react-three/drei/useAnimations";
相反,确保直接从 drei导入的, 像这样:
import { useAnimations } from "@react-three/drei";
11、播放动画
播放动画很容易! 你需要做的就是对 Armada.js 文件进行小的更改。 是的,从 GLTFJSX 自动生成。 动画将作为组件提供的 javascript 对象提供给您。
第 1 步打开自动生成的 Armada.js 组件(来自 gltfjsx)
第 2 步 在 useEffect 挂钩中调用要播放的动画的 play 方法。 动画的名称将来自 Blender 中动作的名称! 这就是为什么在导出之前重命名它如此重要。 如果你不记得要播放的动画的名称,总是可以先在挂钩中控制台记录操作对象。
// Armada.js
/*
Auto-generated by: https://github.com/pmndrs/gltfjsx
*/import React, { useRef, useEffect } from "react";
import { useGLTF } from "@react-three/drei";
//highlight-start
import { useAnimations } from "@react-three/drei";
//highlight-end
export default function Model(props) {const group = useRef();const { nodes, materials, animations } = useGLTF("/armada.gltf");const { actions } = useAnimations(animations, group);//highlight-startuseEffect(() => {actions.Armada.play();});//highlight-endreturn (<group ref={group} {...props} dispose={null}><group rotation={[Math.PI / 2, 0, 0]} scale={[0.01, 0.01, 0.01]}><primitive object={nodes.mixamorigHips} /><skinnedMeshmaterial={materials.Ch03_Body}geometry={nodes.Ch03.geometry}skeleton={nodes.Ch03.skeleton}/></group></group>);
}useGLTF.preload("/armada.gltf");
如果一切正常,你应该会看到你的角色开始执行踢球动画!
原文链接:React Three Fiber动画 — BimAnt
相关文章:

React Three Fiber动画入门
使用静态对象和形状构建 3D 场景非常酷,但是当你可以使用动画使场景栩栩如生时,它会更酷。 在 3D 世界中,有一个称为角色装配的过程,它允许你创建称为骨架的特殊对象,其作用类似于骨骼和关节系统。 这些骨架连接到一块…...

为什么我推荐你使用 systemd timer 替代 cronjob?
概述 前几天在使用 Terraform cloud-init 批量初始化我的实验室 Linux 机器。正好发现有一些定时场景需要使用到 cronjob, 进一步了解到 systemd timer 完全可以替换 cronjob, 并且 systemd timer 有一些非常有趣的功能。 回归话题:为什么我推荐你使用 systemd t…...

elasticsearch基础6——head插件安装和web页面查询操作使用、ik分词器
文章目录一、基本了解1.1 插件分类1.2 插件管理命令二、分析插件2.1 es中的分析插件2.1.1 官方核心分析插件2.1.2 社区提供分析插件2.2 API扩展插件三、Head 插件3.1 安装3.2 web页面使用3.2.1 概览页3.2.1.1 unassigned问题解决3.2.2 索引页3.2.3 数据浏览页3.2.4 基本查询页3…...

【Linux】七、进程间通信(二)
目录 三、system V(IPC) 3.1 system V共享内存 3.1.1 共享内存的概念 3.1.2 共享内存的原理 3.1.3 创建共享内存(shmget ) 3.1.4 ftok函数 3.1.5 查看共享内存资源 3.1.6 创建共享内存测试代码 3.1.7 再次理解共享内存 3.1.8 释放共享内存(shm…...

Synchronized学习大总结
目录 1.synchronized特性 2.synchronized如何使用 3.synchronized的锁机制 1.synchronized特性 synchronized 是乐观锁,也是悲观锁,是轻量级锁(j基于自旋锁实现),也是重量级锁(基于挂起等待锁实现),它不是读写锁,是互斥锁,当一个线程抢到锁之后,其它线程阻塞等待,进入synchr…...

VN5620以太网测试——环境搭建篇
文章目录 前言一、新建以太网工程二、Port Configuration三、Link up四 Trace界面五、添加Ethernet Packet Builder六、添加ARP Packet七、添加Ethernet IG总结前言 CANoe(CAN open environment)VN5620 :是一个紧凑而强大的接口,用于以太网网络的分析、仿真、测试和验证。 …...

redis哨兵和集群部署手册
一、哨兵模式原理及作用 1.原理 哨兵(sentinel): 是一个分布式系统,用于对主从结构中的每台服务器进行监控,当出现 故障时,通过投票机制选择新的master并将所有slave连接到新的master。所以整个运行哨兵的集…...

ctfshow web入门 java 295 298-300
其他没啥好讲的,都是工具就通杀了 web295 漏洞地址 http://ip/S2-048/integration/saveGangster.action 这里我们可以看到他是解析了 尝试使用网上的payload %{(#dmognl.OgnlContextDEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess#dm):((#container#cont…...

SWIG包装器使用指南——(四)C#使用SWIG简介与实践
SWIG系列:http://t.csdn.cn/cIAcr 文章目录一、简介二、全局函数、变量、常量三、继承四、传递指针、引用、数组与值五、基本类型的指针与引用六、基本类型的数组七、基本类型的默认map规则八、常用的typemap方法九、代码插入十、实践10.1 如何映射Foo*&到ref F…...

HashTable, HashMap 和 ConcurrentHashMap
HashTable, HashMap 和 ConcurrentHashMap 都是 Java 集合框架中的类,用于存储和操作键值对。它们之间存在一些关键区别,如下所示: 1.同步性: HashTable:线程安全,所有的方法都是同步的(synchr…...

ToBeWritten之IoT 技战法
也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大 少走了弯路,也就错过了风景,无论如何,感谢经历 转移发布平台通知:将不再在CSDN博客发布新文章,敬…...

基于ASP.NET开发的医院手术麻醉信息管理系统源码 项目源码
系统主要功能介绍: 门诊科室管理系统:手术快速申请、手术申请、手术审核 麻醉科管理系统:手术安排、术后处方、术后小结、PCS实施及管理记录、手术流程 手术护理系统:手术安排、安排临时手术、添加急诊手术、局麻手术护理、整体护…...

伪加密超具体破解办法,直击原理底层,细致演示!!!
前言: 由于我自己目前在misc和取证工作中,也遇到很多压缩包的问题,我个人非常喜欢做压缩包的题目,但也会遇到伪加密问题难以破解,全网ctf教程我都看完了,但是都觉得不够具体,所以我写一篇博客&…...

ChatGPT大规模封锁亚洲地区账号
我是卢松松,点点上面的头像,欢迎关注我哦! 在毫无征兆的情况下,从3月31日开始OpenAI大规模封号,而且主要集中在亚洲地区,特别是ip地址在台湾、日本、香港三地的,命中率目测40%。新注册的账号、…...

脂肪酸脂质Myristic acid PEG NHS,Myristic-acid PEG NHS ester,肉豆蔻酸PEG活性酯,具有优异疏水性
一、基础产品数据: 中文名:肉豆蔻酸PEG N-羟基琥珀酰亚胺,肉豆蔻酸PEG活性酯 英文名:Myristic acid PEG NHS,Myristic-acid PEG NHS ester,Myristic acid PEG SE 结构式(Structural)…...

MFC - CFormView类学习1
CFormView简介 MFC提供了一个名为CFormView的特殊视图类,我们称其为表单视图。表单视图是指用控件来输入和输出数据的视图,用户可以方便地在表单视图中使用控件。表单视图具有对话框和滚动视图的特性,它使程序看起来象是一个具有滚动条的对话…...

图像预处理方法
图像预处理 膨胀腐蚀概述 ⚫ 膨胀、腐蚀属于形态学的操作, 简单来说就是基于形状的一系列图像处理操作 ⚫ 膨胀腐蚀是基于高亮部分(白色)操作的, 膨胀是対高亮部分进行膨胀, 类似“领域扩张”, 腐蚀是高亮部分被腐蚀, 类似“领域被蚕食” ⚫ 膨胀腐蚀的应用和功能: 消除噪声…...

【蓝桥杯C/C++】专题六:动态规划
专题六:动态规划 目录专题六:动态规划导读什么是动态规划解决的问题解题步骤动态规划应该如何debug记忆化搜索斐波那契数题目代码题解爬楼梯题目代码题解使用最小花费爬楼梯题目代码题解不同路径题目题解dfsdp凑硬币题目题解dfsdp滑雪题目代码题解汉罗塔…...

图的定义和基本术语
图的定义和基本术语1.图的定义2.图的基本术语3.图的分类1.图的定义 图是由顶点和有穷非空集合和顶点边的集合吗,表示为G(V,E)。 G表示一个图,V是图G的顶点(数据元素)的集合,E是图G中顶点之间边的集合。在图中…...

041:cesium加载Blue Marble地图
第041个 点击查看专栏目录 本示例的目的是介绍如何在vue+cesium中加载Blue Marble地图。Blue Marble是一个术语,用来描述星球漂浮在浩瀚太空中的形象。早在 1972 年,阿波罗 17 号任务的工作人员就首次捕捉到了地球的标志性卫星图像,并将其称为“Blue Marble”。从那时起,NA…...

【概念梳理】激活函数
一、引言 常用的激活函数如下: 1、Sigmoid函数 2、Tanh函数 3、ReLU函数 4、ELU函数 5、PReLU函数 6、Leaky ReLU函数 7、Maxout函数 8、Mish函数 二、激活函数的定义 多层神经网络中,上层节点的输出和下层节点的输入之间具有一个函数关系,…...

【python】@property 和 @staticmethod
property 和 staticmethod 是 Python 中的两个装饰器,它们分别用于在类中创建属性或静态方法。它们的作用如下: property property:用于将类的一个方法作为属性访问。在 Python 中,使用“getter” 和“setter”方法来实现属性&a…...

Spring题集 - Spring AOP相关面试题总结
文章目录01. Spring AOP 的理解?02. Spring AOP 思想的代码实现03. Spring AOP 的相关术语有哪些?04. Spring AOP 基于注解的切面实现?05. Spring AOP 的通知有哪些类型?06. AOP 有哪些实现方式?07. Spring AOP 和 AspectJ AOP 有…...

分考场
[蓝桥杯 2017 国 C] 分考场(假题:最小色数) 题目描述 nnn 个人参加某项特殊考试。 为了公平,要求任何两个认识的人不能分在同一个考场。 求最少需要分几个考场才能满足条件。 输入格式 第一行,一个整数 n(1<n<100)n(1<n<100…...

BI技巧丨DAX Studio
DAX Studio DAX Studio,作为PowerBI外部插件使用率排名第一的插件,相信各位小伙伴或多或少都听说过,那么DAX Studio具体有哪些功能呢? PS:DAX Studio的下载链接,小伙伴们可以自行搜索,这里就不…...

Java 8常用时间 API
Date: 你不爱我了吗? 🚡本地时间时区相关格式化在Java 8中,Instant类用于表示时间戳,相当于旧的Date类;LocalDateTime类用于表示日期和时间,相当于旧的Calendar类;DateTimeFormatter类用于格式化日期和时间…...

C++运算符
C运算符 运算符是一种告诉编译器执行特定的数学或逻辑操作的符号。C 内置了丰富的运算符,并提供了以下类型的运算符: 算术运算符关系运算符逻辑运算符位运算符赋值运算符杂项运算符 1. 算术运算符 运算符描述实例把两个操作数相加A B 将得到 30-从第…...

低/无代码赋能企业,IT与业务的角色正在悄然改变
现在这个社会,年轻人的压力是真的大,需要会的技能多到数不清。想学习多点技能也不知道去哪学,主要是网络资源太丰富,很难找到一个适合自己的。那接下来推荐4个大神级别的资源网站你可一定得码住,都是年轻人特别 …...

SpringCloud学习2(Spring Cloud Netflix)负载均衡Ribbon、Feign负载均衡、Hystix服务熔断
文章目录负载均衡RibbonRibbon的作用代码实现生产者cloud1_provider实现配置文件在HiController中编写以下代码启动集群消费者cloud1_consumer实现引入依赖编写配置文件编写启动类,并给RestTemplate配置LoadBalanced注解编写RestController来测试Feign负载均衡简介F…...

Spring 源码解析 - @Async 注解下的循环依赖问题原理
一、Async 注解下的循环依赖问题 我们都知道 Spring IOC 单例模式下可以帮助我们解决循环依赖问题,比如下面自己依赖自己循环依赖的场景: Component public class TestAsync {ResourceTestAsync async;public void test() {System.out.println("t…...