文章目录
- 前言
- 一、threejs引入3d模型(html版本)
- 1. 完整代码
- 2. 代码详解
- 二、react fiber引入3d模型(react fiber版本)
- 1.代码详解
- 1.1 引入3d模型的资源
- 问题一:为什么“资源必须放在public文件夹下”?
- 问题二:引入 public 文件夹下的图片显示不出来?
- 问题三:无法加载 public 文件夹下的3D模型?
- 1.2 需要引入的js文件
- 1.3 使用3d模型
前言
本文将从threejs引入3d模型讲起,到react fiber引入3d模型结束。
一、threejs引入3d模型(html版本)
1. 完整代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>3D人像</title> </head> <body> <script src="../libs/build/three.min.js"></script> <script src="../libs/jsm/loaders/GLTFLoader.js"></script> <script src="../libs/jsm/controls/OrbitControls.js"></script> <script src="../libs/jsm/Clock.js"></script> <script> // import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"; let scene, camera, renderer, controls; var root; function initScene() { //场景 scene = new THREE.Scene(); // 创建一个纹理图片加载器加载图片 var textureLoader = new THREE.TextureLoader(); // 加载背景图片 var texture = textureLoader.load('../images/background.jpg'); // 纹理对象Texture赋值给场景对象的背景属性.background scene.background = texture; } function initCamera() { //相机 camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 200); camera.position.set(0, 15, 50); } function initRenderer() { //渲染器 renderer = new THREE.WebGLRenderer({ antiallias: true }); //设置渲染区域尺寸 renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); } function initHilght() { //环境光 hilght = new THREE.AmbientLight(0x404040, 10); scene.add(hilght); } function initPeople() { //导入3D模型 let loader = new THREE.GLTFLoader(); loader.load( '../models/herbalist/scene.gltf', function (gltf) { root = gltf.scene; //模型大小 root.scale.set(0.5, 0.5, 0.5); //初始位置 root.translateX(-10); scene.add(root); renderer.render(scene, camera); }); } //渲染 function render() { renderer.render(scene, camera);//执行渲染操作 requestAnimationFrame(render);//请求再次执行渲染函数render } function initControl() { controls = new THREE.OrbitControls(camera, renderer.domElement) //监听控制器的鼠标事件,执行渲染内容 controls.addEvemtListener('change', () => { renderer.render(scene, camera) }) } function initLine() { var geometry = new THREE.BufferGeometry(); //声明一个几何体对象Geometry //参数:0, 0圆弧坐标原点x,y 100:圆弧半径 0, 2 * Math.PI:圆弧起始角度 var arc = new THREE.ArcCurve(0, 20, 15, 10, 1 * Math.PI); //getPoints是基类Curve的方法,返回一个vector2对象作为元素组成的数组 var points = arc.getPoints(50);//分段数50,返回51个顶点 // setFromPoints方法从points中提取数据改变几何体的顶点属性vertices geometry.setFromPoints(points); //材质对象 var material = new THREE.LineBasicMaterial({ color: 0xffffff }); //线条模型对象 var line = new THREE.Line(geometry, material); scene.add(line); //线条对象添加到场景中 } function init() { initScene(); initCamera(); initRenderer(); initPeople(); initLine(); initHilght(); render(); } init(); </script> </body> </html>
2. 代码详解
首先参考threejs官方文档中,引入3d模型的内容:
- 官方文档链接: Loading 3D models
关键代码:
- 引入js文件
1
2<script src="../libs/jsm/loaders/GLTFLoader.js"></script>
- 按格式引入gltf文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18function initPeople() { //导入3D模型 let loader = new THREE.GLTFLoader(); loader.load( '../models/herbalist/scene.gltf', function (gltf) { root = gltf.scene; //模型大小 root.scale.set(0.5, 0.5, 0.5); //初始位置 root.translateX(-10); scene.add(root); renderer.render(scene, camera); }); }
二、react fiber引入3d模型(react fiber版本)
1.代码详解
查看drei官方文档
如图所示,是useGLTF的用法/语法:
1.1 引入3d模型的资源
注意:
- 引入资源必须放在public文件夹下,否则会引入失败。(报错如图)
问题一:为什么“资源必须放在public文件夹下”?
引入知识点:
在React中有个Public文件夹可以放静态资源,但是在src目录中同样有个assets文件夹,这个同样也是放静态资源的,这个就很困惑了,为何放置静态资源的地方会有两个?
原因如下:
两者区别就在于是否会被webpack所处理。
- Public文件夹放静态资源
如果您将文件放入该public文件夹,webpack 将不会处理它,在你打包的时候,会将public文件夹直接复制一份到你构建出来的文件夹中。
好处:把一些不会改动的静态文件放到public中,可以:
- 减少文件构建时间,减少构建文件的大小
- 避免首页白屏时间过长
- src目录中assets文件夹放静态资源
资源会被webpack编译,比如图片,如果你的图片小于你在webpack中的loader下设置的limit大小(可配置),它会被编译成base64,从而在实际项目中减少http请求,放置在src/assets目录有以下几点好处:
- 脚本和样式表被缩小并捆绑在一起以避免额外的网络请求。
- 缺少文件会导致编译错误,而不是用户的404错误。
- 结果文件名包含内容哈希,因此您无需担心浏览器缓存旧版本。
问题二:引入 public 文件夹下的图片显示不出来?
注意!!该问题仅限于解决图片加载问题。
- 出现错误如图:无法加载public下的图片文件
- 解决办法:
- 在node_module文件夹下找到react-script/config/webpack.config.js,找到相应代码注释掉,然后重新启动项目,问题解决。(可以ctrl+f查找ModuleScopePlugin 相关的代码)
1
2
3
4
5
6
7const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin'); new ModuleScopePlugin(paths.appSrc, [ paths.appPackageJson, reactRefreshOverlayEntry, ]),
问题三:无法加载 public 文件夹下的3D模型?
报错如图所示:models文件夹在public下,但是引用public下的models文件夹,3d模型引入失败,如图一,路径不存在,却可以引入成功(该问题仍未解决)
引入3d模型的完整代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20import { useLoader } from '@react-three/fiber' import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader' export function Man(){ const gltf = useLoader(GLTFLoader,'../../models/table_scene/girl/scene.gltf'); return( <> <primitive object={gltf.scene} position={[3,18,0]} rotation={[Math.PI/2, 0, 0]} scale={3} /> </> ); }
1.2 需要引入的js文件
1
2
3import { useLoader } from '@react-three/fiber' import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
1.3 使用3d模型
在需要使用3d模型的js文件中,用标签形式引用。
例如:我将3d模型建在man.jsx文件中的function Man()
函数中,引用时,
第一步:import { Man } from "../table/man"
第二步:
1
2
3
4
5
6
7<Canvas> {/* 3d模型放置 */} <Table position={[0, 0, 0]} /> <Man /> <Canvas/>
最后
以上就是务实镜子最近收集整理的关于react fiber加载gltf文件:3d模型前言一、threejs引入3d模型(html版本)二、react fiber引入3d模型(react fiber版本)的全部内容,更多相关react内容请搜索靠谱客的其他文章。
发表评论 取消回复