Three.js 实现元宇宙汽车 3D 模型

技术采用three.js+React实现。

Step1:创建一个React项目

create-react-app your-app

Step2:加载three.js

npm install --save three

@react-three/fiber

@react-three/drei

npm install @react-three/fiber

npm install @react-three/drei

Step3:导入3D模型

Step4:加载

一、项目效果

这里我们使用React结合Three.js,创建了一个3D项目,效果如下:

二、项目搭建

2.1 首先在本地创建一个React项目

打开终端,进入到ReactProjects目录,这个项目我们放在这个目录下,项目的名字就叫car-demo01吧。

create-react-app car-demo01

然后我们就在本地目录下,看到了这个项目:

然后我们使用VScode打开这个项目:

结构如下:

2.2 安装Three.js

这个项目用到了Three.js,所以我们需要先安装它。

什么是WebGL。WebGL是在浏览器中实现三维效果的一套规范。使用WebGL原生的API来写3D程序是一件非常痛苦的事情,幸好,有很多同行花业余时间写了一些WebGL开源框架,其中three.js就是非常优秀的一个。

什么是threejs,很简单,你将它理解成three + js就可以了。three表示3D的意思,js表示javascript的意思。那么合起来,three.js就是使用javascript 来写3D程序的意思。

three.js官网地址:https://threejs.org/

在vscode上打开终端,自动进入到该目录下,然后我们输入以下命令:

npm install --save three

如图:

接下来可以直接使用three.js去实现。但是在这篇文章中,我们换一种实现方式,这里我们还需要另外两个包:@react-three/fiber和@react-three/drei。

react-three-fiber是针对three.js的react渲染器。使用可重用、自包含的组件以声明方式构建场景,这些组件可以对状态做出反应,易于交互,并可以进入react的生态系统。https://www.npmjs.com/package/@react-three/fiber

@react-three/drei 是three.js的一些预先制作好的功能的集合。https://www.npmjs.com/package/@react-three/drei

我们添加这两个包:

npm install three @react-three/fiber

如图:

npm install @react-three/drei

如图:

三、代码实现

3.1 初始化代码

首先打开App.js文件,清理掉原来的内容,最终如下:


import './App.css';export default function App() {return ();
}

这里为了操作方便,我们使用styled-components,它利用标记的模板文本(JavaScript的最新添加)和CSS的强大功能,styled-components允许您编写实际的CSS代码来设置组件的样式。它还删除了组件和样式之间的映射——将组件用作低级样式构造是再容易不过了。https://styled-components.com/

在终端:

npm install styled-components

如图:

这里我们定义一个Wrapper,并在它上面设置样式,初始化位红色,是为了显眼一些,后面可以根据自己的喜好调整。

App.js下的代码如下:


import './App.css';
import styled from "styled-components";export default function App() {return (<Wrapper className="App">HelloWorld</Wrapper>);
}const Wrapper = styled.div`position: relative;background: #ff0000;
`;

然后启动项目,终端输入:

npm start

然后打开3000端口,看到页面效果如下:

3.2 添加 Canvas

首先在头部引入Canvas:

import { Canvas } from '@react-three/fiber';

然后我们在Wrapper里面添加

代码如下:


import './App.css';
import styled from "styled-components";
import { Canvas } from '@react-three/fiber';export default function App() {return (<Wrapper className="App"><Canvas className="canvas"></Canvas></Wrapper>);
}const Wrapper = styled.div`position: relative;background: #ff0000;canvas {width:100vw;height: 100vh;}
`;

3.3 导入3D模型

因为我们最终想显示一个Car的3D模型,你可以自己建模,也可以去网上找现成的素材。这里推荐一个网站:https://sketchfab.com/

我们在上面选好素材进行下载:

我把它存储到了桌面的models目录下,并解压缩:

接下来你可以按照three.js官网的说明导入3D模型,但是此处我们选择另一种做法:

这里我们使用一个工具:https://github.com/CesiumGS/gltf-pipeline。

gltf-pipeline由Richard Lee和Cesium团队用来优化glTF的工具。

  • 将glTF转换为glb(并反向)
  • 将缓冲区/纹理保存为嵌入文件或单独文件
  • 将glTF 1.0模型转换为glTF 2.0
  • 应用Draco网格压缩

1、首先安装:

npm install -g gltf-pipeline

我们打开终端,输入复制粘贴上面的命令:(我已经安装过了,此处只是演示),如果报错没有权限,在前面加上sudo即可:

sudo npm install -g gltf-pipeline

2、gltf转换:

将 glTF 转换为 Draco glTF。然后通过终端进入到3d模型的目录下,在终端输入以下命令:

gltf-pipeline -i scene.gltf -o car.gltf -d

如图:

然后我们发现模型目录下多了一个压缩之后的car.gltf的文件:

3、生成js

在终端继续输入以下命令:

npx gltfjsx car.gltf

这个过程需要等待一小会儿:

然后在模型目录下,我们看到了生成的js文件:

我们可以打开Car.js文件:

/*
Auto-generated by: https://github.com/pmndrs/gltfjsx
author: All-Wide (https://sketchfab.com/dsm350)
license: CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/)
source: https://sketchfab.com/3d-models/nissan-idx-nismo-258e8dca96404ab8b450c75cd110b5b6
title: Nissan IDX Nismo
*/import React, { useRef } from 'react'
import { useGLTF } from '@react-three/drei'export default function Model({ ...props }) {const group = useRef()const { nodes, materials } = useGLTF('/car.gltf')return (<group ref={group} {...props} dispose={null}><group rotation={[-Math.PI / 2, 0, 0]}><group rotation={[Math.PI / 2, 0, 0]}><group position={[0.03, 0.01, -0.06]} rotation={[Math.PI / 2, 0, 0]} scale={[0.6, 0.6, 0.6]}><mesh geometry={nodes.Object_4.geometry} material={nodes.Object_4.material} /></group><group position={[0.03, 0.01, -0.06]} rotation={[Math.PI / 2, 0, 0]} scale={[0.6, 0.6, 0.6]}><mesh geometry={nodes.Object_6.geometry} material={nodes.Object_6.material} /></group><group position={[0.03, 0.01, -0.06]} rotation={[Math.PI / 2, 0, 0]} scale={[0.6, 0.6, 0.6]}><mesh geometry={nodes.Object_8.geometry} material={nodes.Object_8.material} /></group><group position={[0.03, 0.01, -0.06]} rotation={[Math.PI / 2, 0, 0]} scale={[0.6, 0.6, 0.6]}><mesh geometry={nodes.Object_10.geometry} material={nodes.Object_10.material} /></group><group position={[0.03, 0.01, -0.06]} rotation={[Math.PI / 2, 0, 0]} scale={[0.6, 0.6, 0.6]}><mesh geometry={nodes.Object_12.geometry} material={nodes.Object_12.material} /></group><group position={[0.03, 0.01, -0.06]} rotation={[Math.PI / 2, 0, 0]} scale={[0.6, 0.6, 0.6]}><mesh geometry={nodes.Object_14.geometry} material={nodes.Object_14.material} /></group><group position={[0.03, 0.01, -0.06]} rotation={[Math.PI / 2, 0, 0]} scale={[0.6, 0.6, 0.6]}><mesh geometry={nodes.Object_16.geometry} material={nodes.Object_16.material} /></group><group position={[0.03, 0.01, -0.06]} rotation={[Math.PI / 2, 0, 0]} scale={[0.6, 0.6, 0.6]}><mesh geometry={nodes.Object_18.geometry} material={nodes.Object_18.material} /></group><group position={[0.03, 0.01, -0.06]} rotation={[Math.PI / 2, 0, 0]} scale={[0.6, 0.6, 0.6]}><mesh geometry={nodes.Object_20.geometry} material={nodes.Object_20.material} /></group><group position={[0.03, 0.01, -0.06]} rotation={[Math.PI / 2, 0, 0]} scale={[0.6, 0.6, 0.6]}><mesh geometry={nodes.Object_22.geometry} material={nodes.Object_22.material} /></group><group position={[0.03, 0.01, -0.06]} rotation={[Math.PI / 2, 0, 0]} scale={[0.6, 0.6, 0.6]}><mesh geometry={nodes.Object_24.geometry} material={materials['Material.001']} /></group><group position={[0.03, 0.01, -0.06]} rotation={[Math.PI / 2, 0, 0]} scale={[0.6, 0.6, 0.6]}><mesh geometry={nodes.Object_26.geometry} material={nodes.Object_26.material} /></group><group position={[0.03, 0.01, -0.06]} rotation={[Math.PI / 2, 0, 0]} scale={[0.6, 0.6, 0.6]}><mesh geometry={nodes.Object_28.geometry} material={nodes.Object_28.material} /></group><group position={[0.03, 0.01, -0.06]} rotation={[Math.PI / 2, 0, 0]} scale={[0.6, 0.6, 0.6]}><mesh geometry={nodes.Object_30.geometry} material={nodes.Object_30.material} /></group><group position={[0.03, 0.01, -0.06]} rotation={[Math.PI / 2, 0, 0]} scale={[0.6, 0.6, 0.6]}><mesh geometry={nodes.Object_32.geometry} material={materials.Chocofur_Free_Car_02_Glass_01} /></group><group position={[0.03, 0.01, -0.06]} rotation={[Math.PI / 2, 0, 0]} scale={[0.6, 0.6, 0.6]}><mesh geometry={nodes.Object_34.geometry} material={nodes.Object_34.material} /></group><group position={[0.03, 0.01, -0.06]} rotation={[Math.PI / 2, 0, 0]} scale={[0.6, 0.6, 0.6]}><mesh geometry={nodes.Object_36.geometry} material={nodes.Object_36.material} /></group><group position={[0.03, 0.01, -0.06]} rotation={[Math.PI / 2, 0, 0]} scale={[0.6, 0.6, 0.6]}><mesh geometry={nodes.Object_38.geometry} material={nodes.Object_38.material} /></group><group position={[0.42, 0, -0.77]} rotation={[Math.PI / 2, 0.08, 0]} scale={[0.04, 0.03, 0.03]}><mesh geometry={nodes.Object_40.geometry} material={nodes.Object_40.material} /><mesh geometry={nodes.Object_41.geometry} material={nodes.Object_41.material} /><mesh geometry={nodes.Object_42.geometry} material={nodes.Object_42.material} /><mesh geometry={nodes.Object_43.geometry} material={nodes.Object_43.material} /></group><group position={[0.56, 0.01, -0.78]} rotation={[Math.PI / 2, 0.08, 0]} scale={[0.82, 0.58, 0.58]}><mesh geometry={nodes.Object_45.geometry} material={nodes.Object_45.material} /></group><group position={[0.48, 0, -0.77]} rotation={[-3.12, 0, -1.65]} scale={[0.18, 0.22, 0.18]}><mesh geometry={nodes.Object_47.geometry} material={nodes.Object_47.material} /></group><group position={[-0.38, -0.01, -0.77]} rotation={[-Math.PI / 2, 0.15, Math.PI]} scale={[0.04, 0.03, 0.03]}><mesh geometry={nodes.Object_49.geometry} material={nodes.Object_49.material} /><mesh geometry={nodes.Object_50.geometry} material={nodes.Object_50.material} /><mesh geometry={nodes.Object_51.geometry} material={nodes.Object_51.material} /><mesh geometry={nodes.Object_52.geometry} material={nodes.Object_52.material} /></group><group position={[-0.52, 0.01, -0.78]} rotation={[-Math.PI / 2, 0.15, -Math.PI]} scale={[0.82, 0.58, 0.58]}><mesh geometry={nodes.Object_54.geometry} material={nodes.Object_54.material} /></group><group position={[-0.44, 0, -0.77]} rotation={[3.12, 0, 1.72]} scale={[0.18, 0.22, 0.18]}><mesh geometry={nodes.Object_56.geometry} material={nodes.Object_56.material} /></group><group position={[-0.39, -0.01, 0.74]} rotation={[-Math.PI / 2, 0.06, -Math.PI]} scale={[0.03, 0.03, 0.03]}><mesh geometry={nodes.Object_58.geometry} material={nodes.Object_58.material} /><mesh geometry={nodes.Object_59.geometry} material={nodes.Object_59.material} /><mesh geometry={nodes.Object_60.geometry} material={nodes.Object_60.material} /><mesh geometry={nodes.Object_61.geometry} material={nodes.Object_61.material} /></group><group position={[-0.51, 0, 0.74]} rotation={[-Math.PI / 2, 0.06, -Math.PI]} scale={[0.72, 0.58, 0.58]}><mesh geometry={nodes.Object_63.geometry} material={nodes.Object_63.material} /></group><group position={[-0.43, 0, 0.75]} rotation={[3.12, 0, 1.63]} scale={[0.18, 0.19, 0.18]}><mesh geometry={nodes.Object_65.geometry} material={nodes.Object_65.material} /></group><group position={[0.44, 0, 0.74]} rotation={[Math.PI / 2, 0.06, 0]} scale={[0.03, 0.03, 0.03]}><mesh geometry={nodes.Object_67.geometry} material={nodes.Object_67.material} /><mesh geometry={nodes.Object_68.geometry} material={nodes.Object_68.material} /><mesh geometry={nodes.Object_69.geometry} material={nodes.Object_69.material} /><mesh geometry={nodes.Object_70.geometry} material={nodes.Object_70.material} /></group><group position={[0.56, 0, 0.74]} rotation={[Math.PI / 2, 0.06, 0]} scale={[0.72, 0.58, 0.58]}><mesh geometry={nodes.Object_72.geometry} material={nodes.Object_72.material} /></group><group position={[0.48, 0, 0.75]} rotation={[-3.12, 0, -1.63]} scale={[0.18, 0.19, 0.18]}><mesh geometry={nodes.Object_74.geometry} material={nodes.Object_74.material} /></group><group position={[0.18, 0.3, -1.27]} rotation={[1.43, 0, -1.56]} scale={[-0.05, 0.05, 0.05]}><mesh geometry={nodes.Object_76.geometry} material={materials['Material.003']} /></group><group position={[0.18, 0.3, -1.27]} rotation={[1.43, 0, -1.56]} scale={[-0.05, 0.05, 0.05]}><mesh geometry={nodes.Object_78.geometry} material={nodes.Object_78.material} /></group><group position={[0.18, 0.3, -1.27]} rotation={[1.43, 0, -1.56]} scale={[-0.05, 0.05, 0.05]}><mesh geometry={nodes.Object_80.geometry} material={nodes.Object_80.material} /></group><group position={[0.18, 0.3, -1.27]} rotation={[1.43, 0, -1.56]} scale={[-0.05, 0.05, 0.05]}><mesh geometry={nodes.Object_82.geometry} material={nodes.Object_82.material} /></group><group position={[0.03, 0.01, -0.06]} rotation={[Math.PI / 2, 0, 0]} scale={[0.6, 0.6, 0.6]}><mesh geometry={nodes.Object_84.geometry} material={nodes.Object_84.material} /></group></group></group></group>)
}useGLTF.preload('/car.gltf')

