快捷搜索:  汽车  科技

元宇宙和虚拟现实有什么区别(实现元宇宙汽车)

元宇宙和虚拟现实有什么区别(实现元宇宙汽车)npm install @react-three/dreinpm install @react-three/fibernpm install --save three@react-three/fiber@react-three/drei

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项目,效果如下:

元宇宙和虚拟现实有什么区别(实现元宇宙汽车)(1)

二、项目搭建2.1 首先在本地创建一个react项目

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

create-react-app car-demo01

元宇宙和虚拟现实有什么区别(实现元宇宙汽车)(2)

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

元宇宙和虚拟现实有什么区别(实现元宇宙汽车)(3)

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

结构如下:

元宇宙和虚拟现实有什么区别(实现元宇宙汽车)(4)

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

如图:

元宇宙和虚拟现实有什么区别(实现元宇宙汽车)(5)

接下来可以直接使用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

如图:

元宇宙和虚拟现实有什么区别(实现元宇宙汽车)(6)

npm install @react-three/drei

如图:

元宇宙和虚拟现实有什么区别(实现元宇宙汽车)(7)

三、代码实现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

如图:

元宇宙和虚拟现实有什么区别(实现元宇宙汽车)(8)

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

App.js下的代码如下:

brimport './App.css';brimport styled from "styled-components";brbrexport default function App() {br return (br <Wrapper className="App">br HelloWorldbr </Wrapper>br );br}brbrconst Wrapper = styled.div`br position: relative;br background: #ff0000;br`;

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

npm start

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

元宇宙和虚拟现实有什么区别(实现元宇宙汽车)(9)

3.2 添加 Canvas

首先在头部引入Canvas:

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

然后我们在Wrapper里面添加

代码如下:

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; `; 3.3 导入3D模型

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

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

元宇宙和虚拟现实有什么区别(实现元宇宙汽车)(10)

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

元宇宙和虚拟现实有什么区别(实现元宇宙汽车)(11)

接下来你可以按照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

元宇宙和虚拟现实有什么区别(实现元宇宙汽车)(12)

2、gltf转换:

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

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

如图:

元宇宙和虚拟现实有什么区别(实现元宇宙汽车)(13)

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

元宇宙和虚拟现实有什么区别(实现元宇宙汽车)(14)

3、生成js

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

npx gltfjsx car.gltf

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

元宇宙和虚拟现实有什么区别(实现元宇宙汽车)(15)

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

元宇宙和虚拟现实有什么区别(实现元宇宙汽车)(16)

我们可以打开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目录下。

元宇宙和虚拟现实有什么区别(实现元宇宙汽车)(17)

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

效果图:

元宇宙和虚拟现实有什么区别(实现元宇宙汽车)(18)

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

猜您喜欢: