Vue集成three.js并加载glb、gltf、FBX、json模型的场景分析

目录
  • 先上几个网址
  • 安装
  • 组件中引入
  • 基本使用
  • 补充

最近刚开始做的一个项目,后面有个模块要通过three.js实现3D的场景,因为之前也没接触过3D这块,就提前学了一下,做个记录。

先上几个网址

ThreeJS官方:http://www.thingjs.com/guide/city2/

ThreeJS文档https://threejs.org/docs/index.html#manual/en/introduction/Creating-a-scene

免费模型网:https://glbxz.com/err/search.php?keyword=%E5%85%8D%E8%B4%B9

接下来就我做的一个demo开始

安装

  1. npm i three
  2. npm i threeorbitcontrols
  3. npm i stats.js // 性能监测

组件中引入

  1. import * as THREE from ‘three’
  2. import * as Stats from ‘stats.js’
  3. import OrbitControls from ‘three-orbitcontrols’
  4. import { GLTFLoader } from ‘three/examples/jsm/loaders/GLTFLoader’
  5. import { DRACOLoader } from ‘three/examples/jsm/loaders/DRACOLoader.js’
  6. import { FBXLoader } from ‘three/examples/jsm/loaders/FBXLoader.js’

基本使用

1.创建场景

  1. this.scene = new THREE.Scene();

2.相机

  1. this.camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 1000);
  2. // 设置摄像机位置,相机方向逆X轴方向,倾斜向下看
  3. this.camera.position.set(360, 360, 360);
  4. // 指向场景中心
  5. this.camera.lookAt(this.scene.position);