最后我们将car.gltf模型文件放在public目录下,注意千万不要放错。然后将Car.js文件放在src目录下。

3.4 显示3D模型

回到App.js文件中:

引入Car模型:

import Car from "./Car.js"

并将它添加到Canvas中:

export default function App() {return (<Wrapper className="App"><Canvas className="canvas"><Car /></Canvas></Wrapper>);
}

但是此时页面上并没有显示这辆车,因为缺少灯光。我们添加一下灯光,再添加一下控制,让车能动起来,再修改一下背景颜色。最终代码如下;


import './App.css';
import styled from "styled-components";
import { Canvas } from '@react-three/fiber';
import Car from "./Car.js"
import { OrbitControls } from "@react-three/drei";
import React, { Suspense } from "react";export default function App() {return (<Wrapper className="App"><Canvas className="canvas"><OrbitControls /><ambientLight intensity={0.5} /><directionalLight position={[-2, 5, 2]} intensity={1} /><Suspense fallback={null}><Car /></Suspense></Canvas></Wrapper>);
}const Wrapper = styled.div`position: relative;background: #333333;canvas {width:100vw;height: 100vh;}
`;

终端执行命令:

npm start

效果图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-50NSPaP8-1645152959627)(https://img.chengxuka.com/WX20220217-164800@2x.png)]

滑动鼠标滚轴,车可以变大变小,点按鼠标可以转动车的方向。

1、Three.js 实现元宇宙汽车 3D 模型(网络)相关推荐

  1. 全国首次!元宇宙真人3D数字人庆祝杭州国际商会元宇宙专委会成立

    6月8日,杭州市国际商会.中国移动杭州分公司等共同发起成立了杭州市国际商会元宇宙专业委员会(以下简称"元宇宙专委会"),杭州市人民政府副市长胡伟等领导发言,浙江大学计算机创新技术研 ...

  2. OpenUSD联盟:塑造元宇宙的3D未来

    一.引言 近日,美国3D内容行业的五家主要公司苹果.英伟达.皮克斯.Adobe和Autodesk联合成立了OpenUSD联盟(AOUSD).这一联盟的成立标志着元宇宙领域的一次重要合作,旨在制定元宇宙 ...

  3. 【学习笔记】元宇宙:虚实相生的网络世界

    混沌大学 2021.12.04+元宇宙:虚实相生的网络世界(问答部分补充) 原文 元宇宙的语言和趋势分析 未来已来 没有job照样work 清华女生华智冰 元宇宙必然到来 从在线到在场 大规模.远距离 ...

  4. 【Android界面实现】可旋转的汽车3D模型效果的实现

    转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992 今天要给大家介绍的是如何实现可旋转的汽车3D模型. 先看实现效果 这只是静态图,实际上,这个模型是可以根据手 ...

  5. 可旋转的汽车3D模型效果的实现

     转载请注明出处: http://blog.csdn.net/zhaokaiqiang1992 今天要给大家介绍的是如何实现可旋转的汽车3D模型. 先看实现效果 这只是静态图,实际上,这个模型是可 ...

  6. 元宇宙——定向未来的网络服务:最新技术动向调研

    元宇宙的概念 元宇宙的特点 管理技术 人体姿势与眼球追踪 Metaverse 是一组相互连接的.体验式的 3D 虚拟世界,身处任何地方的人都可以实时社交,形成一个横跨数字世界和物理世界的持久的.用户所 ...

  7. 莫把“李鬼”当成“李逵”,警惕元宇宙、区块链网络陷阱

    随着元宇宙.区块链.数字藏品(NFT)等概念不断被炒热,这些新技术就成为了一些诈骗团伙的新"画皮",3月15日,北京银保监局对大学生群体发布风险提示,提到骗局的四大套路,包括网络平 ...

  8. Web 3D VS Native 3D是未来元宇宙

    这些都是元宇宙的概念,3D 世界.虚拟社交.虚拟购物.沉浸,通过 AR/VR 以及其他互联网技术,把现实世界的楼房街道.天气温度.人际关系等投射到虚拟世界,构建 "元宇宙". 3D ...

  9. 人类未来将毁于元宇宙?刘慈欣向往星辰大海,小扎却要深耕Meta

    转自:新智元 「三体」的预告片你看了吗? 简单来说,这个作品讲述的是人类文明与三体文明的信息交流,生死存亡,还有两个文明在宇宙中的兴衰历程. 关于人类未来的发展,刘慈欣曾在「不能共存的节日」中提到飞船 ...

最新文章

  1. plotly可视化表格数据:以表格可视化pandas dataframe
  2. bzoj3141: [Hnoi2013]旅行
  3. 住过一晚两万的ICU后,我还是建议你不要轻易买保险
  4. npz文件转为npy_numpy的文件存储 .npy .npz 文件
  5. checkPathValidity 检查所有agent的corridor的m_path是否有效
  6. 8255编程c语言程序,51单片机8255驱动C程序
  7. map写法 scala语言_(转)scala中map与flatMap浅析
  8. ImageMagick 安装 window10与错误总结
  9. 后副车架焊接机器人_焊接机器人的工装设计和工装的使用方法
  10. c语言中的钩子函数,生命周期(vue的钩子函数)
  11. 3月3日 单灭点、双灭点、单应矩阵求解相机姿态,世界坐标-相机坐标-图像坐标-像素坐标四个坐标系的变换关系,通过Vanishing Points计算焦距和像心
  12. Linux操作系统应用领域详解
  13. 各个国家/地区以及对应的手机区号
  14. 一些音视频相关概念学习笔记
  15. 【web】PHP网页调用Matlab代码的实现以及一些需要注意的bug~
  16. 小鹤双拼提速方法个人经验-by老随风
  17. Android中访问sdcard路径的几种方式
  18. 暴跌27%!科通芯城遭沽空机构狙击 被指“横跨十年的世纪骗案”
  19. 标点符号的英文读写搜集(二)中英文标点符号的读法用法大全
  20. 省钱利器 0 成本创业 高佣联盟APP

热门文章

  1. ATtiny13与Proteus仿真-TM1637简单时钟仿真
  2. 小马赠书【第7期】清华出版社 IT BOOK 多得活动(送书5本)
  3. 三自由度无人机飞手培训、PID调试、飞行教学、飞控算法验证、故障仿真平台
  4. Linux忘记root密码如何找回
  5. 我是如何在硅谷获得年薪30万美金Offer的?
  6. Adobe Creative Suite 2 精彩创意广告和精美图标
  7. 球栅尺光栅尺磁栅尺编码器脉冲计数器数据采集模块
  8. html表单输入框分割成三个,Go Web开发三:HTML表单
  9. 一加账号app_一加云服务app-一加云服务登录平台v1.0 安卓版 - 极光站
  10. 提高服务器安全性能的方式