当前位置:   article > 正文

Vue3 + Three.js加载gltf模型_vue three gltf插件

vue three gltf插件

推荐3D模型库: sketchfab.com

大量免费模型可供下载

天空盒分享: 天空盒素材

加载gltf模型首先需要引入Three.js内置GLTF加载器

import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"

然后实例化加载器, 引入模型地址, 最后添加到场景中

注意: gltf模型存放在assets文件夹中, 必须是完整的gltf文件, 如下:

  1. //添加模型
  2. const loader = new GLTFLoader()
  3. loader.load("src/assets/tudao/scene.gltf", (gltf) => {
  4. gltf.scene.position.set(-2.2, -0.5 , 0.8) // 模型位置
  5. gltf.scene.rotation.y = Math.PI / 2 // y轴旋转
  6. gltf.scene.rotation.z = -Math.PI / 8 // z轴旋转
  7. scene.add(gltf.scene) // 加入场景
  8. })

加载天空盒(可选)

three.js中天空盒加载顺序为: right, left, top, down, back, front (右, 左, 上, 下, 后, 前)

  1. // 创建天空盒
  2. // 相应面对应相应图片
  3. const imgUrl = [
  4. 'src/assets/bak5/right.jpg',
  5. 'src/assets/bak5/left.jpg',
  6. 'src/assets/bak5/top.jpg',
  7. 'src/assets/bak5/down.jpg',
  8. 'src/assets/bak5/back.jpg',
  9. 'src/assets/bak5/front.jpg',
  10. ]
  11. // 调用getTexturesFromAtlasFile() 给每个材质加上相应的图片
  12. const textures = getTexturesFromAtlasFile(imgUrl, 6)
  13. const materials = []
  14. for (let i = 0; i < 6; i++) {
  15. // 创造六个面的材质
  16. materials.push(new THREE.MeshBasicMaterial({ map: textures[i] }))
  17. }
  18. //创造包围盒
  19. const skyBox = new THREE.Mesh(new THREE.BoxBufferGeometry(1024, 1024, 1024), materials)
  20. // skyBox.position.set(0, 0, 0);
  21. skyBox.geometry.scale(1, 1, -1)
  22. scene.add(skyBox)
  23. // 六个面添加图片
  24. function getTexturesFromAtlasFile (atlasImgUrl, tilesNum) {
  25. const textures = []
  26. for (let i = 0; i < tilesNum; i++) {
  27. textures[i] = new THREE.Texture()
  28. }
  29. for (let i = 0; i < textures.length; i++) {
  30. const imageObj = new Image()
  31. imageObj.src = atlasImgUrl[i]
  32. imageObj.onload = () => {
  33. let context = ''
  34. // let tileWidth = imageObj.height;
  35. // let tileWidth = 5000;
  36. const canvas = document.createElement('canvas')
  37. // const canvas: HTMLCanvasElement = this.canvasRef.nativeElement; // 得到canvas 元素
  38. context = canvas.getContext('2d')
  39. const canvasHeight = 720
  40. canvas.height = canvasHeight
  41. canvas.width = canvasHeight
  42. // context.drawImage( imageObj, canvasHeight * i, 0, canvasHeight, canvasHeight, 0, 0, canvasHeight, canvasHeight );
  43. context.drawImage(imageObj, 0, 0, canvasHeight, canvasHeight)
  44. textures[i].image = canvas
  45. textures[i].needsUpdate = true
  46. }
  47. }
  48. return textures
  49. }

