ModelViewer.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. <template>
  2. <div ref="container" class="w-full h-full z-999 cursor-pointer"></div>
  3. </template>
  4. <script setup lang="ts">
  5. import { ref, onMounted, onUnmounted } from 'vue'
  6. import * as THREE from 'three'
  7. import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
  8. import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
  9. const container = ref<HTMLDivElement>()
  10. let scene: THREE.Scene
  11. let camera: THREE.PerspectiveCamera
  12. let renderer: THREE.WebGLRenderer
  13. let controls: OrbitControls
  14. let model: THREE.Group
  15. const init = () => {
  16. scene = new THREE.Scene()
  17. // scene.background = new THREE.Color(0x0a0a0a) // 移除深色背景
  18. camera = new THREE.PerspectiveCamera(75, 1, 0.1, 1000)
  19. camera.position.set(3, 3, 3)
  20. camera.lookAt(0, 0, 0)
  21. renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true })
  22. renderer.setSize(2000, 1000)
  23. renderer.shadowMap.enabled = true
  24. renderer.shadowMap.type = THREE.PCFSoftShadowMap
  25. container.value?.appendChild(renderer.domElement)
  26. controls = new OrbitControls(camera, renderer.domElement)
  27. controls.enableDamping = true
  28. controls.dampingFactor = 0.05
  29. controls.enableZoom = true
  30. controls.enablePan = false
  31. const hemisphereLight = new THREE.HemisphereLight(0xffffbb, 0x080820, 2) // 增加强度从1到2
  32. scene.add(hemisphereLight)
  33. const pointLight = new THREE.PointLight(0xffffff, 2, 100) // 增加强度从1到2
  34. pointLight.position.set(0, 5, 5)
  35. scene.add(pointLight)
  36. const directionalLight = new THREE.DirectionalLight(0xffffff, 1.5) // 增加强度从0.8到1.5
  37. directionalLight.position.set(10, 10, 5)
  38. directionalLight.castShadow = true
  39. scene.add(directionalLight)
  40. // 添加额外的环境光
  41. const ambientLight = new THREE.AmbientLight(0x404040, 0.6) // 添加环境光
  42. scene.add(ambientLight)
  43. const modelUrl = new URL('../assets/model/industrialEquipment.glb', import.meta.url).href
  44. console.log('模型URL:', modelUrl)
  45. const loader = new GLTFLoader()
  46. loader.load(
  47. modelUrl,
  48. (gltf) => {
  49. console.log('模型加载成功:', gltf)
  50. model = gltf.scene
  51. model.scale.set(7, 7, 7) // 增加缩放
  52. model.position.set(0, 0, 0)
  53. scene.add(model)
  54. },
  55. (progress) => {
  56. console.log('模型加载进度:', progress) // 加载进度
  57. },
  58. (error) => {
  59. console.error('模型加载失败:', error)
  60. }
  61. )
  62. const animate = () => {
  63. requestAnimationFrame(animate)
  64. controls.update()
  65. if (model) {
  66. model.rotation.y += 0.005
  67. } else {
  68. scene.children.forEach((child) => {
  69. if (child instanceof THREE.Mesh && child.geometry instanceof THREE.BoxGeometry) {
  70. child.rotation.y += 0.01
  71. }
  72. })
  73. }
  74. renderer.render(scene, camera)
  75. }
  76. animate()
  77. const resize = () => {
  78. if (container.value) {
  79. const width = container.value.clientWidth
  80. const height = container.value.clientHeight
  81. camera.aspect = width / height
  82. camera.updateProjectionMatrix()
  83. renderer.setSize(width, height)
  84. }
  85. }
  86. window.addEventListener('resize', resize)
  87. resize()
  88. }
  89. onMounted(() => {
  90. init()
  91. })
  92. onUnmounted(() => {
  93. if (renderer) {
  94. renderer.dispose()
  95. }
  96. if (controls) {
  97. controls.dispose()
  98. }
  99. })
  100. </script>