Implementación simple de la generación de miniaturas del modelo threejs en Vue3

Tabla de contenido

I. Introducción

2. Introducción

3. Implementación sencilla

0. Preparar

1. Crea una escena

2. Importación de modelos

3. Generar Base64

4. Enlazar imágenes

4. Visualización de resultados


I. Introducción

        Dado que el modelo 3D necesita renderizar cada cara y borde del modelo, el problema de abrir el modelo suele ser muy lento. Entonces, cómo resolver este problema, el método más simple y crudo es, por supuesto, optimizar continuamente la carga del modelo, pero la optimización suele ser la más difícil. Por otro lado, permitir que los usuarios abran con precisión el modelo que necesitan, ¿se puede aliviar este problema hasta cierto punto? Entonces es necesario realizar la miniatura del modelo 3D.

2. Introducción

        El marco principal para implementar miniaturas de modelos en este artículo es Vue3, que usa threejs para administrar modelos. Generalmente se divide en tres pasos: 1. Preparar el contenedor de la escena threejs, 2. Construir la escena threejs y cargar el modelo, 3. Convertir el lienzo a la codificación base64 y cargarlo en el contenedor img.

3. Implementación sencilla

0. Preparar

        En primer lugar, dado que desea importar el modelo, debe preparar un modelo que desee agregar a la escena. Aquí recomiendo un sitio de descarga de modelos, SketchChfab , de donde provienen la mayoría de los modelos a los que se hace referencia en el código fuente de Threejs.

        Luego, debe preparar un contenedor para el lienzo generado:

<template>
    <div id="thumbnail"></div>
</template>

        Cree un archivo ts para integrar las operaciones que se pueden usar en la escena del modelo y asígnele el nombre sceneCreator aquí:

1. Crea una escena

La creación básica de la escena no se repetirá. Si no la entiende, puede consultar el uso simple de Three.js en Vue3 .

//引入threejs
import * as THREE from 'three' 
//引入加载器
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
​
class SceneCreator {
   public scene: THREE.Scene = new THREE.Scene()
   private camera: THREE.PerspectiveCamera
   private renderer: THREE.Renderer
   private controls: OrbitControls
​
   constructor (fatherElement: HTMLElement) {
     this.scene.background = new THREE.Color(0xaaaaaa)
     // 添加光源
     this.initLight()
​
     // 创建一个透视相机
     const width = window.innerWidth; const height = window.innerHeight
     this.camera = new THREE.PerspectiveCamera(45, width / height, 1, 5000)
     // 设置相机位置
     this.camera.position.set(100, 400, 600)
     // 设置相机方向
     this.camera.lookAt(0, 0, 0)
​
     // 创建辅助坐标轴
     const axesHelper = new THREE.AxesHelper(100)
     this.scene.add(axesHelper)
​
     // 创建一个WebGL渲染器
     this.renderer = new THREE.WebGLRenderer()
     this.renderer.setSize(width, height)
     this.renderer.render(this.scene, this.camera)
​
     fatherElement.appendChild(this.renderer.domElement)
   }
​
   render () {
     this.renderer.render(this.scene, this.camera)
   }
    /**
    *灯光初始化
    */
   initLight () {
     const ambient = new THREE.AmbientLight(0x505050)
     this.scene.add(ambient)
     const pointLight1 = new THREE.PointLight(0xffffff, 0.4)
     const pointLight2 = new THREE.PointLight(0xffffff, 0.4)
     pointLight1.position.set(200, 300, 400)
     this.scene.add(pointLight1)
     pointLight2.position.set(-200, -300, -400)
     this.scene.add(pointLight2)
​
     const hemiLight = new THREE.HemisphereLight(0xffffff, 0xffffff, 0.6)
     hemiLight.color.setHSL(0.6, 1, 0.6)
     hemiLight.groundColor.setHSL(0.095, 1, 0.75)
     hemiLight.position.set(0, 200, 0)
     this.scene.add(hemiLight)
​
     const hemiLightHelper = new THREE.HemisphereLightHelper(hemiLight, 10)
     this.scene.add(hemiLightHelper)
​
     const dirLight = new THREE.DirectionalLight(0xffffff, 1)
     dirLight.color.setHSL(0.1, 1, 0.95)
     dirLight.position.set(-100, 175, 100)
     dirLight.position.multiplyScalar(30)
     this.scene.add(dirLight)
   }
}
//暴露
export { SceneCreator }

2. Importación de modelos

        Aquí, use el GLTFLoader en threejs para cargar el glb descargado. Dado que hacer una miniatura no requiere ninguna operación especial en el modelo, solo necesita agregar el modelo cargado a la escena.

createCar () {
     const loader = new GLTFLoader()
​
     const glbHref = new URL('../assets/glb/car/ferrari_458.glb', import.meta.url).href
​
     loader.load(glbHref, (gltf) => {
       const carModel = gltf.scene.children[0]
​
       this.scene.add(carModel)
     })
   }

3. Generar Base64

<script lang='ts' setup>
import { onMounted, Ref, ref } from 'vue'
import { SceneCreator } from '../utils/sceneCreator'
​
let myScene: SceneCreator
const img:Ref<string> = ref('')
​
const createThumbnails = async () => {
  const el = document.getElementById('thumbnail')
  if (el) {
    // 创建场景
    myScene = new SceneCreator(el)
    // 场景自适应,防止模型变形
    myScene.resize()
    // 载入模型,由于loader是异步的所以我们需要等它加载好后再生成base64,否则生成的图片是没有模型的
    await myScene.createCar()
    myScene.render()
    // 生成base64
    const canvas = el.children[0] as HTMLCanvasElement
    img.value = canvas.toDataURL('img/png')
    // 不需要展示canvas就移除它
    // el.remove()
  }
}
​
onMounted(() => {
  createThumbnails()
})
</script>

4. Enlazar imágenes

        Cree una etiqueta img y vincule el base64 generado en el paso 3 al scr de la etiqueta img.

<template>
  <div id="thumbnail"></div>
  <img :src="img" alt="">
</template>

4. Visualización de resultados

Supongo que te gusta

Origin blog.csdn.net/qq_52013792/article/details/128129616
Recomendado
Clasificación