3. 渲染器

  1. this.renderer = new THREE.WebGLRenderer({ antialias: true });
  2. // 设置环境
  3. this.renderer.setClearColor(new THREE.Color(“#f1f9fb”));
  4. // 设置场景大小
  5. this.renderer.setSize(window.innerWidth / window.innerHeight);
  6. // 渲染器开启阴影效果
  7. this.renderer.shadowMap.enabled = true;

4.创建纹理加载器

  1. this.textureLoader = new THREE.TextureLoader();

5.创建组合对象

加载外部模型的时候,基本上都是一个组合对象,因为外部模型都是比较大的,把零散的模型组合到一块便于操作,可以使用THREE.Group来操作一组对象,包括旋转,缩放,移动等,里面的子对象都会受到影响。THREE.Group继承自THREE.Object3D对象,并且和THREE.Object3D对象没有任何区别,仅仅是名字上的差异

  1. this.groupBox = new THREE.Group();

6.添加坐标轴,辅助判断位置

  1. let axes = new THREE.AxesHelper(1000);
  2. this.scene.add(axes);

7.点光源

  1. // 点光源
  2. let point = new THREE.PointLight(0xffffff);
  3. point.position.set(500, 300, 400); // 点光源位置
  4. this.scene.add(point); // 点光源添加到场景中

8.环境光

  1. // 环境光
  2. let ambient = new THREE.AmbientLight(0x999999);
  3. this.scene.add(ambient);

9.性能监测

  1. //创建性能监测
  2. this.stats = new Stats()
  3. this.stats.showPanel(0) // 0: fps, 1: ms, 2: mb, 3+: custom
  4. this.stats.domElement.style.position = ‘absolute’; //绝对坐标 this.stats.domElement.style.left = ‘0px’;// (0,0)px,左上角
  5. this.stats.domElement.style.top = ‘0px’;
  6. $(‘#stats’).appendChild(this.stats.domElement)

10.相机控件

  1. //创建相机控件
  2. this.control = new OrbitControls(this.camera, this.renderer.domElement)
  3. this.control.enableDamping = true
  4. // 动态阻尼系数 就是鼠标拖拽旋转灵敏度,阻尼越小越灵敏
  5. this.control.dampingFactor = 0.5;
  6. // 是否可以缩放
  7. this.control.enableZoom = true;
  8. // 是否自动旋转
  9. this.control.autoRotate = false;
  10. // 设置相机距离原点的最近距离
  11. this.control.minDistance = 20;
  12. // 设置相机距离原点的最远距离
  13. this.control.maxDistance = 1000;
  14. // 是否开启右键拖拽
  15. this.control.enablePan = true;
  16. // 上下翻转的最大角度
  17. this.control.maxPolarAngle = 1.5;
  18. // 上下翻转的最小角度
  19. this.control.minPolarAngle = 0.0;
  20. // 是否可以旋转
  21. this.enableRotate = true;

11.渲染canvas到容器

  1. $(‘#container’).appendChild(this.renderer.domElement);

12.加载glb、gltf模型

  1. loadGlbModel() {
  2. const loader = new GLTFLoader()
  3. // const dracoLoader = new DRACOLoader()
  4. // dracoLoader.setDecoderPath(‘/draco/’)
  5. // dracoLoader.preload()
  6. // loader.setDRACOLoader(dracoLoader)
  7. loader.load(`${this.publicPath}model/12OJJ6MOWT722N61Z5N92KA9C.glb`, (gltf) => {
  8. console.log(gltf, ‘gltf—–>>>’)
  9. gltf.scene.scale.set(100,100,100) // 设置模型大小缩放
  10. gltf.scene.position.set(0,0,0)
  11. let axis = new THREE.Vector3(0,1,0);//向量axis
  12. gltf.scene.rotateOnAxis(axis,Math.PI/2);
  13. //绕axis轴逆旋转π/16
  14. gltf.scene.rotateOnAxis(axis,Math.PI/-20);
  15. gltf.scene.rotateOnAxis(axis,Math.PI/50);
  16. // gltf.rotateY(Math.PI / 2);
  17. // this.groupBox.add(gltf);
  18. this.scene.add(gltf.scene)
  19. }, (xhr) => {
  20. console.log((xhr.loaded / xhr.total) * 100 + ‘% loaded’)
  21. }, (error) => {
  22. console.error(error)
  23. })
  24. },

13.加载FBX模型

  1. // 加载 FBX 模型
  2. loadFbxModel() {
  3. const loader = new FBXLoader();
  4. loader.load(`${this.publicPath}model/glbxz.com6031.FBX`, object => {//加载路径fbx文件
  5. console.log(object, ‘object—–>>>’)
  6. object.traverse( child => {
  7. if ( child.isMesh ){
  8. child.castShadow = true;
  9. child.receiveShadow = true;
  10. }
  11. });
  12. this.scene.add(object);//模型
  13. })
  14. },

14.加载json模型

  1. //加载 JSON格式 模型
  2. loadJsonModel() {
  3. //设置相机位置
  4. this.camera.position.z = 130
  5. this.camera.position.y = 80
  6. const loader = new THREE.ObjectLoader()
  7. loader.load(`${this.publicPath}model/xxxx.json`, json => {
  8. //处理加载模型为黑色问题
  9. json.traverse(child => {
  10. if (child.isMesh) {
  11. child.material.emissive = child.material.color
  12. child.material.emissiveMap = child.material.map
  13. }
  14. })
  15. this.scene.add(group)
  16. }, xhr => {
  17. // called while loading is progressing
  18. console.log(`${( xhr.loaded / xhr.total * 100 )}% loaded`);
  19. }, error => {
  20. // called when loading has errors
  21. console.error(‘An error happened’, error);
  22. })
  23. },

15.创建材质

  1. // 创建材质
  2. createMaterial() {
  3. // 创建三维用到的材质
  4. /**
  5. *
  6. * MeshBasicMaterial: 网格基础材质
  7. * MeshDepthMaterial: 网格深度材质
  8. * MeshNormalMaterial: 网格法向材质
  9. * MeshLambertMaterial: 网格Lambert 材质
  10. * MeshPhongMaterial: 网格 Phong式材质
  11. * MeshStandardMaterial: 网格标准材质
  12. * MeshPhysicalMaterial: 网格物理材质
  13. * MeshToonMaterial: 网格卡通材质
  14. * ShadowMaterial: 阴影材质
  15. * ShaderMaterial: 着色器材质
  16. * LineBasicMaterial: 直线基础材质
  17. * LineDashMaterial: 虚线材质
  18. */
  19. // 外墙
  20. let wallMaterial = new THREE.MeshLambertMaterial({ color: 0x00ffff });
  21. let wallGeo = new THREE.BoxGeometry(439 + 2 + 2, 120, 376.5 + 2 + 2); // 创建几何体
  22. let wallMesh = new THREE.Mesh(wallGeo, wallMaterial);
  23. wallMesh.position.set(0, 60, 0); //(0, 60, -14.95);
  24. this.scene.add(wallMesh) // 添加结果到场景中
  25. // 内墙
  26. let wallInnerMaterial = new THREE.MeshLambertMaterial({
  27. color: 0x2d1bff,
  28. });
  29. let wallInnerGeo = new THREE.BoxGeometry(439, 120, 376.5); //(270, 120, 390);
  30. let wallInnerMesh = new THREE.Mesh(wallInnerGeo, wallInnerMaterial);
  31. wallInnerMesh.position.set(0, 60, 0); //(0, 60, -14.95);
  32. this.scene.add(wallInnerMesh) // 添加结果到场景中
  33. // 门
  34. let doorTexture = this.textureLoader.load(
  35. require(“../../../../assets/img/1.png”) // 暂时注掉
  36. );
  37. let boxTextureMaterial = new THREE.MeshStandardMaterial({
  38. map: doorTexture,
  39. metalness: 0.2,
  40. roughness: 0.07,
  41. side: THREE.DoubleSide,
  42. });
  43. //let doorInnerMaterial = new THREE.MeshLambertMaterial({color: 0x2D1BFF});
  44. let doorGeo = new THREE.BoxGeometry(2, 80, 74.5);
  45. let doorMesh = new THREE.Mesh(doorGeo, boxTextureMaterial);
  46. doorMesh.position.set(-220.5, 40, 0);
  47. this.scene.add(doorMesh); // 添加结果到场景中
  48.  
  49. /**
  50. * threeBSP – 引用还有问题
  51. */
  52. // //转BSP
  53. // let wallBSP = new ThreeBSP(wallMesh);
  54. // let wallInnerBSP = new ThreeBSP(wallInnerMesh);
  55. // let doorBSP = new ThreeBSP(doorMesh);
  56. // // let window1BSP = new ThreeBSP(this.createWindowRight());
  57. // //let window2BSP = new ThreeBSP(this.createWindowRight());// createWindowLeft
  58. // let wallResultBSP = wallBSP.subtract(wallInnerBSP);
  59. // wallResultBSP = wallResultBSP.subtract(doorBSP);
  60. // // wallResultBSP = wallResultBSP.subtract(window1BSP);
  61. // //wallResultBSP = wallResultBSP.subtract(window2BSP);
  62. // let wallResultMesh = wallResultBSP.toMesh();
  63.  
  64. // //转换后的Mesh配置属性
  65. // let wallTexture = this.textureLoader.load(require(“../../../../assets/img/3.jpg”)); // 暂时注掉
  66. // let wallTextureMaterial = new THREE.MeshStandardMaterial({
  67. // map: wallTexture,
  68. // metalness: 0.2,
  69. // roughness: 0.07,
  70. // side: THREE.DoubleSide,
  71. // });
  72. // let wallInnerTexture = this.textureLoader.load(
  73. // require(“../../../../assets/img/6.jpg”) // 暂时注掉
  74. // );
  75. // let wallInnerTextureMaterial = new THREE.MeshStandardMaterial({
  76. // map: wallInnerTexture,
  77. // metalness: 0.2,
  78. // roughness: 0.07,
  79. // side: THREE.DoubleSide,
  80. // });
  81. // let wallResultMeshMaterial = [];
  82. // wallResultMeshMaterial.push(wallTextureMaterial);
  83. // wallResultMeshMaterial.push(wallInnerTextureMaterial);
  84. // //wallResultMeshMaterial.push(boxTextureMaterial);
  85. // wallResultMesh.material = wallResultMeshMaterial;
  86.  
  87. // // console.log(wallResultMesh.geometry.faces, 112233);
  88. // wallResultMesh.geometry.faces.forEach((item, i) => {
  89. // if (i < 160) {
  90. // item.materialIndex = 0;
  91. // } else {
  92. // item.materialIndex = 1;
  93. // }
  94. // });
  95.  
  96. // wallResultMesh.geometry.computeFaceNormals();
  97. // wallResultMesh.geometry.computeVertexNormals();
  98. // //添加结果到场景中
  99. // this.scene.add(wallResultMesh);
  100. },

16.进行渲染

  1. render() {
  2. let animate = () => {
  3. //循环调用函数
  4. this.clearAnim = requestAnimationFrame(animate)
  5. //更新相机控件
  6. this.control.update()
  7. // 更新性能插件
  8. this.stats.update()
  9. //渲染界面
  10. this.renderer.render(this.scene, this.camera)
  11. }
  12. animate()
  13. }

17.为模型绑定事件

这里以点击事件为例

  1. this.renderer.domElement.addEventListener(‘click’, this.modelMouseClick, false)
  1. // 模型的点击事件
  2. modelMouseClick( event ) {
  3. var raycaster = new THREE.Raycaster();
  4. var mouse = new THREE.Vector2();
  5. // 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)
  6. mouse.x = ( event.clientX / window.innerWidth ) * 2 1;
  7. mouse.y = ( event.clientY / window.innerHeight ) * 2 + 1;
  8. raycaster.setFromCamera(mouse, this.camera);
  9. const intersects = raycaster.intersectObjects(this.scene.children);
  10. // 根据它来判断点击的什么,length为0即没有点击到模型
  11. console.log(intersects, ‘intersects—–>>>’)
  12. }

完整代码

  1. <template>
  2. <div id=“import-template”>
  3. <!– 放性能监测的容器 –>
  4. <div id=“stats”></div>
  5. <!– 3D模型容器 –>
  6. <div id=“container”></div>
  7. </div>
  8. </template>
  9.  
  10. <script>
  11. // import ‘@/utils/ThreeBSP.js’ // 不可以这么引
  12. import * as THREE from ‘three’
  13. import * as Stats from ‘stats.js’
  14. // import * as dat from ‘dat.gui’
  15. import OrbitControls from ‘three-orbitcontrols’
  16. import { GLTFLoader } from ‘three/examples/jsm/loaders/GLTFLoader’
  17. import { DRACOLoader } from ‘three/examples/jsm/loaders/DRACOLoader.js’
  18. import { FBXLoader } from ‘three/examples/jsm/loaders/FBXLoader.js’
  19. const $ = name => document.querySelector(name)
  20.  
  21. export default {
  22. data() {
  23. return {
  24. scene: null, // 场景
  25. camera: null, // 照相机
  26. renderer: null, // 渲染器
  27. mesh: null, // 网格
  28. textureLoader: null, // 纹理加载器
  29. mixer: null,
  30. groupBox: null,
  31. stats: null, // 性能监测
  32. control: null, // 相机控件
  33. publicPath: process.env.BASE_URL,
  34. clearAnim: null,
  35. clock: null
  36. }
  37. },
  38. created() {
  39. // this.init()
  40. },
  41. mounted() {
  42. this.init()
  43. },
  44. destroyed() {
  45. cancelAnimationFrame(this.clearAnim) // 清除requestAnimationFrame
  46. this.renderer.domElement.removeEventListener(‘click’, this.modelMouseClick, false)
  47. this.scene = null, // 场景
  48. this.camera = null, // 照相机
  49. this.renderer = null, // 渲染器
  50. this.mesh = null, // 网格
  51. this.textureLoader = null, // 纹理加载器
  52. this.mixer = null,
  53. this.groupBox = null,
  54. this.stats = null, // 性能监测
  55. this.control = null, // 相机控件
  56. this.publicPath = process.env.BASE_URL,
  57. this.clock = null
  58. },
  59. methods: {
  60. //初始化
  61. init() {
  62. // 场景
  63. this.scene = new THREE.Scene();
  64. // 1.2 相机
  65. this.camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 1000);
  66. // 设置摄像机位置,相机方向逆X轴方向,倾斜向下看
  67. this.camera.position.set(360, 360, 360);
  68. //this.camera.position.set(-20, 40 ,30)
  69. // 指向场景中心
  70. this.camera.lookAt(this.scene.position);
  71. // 1.3 渲染器
  72. this.renderer = new THREE.WebGLRenderer({ antialias: true });
  73. // 创建纹理加载器
  74. this.textureLoader = new THREE.TextureLoader();
  75. // 创建一个组合对象
  76. this.groupBox = new THREE.Group();
  77. // 添加坐标轴,辅助判断位置
  78. let axes = new THREE.AxesHelper(1000);
  79. this.scene.add(axes);
  80. // 设置环境
  81. this.renderer.setClearColor(new THREE.Color(“#f1f9fb”));
  82. // 设置场景大小
  83. this.renderer.setSize(
  84. $(‘#container’).getBoundingClientRect().width,
  85. $(‘#container’).getBoundingClientRect().height
  86. );
  87. // 渲染器开启阴影效果
  88. this.renderer.shadowMap.enabled = true;
  89. // 点光源
  90. let point = new THREE.PointLight(0xffffff);
  91. point.position.set(500, 300, 400); // 点光源位置
  92. this.scene.add(point); // 点光源添加到场景中
  93. // 环境光
  94. let ambient = new THREE.AmbientLight(0x999999);
  95. this.scene.add(ambient);
  96.  
  97. //创建性能监测
  98. this.stats = new Stats()
  99. this.stats.showPanel(0) // 0: fps, 1: ms, 2: mb, 3+: custom
  100. this.stats.domElement.style.position = ‘absolute’; //绝对坐标
  101. this.stats.domElement.style.left = ‘0px’;// (0,0)px,左上角
  102. this.stats.domElement.style.top = ‘0px’;
  103. $(‘#stats’).appendChild(this.stats.domElement)
  104.  
  105. // 渲染div到canvas
  106. $(‘#container’).appendChild(this.renderer.domElement);
  107.  
  108. //创建相机控件
  109. this.control = new OrbitControls(this.camera, this.renderer.domElement)
  110. this.control.enableDamping = true
  111. // 动态阻尼系数 就是鼠标拖拽旋转灵敏度,阻尼越小越灵敏
  112. this.control.dampingFactor = 0.5;
  113. // 是否可以缩放
  114. this.control.enableZoom = true;
  115. // 是否自动旋转
  116. this.control.autoRotate = false;
  117. // 设置相机距离原点的最近距离
  118. this.control.minDistance = 20;
  119. // 设置相机距离原点的最远距离
  120. this.control.maxDistance = 1000;
  121. // 是否开启右键拖拽
  122. this.control.enablePan = true;
  123. // 上下翻转的最大角度
  124. this.control.maxPolarAngle = 1.5;
  125. // 上下翻转的最小角度
  126. this.control.minPolarAngle = 0.0;
  127. // 是否可以旋转
  128. this.enableRotate = true;
  129. this.loadGlbModel(); // 加载 glb、gltf模型
  130. // this.loadFbxModel() // 加载 FBX 模型
  131. // this.loadJsonModel() // 加载 json 模型
  132. // this.createMaterial() // 创建材质
  133. // 最后进行渲染
  134. this.render()
  135. },
  136. // 最后的渲染
  137. render() {
  138. let animate = () => {
  139. //循环调用函数
  140. this.clearAnim = requestAnimationFrame(animate)
  141. //更新相机控件
  142. this.control.update()
  143. // 更新性能插件
  144. this.stats.update()
  145. //渲染界面
  146. this.renderer.render(this.scene, this.camera)
  147. }
  148. animate()
  149. // 为模型绑定点击事件
  150. this.renderer.domElement.addEventListener(‘click’, this.modelMouseClick, false)
  151. },
  152. // 创建材质
  153. createMaterial() {
  154. // 创建三维用到的材质
  155. /**
  156. *
  157. * MeshBasicMaterial: 网格基础材质
  158. * MeshDepthMaterial: 网格深度材质
  159. * MeshNormalMaterial: 网格法向材质
  160. * MeshLambertMaterial: 网格Lambert 材质
  161. * MeshPhongMaterial: 网格 Phong式材质
  162. * MeshStandardMaterial: 网格标准材质
  163. * MeshPhysicalMaterial: 网格物理材质
  164. * MeshToonMaterial: 网格卡通材质
  165. * ShadowMaterial: 阴影材质
  166. * ShaderMaterial: 着色器材质
  167. * LineBasicMaterial: 直线基础材质
  168. * LineDashMaterial: 虚线材质
  169. */
  170. // 外墙
  171. let wallMaterial = new THREE.MeshLambertMaterial({ color: 0x00ffff });
  172. let wallGeo = new THREE.BoxGeometry(439 + 2 + 2, 120, 376.5 + 2 + 2); // 创建几何体
  173. let wallMesh = new THREE.Mesh(wallGeo, wallMaterial);
  174. wallMesh.position.set(0, 60, 0); //(0, 60, -14.95);
  175. this.scene.add(wallMesh)
  176. // 内墙
  177. let wallInnerMaterial = new THREE.MeshLambertMaterial({
  178. color: 0x2d1bff,
  179. });
  180. let wallInnerGeo = new THREE.BoxGeometry(439, 120, 376.5); //(270, 120, 390);
  181. let wallInnerMesh = new THREE.Mesh(wallInnerGeo, wallInnerMaterial);
  182. wallInnerMesh.position.set(0, 60, 0); //(0, 60, -14.95);
  183. this.scene.add(wallInnerMesh)
  184. // 门
  185. let doorTexture = this.textureLoader.load(
  186. require(“../../../../assets/img/1.png”) // 暂时注掉
  187. );
  188. let boxTextureMaterial = new THREE.MeshStandardMaterial({
  189. map: doorTexture,
  190. metalness: 0.2,
  191. roughness: 0.07,
  192. side: THREE.DoubleSide,
  193. });
  194. //let doorInnerMaterial = new THREE.MeshLambertMaterial({color: 0x2D1BFF});
  195. let doorGeo = new THREE.BoxGeometry(2, 80, 74.5);
  196. let doorMesh = new THREE.Mesh(doorGeo, boxTextureMaterial);
  197. doorMesh.position.set(-220.5, 40, 0);
  198. this.scene.add(doorMesh);
  199.  
  200. /**
  201. * threeBSP – 引用还有问题
  202. */
  203. // //转BSP
  204. // let wallBSP = new ThreeBSP(wallMesh);
  205. // let wallInnerBSP = new ThreeBSP(wallInnerMesh);
  206. // let doorBSP = new ThreeBSP(doorMesh);
  207. // // let window1BSP = new ThreeBSP(this.createWindowRight());
  208. // //let window2BSP = new ThreeBSP(this.createWindowRight());// createWindowLeft
  209. // let wallResultBSP = wallBSP.subtract(wallInnerBSP);
  210. // wallResultBSP = wallResultBSP.subtract(doorBSP);
  211. // // wallResultBSP = wallResultBSP.subtract(window1BSP);
  212. // //wallResultBSP = wallResultBSP.subtract(window2BSP);
  213. // let wallResultMesh = wallResultBSP.toMesh();
  214.  
  215. // //转换后的Mesh配置属性
  216. // let wallTexture = this.textureLoader.load(require(“../../../../assets/img/3.jpg”)); // 暂时注掉
  217. // let wallTextureMaterial = new THREE.MeshStandardMaterial({
  218. // map: wallTexture,
  219. // metalness: 0.2,
  220. // roughness: 0.07,
  221. // side: THREE.DoubleSide,
  222. // });
  223. // let wallInnerTexture = this.textureLoader.load(
  224. // require(“../../../../assets/img/6.jpg”) // 暂时注掉
  225. // );
  226. // let wallInnerTextureMaterial = new THREE.MeshStandardMaterial({
  227. // map: wallInnerTexture,
  228. // metalness: 0.2,
  229. // roughness: 0.07,
  230. // side: THREE.DoubleSide,
  231. // });
  232. // let wallResultMeshMaterial = [];
  233. // wallResultMeshMaterial.push(wallTextureMaterial);
  234. // wallResultMeshMaterial.push(wallInnerTextureMaterial);
  235. // //wallResultMeshMaterial.push(boxTextureMaterial);
  236. // wallResultMesh.material = wallResultMeshMaterial;
  237.  
  238. // // console.log(wallResultMesh.geometry.faces, 112233);
  239. // wallResultMesh.geometry.faces.forEach((item, i) => {
  240. // if (i < 160) {
  241. // item.materialIndex = 0;
  242. // } else {
  243. // item.materialIndex = 1;
  244. // }
  245. // });
  246.  
  247. // wallResultMesh.geometry.computeFaceNormals();
  248. // wallResultMesh.geometry.computeVertexNormals();
  249. // //添加结果到场景中
  250. // this.scene.add(wallResultMesh);
  251. },
  252. // 加载 GLTF 模型
  253. loadGlbModel() {
  254. const loader = new GLTFLoader()
  255. // const dracoLoader = new DRACOLoader()
  256. // dracoLoader.setDecoderPath(‘/draco/’)
  257. // dracoLoader.preload()
  258. // loader.setDRACOLoader(dracoLoader)
  259. loader.load(`${this.publicPath}model/12OJJ6MOWT722N61Z5N92KA9C.glb`, (gltf) => {
  260. console.log(gltf, ‘gltf—–>>>’)
  261. gltf.scene.scale.set(100,100,100) // 设置模型大小缩放
  262. gltf.scene.position.set(0,0,0)
  263. let axis = new THREE.Vector3(0,1,0);//向量axis
  264. gltf.scene.rotateOnAxis(axis,Math.PI/2);
  265. //绕axis轴逆旋转π/16
  266. gltf.scene.rotateOnAxis(axis,Math.PI/-20);
  267. gltf.scene.rotateOnAxis(axis,Math.PI/50);
  268. // gltf.rotateY(Math.PI / 2);
  269. // this.groupBox.add(gltf);
  270. this.scene.add(gltf.scene)
  271. }, (xhr) => {
  272. console.log((xhr.loaded / xhr.total) * 100 + ‘% loaded’)
  273. }, (error) => {
  274. console.error(error)
  275. })
  276. },
  277. // 加载 FBX 模型
  278. loadFbxModel() {
  279. const loader = new FBXLoader();
  280. loader.load(`${this.publicPath}model/glbxz.com6031.FBX`, object => {//加载路径fbx文件
  281. console.log(object, ‘object—–>>>’)
  282. object.traverse( child => {
  283. if ( child.isMesh ){
  284. child.castShadow = true;
  285. child.receiveShadow = true;
  286. }
  287. });
  288. this.scene.add(object);//模型
  289. })
  290. },
  291. //加载 JSON格式 模型
  292. loadJsonModel() {
  293. //设置相机位置
  294. this.camera.position.z = 130
  295. this.camera.position.y = 80
  296. const loader = new THREE.ObjectLoader()
  297. loader.load(`${this.publicPath}model/xxxx.json`, json => {
  298. //处理加载模型为黑色问题
  299. json.traverse(child => {
  300. if (child.isMesh) {
  301. child.material.emissive = child.material.color
  302. child.material.emissiveMap = child.material.map
  303. }
  304. })
  305. this.scene.add(group)
  306. }, xhr => {
  307. // called while loading is progressing
  308. console.log(`${( xhr.loaded / xhr.total * 100 )}% loaded`);
  309. }, error => {
  310. // called when loading has errors
  311. console.error(‘An error happened’, error);
  312. })
  313. },
  314. // 模型的点击事件
  315. modelMouseClick( event ) {
  316. var raycaster = new THREE.Raycaster();
  317. var mouse = new THREE.Vector2();
  318. // 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)
  319. mouse.x = ( event.clientX / window.innerWidth ) * 2 1;
  320. mouse.y = ( event.clientY / window.innerHeight ) * 2 + 1;
  321. raycaster.setFromCamera(mouse, this.camera);
  322. const intersects = raycaster.intersectObjects(this.scene.children);
  323. // 根据它来判断点击的什么,length为0即没有点击到模型
  324. console.log(intersects, ‘intersects—–>>>’)
  325. }
  326. }
  327. }
  328. </script>
  329. <style scoped>
  330. #import-template {
  331. width: 100%;
  332. height: 100%;
  333. }
  334. #stats {
  335. width: 100%;
  336. height: 50px;
  337. position: relative;
  338. }
  339. #container {
  340. width: 100%;
  341. height: calc(100% 50px);
  342. }
  343. </style>

效果

自动草稿

最后再补充一下,有个threeBSP,,到现在还没知道怎么去引用,搞这个东西才两天,很多还需要慢慢摸索 ,好像这个threBSP不支持npm装,而且必须要引在THREE后面。。。慢慢再搞

  1. <script src=“https://johnson2heng.github.io/three.js-demo/lib/threebsp.js”></script>

这个是threeBSP在线的包,如果向上面例子按需引入THREE,那应该怎么去引这个包呢,,

不断学习中。。。

补充

接上面的问题,【已解决】ThreeBSP引入问题

见下篇博文three.js 利用uv和ThreeBSP制作一个快递柜功能

到此这篇关于Vue集成three.js,并加载glb、gltf、FBX、json模型的文章就介绍到这了,更多相关Vue集成three.js内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,请不要用于商业用途!
3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员!
8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载
声明如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性

GLB下载网 - GLB/GLTF模型与格式资源免费下载,支持在线浏览与转换 » Vue集成three.js并加载glb、gltf、FBX、json模型的场景分析

常见问题FAQ

免费下载或者VIP会员专享资源能否直接商用?
本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
提示下载要提取码
百度网盘提取码都是gltf。
分享过期和重复下载怎么办
分享过期请使用备份下载,重复下载是不另扣费的,请放心下载。
模型和平台不兼容怎么办
可以用网站在线编辑功能,修改模型属性,大小,方向,坐标,中心,透明等问题,然后重新导出既可https://glbxz.com/38636.html
开通VIP 享更多特权,建议使用 QQ 登录