全部代码

  1. <template>
  2. <div class="canvas-container" ref="screenDom"></div>
  3. </template>
  4. <script setup>
  5. import * as THREE from 'three'
  6. import { ref, onMounted } from "vue"
  7. import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"
  8. import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"
  9. let screenDom = ref(null)
  10. onMounted(() => {
  11. //创建场景
  12. let scene = new THREE.Scene()
  13. //创建相机
  14. let camera = new THREE.PerspectiveCamera(
  15. 100,
  16. screenDom.value.clientWidth / screenDom.value.clientHeight,
  17. 0.1,
  18. 1000
  19. );
  20. camera.position.set(0, 1, 5);
  21. //创建渲染器
  22. let renderer = new THREE.WebGLRenderer({ antialias: true });
  23. renderer.setSize(screenDom.value.clientWidth, screenDom.value.clientHeight);
  24. screenDom.value.appendChild(renderer.domElement)
  25. //添加控制器
  26. let control = new OrbitControls(camera, renderer.domElement)
  27. // 创建天空盒
  28. // 相应面对应相应图片
  29. const imgUrl = [
  30. 'src/assets/bak5/right.jpg',
  31. 'src/assets/bak5/left.jpg',
  32. 'src/assets/bak5/top.jpg',
  33. 'src/assets/bak5/down.jpg',
  34. 'src/assets/bak5/back.jpg',
  35. 'src/assets/bak5/front.jpg',
  36. ]
  37. // 调用getTexturesFromAtlasFile() 给每个材质加上相应的图片
  38. const textures = getTexturesFromAtlasFile(imgUrl, 6)
  39. const materials = []
  40. for (let i = 0; i < 6; i++) {
  41. // 创造六个面的材质
  42. materials.push(new THREE.MeshBasicMaterial({ map: textures[i] }))
  43. }
  44. //创造包围盒
  45. const skyBox = new THREE.Mesh(new THREE.BoxBufferGeometry(1024, 1024, 1024), materials)
  46. // skyBox.position.set(0, 0, 0);
  47. skyBox.geometry.scale(1, 1, -1)
  48. scene.add(skyBox)
  49. // 六个面添加图片
  50. function getTexturesFromAtlasFile (atlasImgUrl, tilesNum) {
  51. const textures = []
  52. for (let i = 0; i < tilesNum; i++) {
  53. textures[i] = new THREE.Texture()
  54. }
  55. for (let i = 0; i < textures.length; i++) {
  56. const imageObj = new Image()
  57. imageObj.src = atlasImgUrl[i]
  58. imageObj.onload = () => {
  59. let context = ''
  60. // let tileWidth = imageObj.height;
  61. // let tileWidth = 5000;
  62. const canvas = document.createElement('canvas')
  63. // const canvas: HTMLCanvasElement = this.canvasRef.nativeElement; // 得到canvas 元素
  64. context = canvas.getContext('2d')
  65. const canvasHeight = 720
  66. canvas.height = canvasHeight
  67. canvas.width = canvasHeight
  68. // context.drawImage( imageObj, canvasHeight * i, 0, canvasHeight, canvasHeight, 0, 0, canvasHeight, canvasHeight );
  69. context.drawImage(imageObj, 0, 0, canvasHeight, canvasHeight)
  70. textures[i].image = canvas
  71. textures[i].needsUpdate = true
  72. }
  73. }
  74. return textures
  75. }
  76. //添加模型
  77. const loader = new GLTFLoader()
  78. loader.load("src/assets/tudao/scene.gltf", (gltf) => {
  79. gltf.scene.position.set(-2.2, -0.5 , 0.8) // 模型位置
  80. gltf.scene.rotation.y = Math.PI / 2 // y轴旋转
  81. gltf.scene.rotation.z = -Math.PI / 8 // z轴旋转
  82. scene.add(gltf.scene) // 加入场景
  83. })
  84. loader.load("src/assets/csgo_terrorist_characters/scene.gltf", (gltf) => {
  85. gltf.scene.scale.set(0.1, 0.1, 0.1);
  86. gltf.scene.position.set(0, -4, 0)
  87. scene.add(gltf.scene)
  88. })
  89. loader.load("src/assets/tudao/scene.gltf", (gltf) => {
  90. gltf.scene.position.set(2.15, -0.5, 0.8)
  91. gltf.scene.rotation.y = Math.PI / 2
  92. gltf.scene.rotation.z = -Math.PI / 8
  93. scene.add(gltf.scene)
  94. })
  95. //添加直线光
  96. let light1 = new THREE.DirectionalLight(0xffffff, 1)
  97. light1.position.set(0, 50, 50)
  98. let light2 = new THREE.DirectionalLight(0xffffff, 1)
  99. light2.position.set(0, 50, -50)
  100. let light3 = new THREE.DirectionalLight(0xffffff, 1)
  101. light3.position.set(50, 50, 50)
  102. let light4 = new THREE.DirectionalLight(0xffffff, 1)
  103. light4.position.set(-50, -10, 0)
  104. let light5 = new THREE.DirectionalLight(0xffffff, 1)
  105. light5.position.set(0, 0, 50)
  106. let light6 = new THREE.DirectionalLight(0xffffff, 1)
  107. light6.position.set(0, 0, -50)
  108. let light7 = new THREE.DirectionalLight(0xffffff, 1)
  109. light7.position.set(50, 0, 0)
  110. let light8 = new THREE.DirectionalLight(0xffffff, 1)
  111. light8.position.set(-50, 0, 0)
  112. scene.add(light1, light2, light3, light4, light5, light6, light7, light8)
  113. //绘制画布
  114. function render () {
  115. requestAnimationFrame(render);
  116. renderer.render(scene, camera)
  117. }
  118. render()
  119. })
  120. </script>
  121. <style lang="scss" scoped>
  122. .canvas-container {
  123. width: 100%;
  124. height: 100%;
  125. }
  126. </style>

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/665494
推荐阅读
相关标签
  

闽ICP备14008679号