Cómo construir una sala de exposiciones web 3D con Three.js + Blender

Autor: Equipo front-end de Vivo Internet - Wei Xing 

Están surgiendo nuevas formas de operar actividades una tras otra, y el 3D web está de moda. Este artículo lo guiará paso a paso para comprender cómo usar Three.js y Blender para crear una sala de exhibición 3D web inmersiva.

I. Introducción

¿Qué es la sala de exposiciones en 3D? Veamos primero el efecto:

imagen

Parece un juego móvil de aventuras en 3D. Los usuarios pueden manipular el joystick virtual en el centro de la pantalla para moverse libremente en la sala y ver exposiciones desde una perspectiva en primera persona.

1.1 ¿Por qué construir una sala de exposiciones en 3D?

En primer lugar, permítanme presentarles un trasfondo. Nuestro trabajo es realizar actividades de operación del usuario del centro de juegos. Haremos algunas actividades divertidas para que los usuarios participen y obtengan algunos beneficios.

El trasfondo del evento en ese momento era el festival anual de juegos vivo de nuestra compañía, y Metaverse era una palabra candente. Así que hay varias razones para hacerlo:

  • tema del festival de juegos vivo

  • Ajuste de puntos de acceso metaverso

  • Nueva jugabilidad, nueva experiencia.

1.2 Selección de tecnología

El esquema de combinación utilizado: Three.js + Blender .

  • por qué Three.js

Hay muchos frameworks 3D de código abierto, pero hay dos de los más utilizados: Three.js y Babylon.js, solo tenemos que elegir uno de ellos. Después del análisis, se encuentra que ambos tienen sus propias ventajas:

imagen

Teniendo en cuenta varias características básicas de la sala de exposiciones 3D:

  1. Escena 3D pequeña simple, sin interacción compleja (bajos requisitos en la lente)

  2. Publicado en dispositivos móviles, el paquete debe ser lo más pequeño posible para mejorar el rendimiento

  3. Período de construcción corto, necesita comenzar rápidamente y más referencias de casos

El paquete Three.js es más pequeño, tiene más casos de referencia y se inicia más rápido, por lo que aunque Babylon.js tiene sus ventajas, Three.js es más adecuado para este proyecto.

  • porque licuadora

Blender es un software de modelado 3D de código abierto liviano con muchos complementos gratuitos útiles, y Blender puede exportar modelos GLTF / GLB (más adelante presentará los modelos GLTF / GLB), combinando el uso de Three.js, el más simple y más fácil de usar. usar.

Entonces, ahí está.

2. Parte práctica

2.1 Comprender el modelo GLTF/GLB

Antes de pasar al desarrollo, una breve comprensión de los modelos Blender y GLTF/GLB.

  • Comprensión simple de Blender

En primer lugar, Blender se ve así: la imagen muestra el borrador de la sala de exhibición en 3D entregado por el diseñador. Simplemente entendido, el lado izquierdo es la estructura jerárquica del modelo, el medio es el efecto de vista previa del modelo y el lado derecho es el panel de propiedades del modelo.

En términos generales, como desarrollador, no necesitamos tener demasiados conocimientos sobre Blender, solo necesitamos saber cómo comprender la estructura del modelo, exportar modelos GLTF/GLB y los principios básicos de la cocción.

imagen

  • Modelo GLTF/GLB

GLTF (Graphics Language Transmission Format) es un formato de archivo de modelo 3D estándar, que almacena información de modelo 3D en forma de JSON, como jerarquía de modelo, material, animación, textura, etc.

Los recursos estáticos de los que depende el modelo, como imágenes, pueden importarse a través de URI externos o convertirse a base64 e insertarse directamente en el archivo GLTF.

Contiene dos formas de sufijos, .gltf (JSON/ASCII) y .glb (binario) . .gltf almacena información en forma de JSON. .glb es un formato extendido de .gltf, que almacena información en forma binaria, por lo que el modelo exportado es de menor tamaño. Si no necesitamos modificar directamente el modelo .gltf a través de JSON, se recomienda utilizar el modelo .glb, que es más pequeño y se carga más rápido.

  • Blender exportar modelo GLTF/GLB

En blender, puede exportar directamente el modelo a formato GLTF/GLB. La diferencia entre las tres opciones no se repetirá. Simplemente elijamos el formato .glb más eficiente.

imagen

Una vez que tengamos el modelo, podemos comenzar a crear la escena a través de Three.js e importar el modelo.

2.2 Modelo de carga Three.js

Para evitar la extensión del artículo, se supone que todos dominan la sintaxis básica de Three.js. El artículo se centra en cómo cargar el modelo, ajustarlo paso a paso y lograr el efecto final de sala de exposiciones en 3D.

¿Cómo cargar un modelo?

(1) Crea una escena vacía

Primero cree una escena de escena vacía, y todos los modelos o materiales posteriores se agregarán a esta escena.

import * as THREE from 'three'

// 1. 创建场景
const scene = new THREE.Scene(); 


// 2. 创建镜头
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
// 3. 创建Renderer
const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

(2) Importar modelo GLTF/GLB

Importe el modelo .glb a través de GLTFLoader y agréguelo a la escena.

import GLTFLoader from 'GLTFLoader'
const loader = new GLTFLoader()
loader.load('path/to/gallery.glb',
  gltf => {
    scene.add(gltf.scene) // 添加到场景中
  } 
}

(3) Comenzar a renderizar

Llame al método renderer.render a través de requestAnimationFrame para comenzar a renderizar la escena en tiempo real.

function animate() {
      requestAnimationFrame( animate );
      renderer.render( scene, camera );
}
animate();

Bien, hemos completado la importación del modelo 3D, pero descubrimos que toda la escena está oscura.

imagen

Intenta agregar una luz ambiental.

const ambientLight = new THREE.AmbientLight(0xffffff, 1)

scene.add(ambientLight)

imagen

ok, está iluminado, pero el efecto sigue siendo muy pobre, de muy mala calidad.

La razón es que los efectos de material, las fuentes de luz, las sombras y las texturas ambientales en el modelo se pierden, por lo que cuando importamos el modelo, lo que vemos es un montón de formas simples de color sólido.

Así que tenemos que encontrar estas cosas perdidas paso a paso y restaurar el borrador del diseño.

2.3 Restauración del borrador de diseño

A continuación, restaure el borrador del diseño paso a paso.

(1) añadir fuente de luz

Verifique el modelo de Blender y vea que se han agregado un montón de fuentes de luz puntuales y fuentes de luz paralelas al borrador del diseño.

imagen

Una fuente de luz puntual puede entenderse como una bombilla en una habitación, y la intensidad de la luz se atenúa con la distancia;

Las fuentes de luz paralelas pueden entenderse como la luz directa del Sol. A diferencia de las fuentes de luz puntuales, la intensidad de la luz no se atenúa con la distancia.

Así que también añadimos algunas fuentes de luz:

// 一些灯光选项
// 如果是平行光则没有distance、decay选项
const lightOptions = [

  {
    type: 'point', // 灯光类型:1. point点光源、2. directional平行光源
    color: 0xfff0bf, // 灯光颜色
    intensity: 0.4, // 灯光强度
    distance: 30,    // 光照距离
    decay: 2,    // 衰减速度
    position: { // 光源位置
      x: 2,
      y: 6,
      z: 0
    }
  },
  ...

]

function createLights() {
  pointLightOptions.forEach(option => {
    const light = option.type === 'point' ?
        new THREE.PointLight(option.color, option.intensity, option.distance, option.decay) :
        new THREE.DirectionalLight(option.color, option.intensity)
    const position = option.position
    light.position.set(position.x, position.y, position.z)
    scene.add(light)
  })
}

createLights()

Se puede ver que la escena es mejor que antes.Con la fuente de luz, el modelo se vuelve tridimensional y real, con algo de brillo anticolor.

imagen

imagen

Pero notamos que el logo y los lados del banco en la imagen son negros, y las esferas y sillas al lado no son lo suficientemente realistas.

Por lo tanto, debemos hacer el siguiente ajuste: ajustar el material del modelo y aumentar la textura del entorno.

(2) Ajuste el material del modelo y aumente la textura del entorno.

Comencemos con una breve mirada a los materiales y las texturas del entorno.

  • material

El material es como la piel de un objeto.Podemos ajustar las propiedades de la piel, como el brillo, la metalicidad, la rugosidad y la transparencia, para que el objeto tenga diferentes efectos visuales.

Generalmente, el modelo exportado desde blender ya contiene algunas propiedades de material, pero las propiedades de material en Three.js y las propiedades en Blender no están completamente mapeadas.Después de importar el modelo a Three.js, el efecto será diferente del borrador de diseño. . . En este momento, necesitamos ajustar manualmente las propiedades del material para lograr un efecto similar al borrador del diseño.

  • Textura del entorno (mapa del entorno)

La textura ambiental es hacer que el modelo mapee el entorno circundante, haciendo que la escena o el objeto sean más realistas. Por ejemplo, si queremos renderizar un cubo y poner el cubo en una habitación, el entorno de la habitación afectará el efecto de renderizado del cubo.

Por ejemplo, después de pegar un objeto de espejo con una textura de entorno, puede reflejar el espejo del entorno circundante en tiempo real, lo que parece muy real.

En el borrador del diseño, también se utiliza una sala como textura ambiental para hacer que la escena sea más realista.

imagen

Las texturas ambientales se dividen en: texturas esféricas y texturas de cubo. Ambos están bien, aquí usamos una textura esférica de la sala como mapa del entorno.

imagen

Tomando como ejemplo el logo del vivo game festival en la pantalla, ajustamos su material y textura ambiental para hacerlo más realista.

  1. De acuerdo con el nombre en Blender, busque el modelo del logotipo.

  2. Ajuste la rugosidad de la superficie y la metalicidad del logotipo.

  3. Cargue y configure el mapa de textura del entorno.

imagen

const loader = new GLTFLoader()
loader.load('path/to/gallery.glb',
  gltf => {
      // 1. 根据Blender中物体的名字,找到logo模型
      gltf.scene.traverse(child => {
        if (isLogo(child)) {
       initLogo(child)   // 2. 调整材质
       setEnvMap(child)  // 3. 设置环境纹理
      }
      })
    scene.add(gltf.scene)
  } 
}


// 判断是否为Logo
const isLogo = object.name === 'logo'

function initLogo(object) {
  object.material.roughness = 0   // 调整表面粗糙度
  object.material.metalness = 1   // 调整金属度
}
// 加载环境纹理

let envMap
const envmaploader = new THREE.PMREMGenerator(renderer)

const setEnvMap = (object) => {
      if(envMap) {
        object.material.envMap = envMap.texture
      } else {
        textureLoader.load('path/to/envMap.jpg',
             texture => {
             texture.encoding = THREE.sRGBEncoding
             envMap = envmaploader.fromCubemap(texture)
                 object.material.envMap = envMap.texture
             })
      }
}

Después del procesamiento anterior, puede ver que el logotipo negro original tiene un brillo metálico y reflejará la textura del entorno circundante.

Otros objetos también se vuelven más realistas después de un procesamiento similar.

imagen

imagen

imagen

imagen

Ahora toda la escena está más cerca del borrador de diseño, pero hay menos sombras en la escena y se ve muy seca.

Agrega sombras.

(3) Añadir sombras

La adición de sombras se realiza en cuatro pasos:

  1. Habilite la compatibilidad con sombras para el renderizador: renderer.shadowMap.enabled = true

  2. Establecer la fuente de luz: castShadow = true

  3. Establezca el objeto que debe proyectarse: castShadow = true

  4. Establecido para el plano u objeto (como el piso) que necesita ser proyectado: receiveShadow = true

// 1. renderer
const renderer = new THREE.WebGLRenderer()
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;

// 2. light
const light = new THREE.DirectionalLight()
light.castShadow = true;

// 3. object
gltf.scene.traverse(function (child) {
   if (child.isMesh) {
     child.castShadow = true;
   }
});
// 4. floor
floor.receiveShadow = true

imagen

Después de agregar sombras, hay una mejora cualitativa, y se encuentra que toda la escena es mucho más tridimensional, y el grado de restauración ya es muy alto en este momento.

Si no se considera la pérdida de rendimiento, el estilo de esta escena está listo para usarse. (La optimización del rendimiento se mencionará más adelante)

Para resumir, algunas cosas recién hechas:

  1. añadir fuente de luz

  2. Ajuste los materiales del modelo y agregue texturas ambientales.

  3. agregar sombras

Ahora que la escena de la sala de exposiciones en 3D ha sido casi restaurada, se construirá un joystick virtual para controlar el movimiento y la dirección de la cámara en primera persona para lograr una experiencia de exposición inmersiva.

2.4 Joystick virtual

Para realizar el movimiento y la dirección de la cámara controlada por el joystick virtual, necesitamos tres cosas:

  • Un joystick móvil (manejador)

  • Un cuboide (jugador): utilizado para llevar la perspectiva en primera persona

  • Una lente (cámara): se ha creado antes

Algunas personas pueden preguntarse por qué se necesita un jugador, ¿no es suficiente controlar directamente la cámara a través del joystick? De hecho, el papel del jugador es detectar colisiones. Cuando el jugador encuentra obstáculos como taburetes y paredes, debe detener el movimiento de la cámara. Es imposible realizar la detección de colisiones controlando directamente la lente.

Entonces, de hecho, la lógica del movimiento de la cámara es:

El usuario manipula el joystick → actualiza la posición y orientación del jugador → por lo tanto, actualiza sincrónicamente la posición y orientación de la cámara

(1) Crear un balancín móvil

El principio de realización de mover el balancín es muy simple, aquí hay solo una breve descripción.

El núcleo es crear un disco, escuchar gestos táctiles y actualizar los parámetros de movimiento en tiempo real según la dirección de los gestos para controlar el movimiento y la dirección de la cámara.

const speed = 8 // 移动速度
const turnSpeed = 3  // 转向速度
// move option,用于调整第一人称镜头的移动和转向
const move = {
      turn: 0,  // 旋转角度
      forward: 0     // 前进距离
}

// 创建一个handler,并监听手势,调整move option
const handler = new Handler()
handler.onTouchMove = () => { // update move option }

(2) Crear un jugador

Primero cree un objeto jugador, que es un cuboide transparente de 1.2 * 2 * 1.

function createPlayer() {
  const box = new THREE.BoxGeometry(1.2, 2, 1)
  const mat = new THREE.MeshBasicMaterial({
    color: 0x000000,
    wireframe: true
  })

  const mesh = new THREE.Mesh(box, mat)
  box.translate(0, 1, 0)
  return mesh
}

const player = createPlayer() // 创建player
player.position.set(4.5, 2, 12)     // 设置player的初始位置

(3) actualizar reproductor y actualizar cámara

Cada vez que renderice, actualice la posición y la orientación del jugador, y actualice la posición y la orientación de la cámara de forma sincrónica.

const clock = THREE.clock()

function render() {
  const dt = clock.delta()   // 获取每帧之间的时间间隔,根据时间间隔长短来更新player和camera的移动距离和转向的多少
  updatePlayer(dt)
  updateCamera(dt)
  renderer.render(scene, camera)
  window.requestAnimationFrame(render)
}

// 更新player的位置和朝向

function updatePlayer(dt) {
  const pos = player.position.clone()
  pos.y -= 1.5 // 降低高度,后续用于计算碰撞检测
  const dir = new THREE.Vector3()
  player.getWorldDirection(dir)
  dir.negate()
  if (move.forward < 0) dir.negate()
  // 调整镜头前进 or 后退

  if (move.forward !== 0) {
    player.translateZ(move.forward > 0 ? -dt * speed : dt * speed * 0.5)
  }
  // 调整镜头朝向

  if (move.turn !== 0) {
    player.rotateY(move.turn * 1.2 * dt)
  }
}

// 根据player的位置和朝向,同步更新camera的位置和朝向

function updateCamera(dt) {
  camera.position.lerp(activeCamera.getWorldPosition(new THREE.Vector3()), 0.08)
  const pos = player.position.clone()
  pos.y += 2.5
  camera.lookAt(pos)
}

Nota: el método de renderizado usa clock.delta() para calcular el intervalo de tiempo entre cada renderizado y usa este intervalo de tiempo para actualizar el reproductor y la cámara. Porque en la situación ideal de 60 fotogramas por segundo, el intervalo de tiempo entre dos fotogramas es de 16,67 ms, pero de hecho este valor fluctuará, por lo que debemos actualizar el reproductor y la cámara de acuerdo con el intervalo de tiempo de renderizado real, de modo que el movimiento y la dirección de la lente son más precisos Sea natural.

Después de completar los pasos anteriores, podemos mover y girar la cámara controlando el joystick virtual.

A continuación, agregue la detección de colisiones y agregue algunas restricciones en el movimiento de la cámara.

2.5 Detección de colisiones

Los pasos de la detección de colisiones también son muy simples:

  • Recoge obstáculos (colisionadores)

  • Detectar colisiones (basado en TRES. Raycaster)

(1) recoger obstáculos

Después de cargar el modelo, atraviese todos los niños, si el niño es un objeto (malla), agréguelo a la cola de obstáculos (colisionadores).

const colliders = []

loader.load('path/to/gallery.glb',
  gltf => {
    gltf.scene.traverse(child => {
        // 收集障碍物
        if(isMesh(child)) {
          colliders.push(child) 
        }
    })
  } 
})

(2) Detectar colisión

Ajuste el método updatePlayer justo ahora e inserte la lógica de detección de colisiones en él.

La lógica de detección de colisión se implementa en base a TRES.Raycaster. El racaster puede entenderse como un rayo. Cuando el rayo pasa a través de un objeto, consideramos que el rayo interseca al objeto.

Mantenemos la dirección del rayo consistente con la orientación del jugador, y juzgamos constantemente si hay un objeto que se cruza delante o detrás del rayo durante el proceso de movimiento. Si hay un objeto que se cruza y la distancia desde el vértice del rayo es < 2,5, se considera que se ha encontrado un obstáculo, no se puede avanzar más.

function updatePlayer(dt) {
  const pos = player.position.clone()
  pos.y -= 1.5 // 降低高度,用于计算collision
  const dir = new THREE.Vector3()

  // 获取当前player的朝向
  player.getWorldDirection(dir)
  dir.negate()
  // 如果是向后退,需要对朝向取反
  if (move.forward < 0) dir.negate()

  // 利用Raycaster判断player是否和colliders有碰撞行为
  const raycaster = new THREE.Raycaster(pos, dir)
  let blocked = false

  if (colliders.length > 0) {
    const intersect = raycaster.intersectObjects(colliders)
    if (intersect.length > 0) {
      // 如果相交距离<2.5,表示前方或后面有障碍物
      if (intersect[0].distance < 2.5) {
        blocked = true
      }
    }
  }
  // 如果遇到障碍物,则停滞移动

  if (!blocked) {
    // 调整镜头前进 or 后退
    if (move.forward !== 0) {
      player.translateZ(move.forward > 0 ? -dt * speed : dt * speed * 0.5)
    }
  }

  // 调整镜头朝向
  if (move.turn !== 0) {
    player.rotateY(move.turn * 1.2 * dt)
  }
}

Esto completa el movimiento de la cámara y la detección de colisiones.

Cuando nos acercamos a obstáculos como sillas y paredes, la cámara deja de moverse. El rango de movimiento de la lente también está limitado por nosotros en la habitación y no saldrá de la habitación.

imagen

3. Ajuste de rendimiento

3.1 Horneado de texturas

Se han completado las funciones básicas de la sala de exposiciones 3D, pero no se ha realizado ningún ajuste de rendimiento. Cuando ejecutamos el proyecto en el teléfono móvil, encontraremos que el dispositivo está muy caliente, la velocidad de fotogramas es muy baja y los modelos de gama baja ni siquiera pueden ejecutarse.

Después del análisis, la representación de luces y sombras en tiempo real es la culpable.

Hay más de 10 fuentes de luz en la página, y cada fuente de luz proyecta sombras en tiempo real (especialmente las fuentes de luz puntuales consumen recursos y provocan retrasos). Pero, de hecho, la posición de la fuente de luz y el objeto en la escena no han cambiado, lo que significa que no necesitamos calcular sombras en tiempo real, solo sombras fijas.

Esto se puede lograr horneando texturas. Y en el lado móvil, el efecto de luz y sombra generado por la textura es mejor que el efecto de luz y sombra en tiempo real calculado por el dispositivo.

  • Hornear textura

El horneado de texturas se refiere a la generación de una textura de modelo renderizando previamente el efecto de la escena en la textura especificada. En Blender, podemos seleccionar cualquier objeto para hornear.

imagen

Tomando el suelo de la sala de exposiciones 3D como ejemplo, podemos representar directamente los efectos de luz y sombra en la textura a través de la cocción de texturas.

La imagen de la izquierda es la textura original del tablero de ajedrez y la imagen de la derecha es la textura horneada combinada con efectos de luces y sombras. Una vez que se completa el horneado, los efectos de luz y sombra en el piso se arreglan, y no necesitamos hacer una representación de luz y sombra en tiempo real.

imagen

imagen

Del mismo modo, hornee el piso, la pared, el techo y otros objetos uno por uno y exporte un nuevo modelo. Dado que el efecto de luz y sombra se ha renderizado en la textura, podemos eliminar la mayoría de las fuentes de luz y solo mantener 2-3 puntos necesarios, fuentes de luz paralelas y luz global. Después de ejecutarlo nuevamente, se descubrió que los problemas de congelamiento y sobrecalentamiento ya no eran evidentes. Y el efecto es en realidad más fino que el renderizado en tiempo real.

imagen

imagen

No hay una introducción a la cocción aquí. Para generar resultados de cocción exquisitos, debe confiar en la comprensión del mapa UV y los parámetros de cocción. Aunque estos están sesgados hacia el trabajo de los estudiantes de diseño, generalmente generan texturas horneadas. Pero como desarrollador, solo después de comprender esto podemos comunicarnos mejor y cooperar con la interfaz de usuario.

3.2 Optimización del tamaño del modelo

El tamaño del modelo es de unos 23M, y se tarda unos 9 segundos en cargar el modelo por primera vez. (Especialmente después del horneado de texturas, el modelo es más grande debido a la textura compleja)

Aquí hay algunas sugerencias para optimizar el tamaño del modelo:

  1. Prefiere el formato .glb sobre el .gltf . .glb es un formato binario, que es entre un 25 % y un 30 % más pequeño que el formato JSON de .gltf.

  2. Separar la textura (Texture) del modelo y cargarlo en paralelo . En el modelo de 23M, solo 2,3M es el tamaño del modelo, y el resto son mapas de textura. Después de separar el modelo y la textura, la velocidad de carga del modelo se puede reducir considerablemente.

  3. Use herramientas como Draco, gltfpack o algún compresor en línea para comprimir el modelo (Blender tiene opciones de compresión basadas en Draco al exportar modelos gltf). Este proyecto comprime el tamaño del modelo en un 50% a través de este paso: 3M → 1,2M.

  4. Comprimir la textura (Texture) . Este proyecto utiliza 5 texturas, después de la compresión: 18M → 2M.

Después de la optimización, el tamaño del modelo inicial se redujo de 23M a 1,2M, y el primer tiempo de carga se redujo de 9 s a menos de 3 s.

(La imagen de la izquierda es antes de la optimización y la imagen de la derecha es después de la optimización)

imagen

imagen

Cuatro Resumen

Ahora, básicamente hemos completado el desarrollo de toda la sala de exposiciones en 3D. Aunque hay algunos detalles que no se tratan en el artículo, el proceso de desarrollo es más o menos el mismo.

(1) Comprender los modelos Blender, GLTF / GLB

(2) js importar modelo GLTF/GLB

(3) Restauración del borrador de diseño

  • añadir fuente de luz

  • Ajuste los materiales del modelo y agregue texturas ambientales.

  • agregar sombras

(4) Realice el joystick móvil virtual para controlar el movimiento de la cámara

(5) Aumentar la detección de colisiones

(6) Ajuste de rendimiento:

  • Horneado de texturas: reduzca la pérdida de rendimiento de la luz y las sombras en tiempo real mediante el horneado de texturas.

  • Optimizar el tamaño del paquete:

- Prefiere el formato .glb sobre .gltf

- Separación de texturas y modelos.

- modelo comprimido

- Texturas comprimidas

5. Otros

algunos consejos:

  • Los diseñadores deben estandarizar la denominación de objetos y materiales en Blender para evitar nombres extraños o sin sentido, ya que se utilizarán durante el proceso de desarrollo y son fáciles de confundir.

  • Los diseñadores deben tener cuidado al reutilizar materiales en Blender para evitar afectar otros objetos que usan el mismo material (errores potenciales) al ajustar un determinado material.

  • Cuando el modelo se carga lentamente, puede aumentar la barra de progreso de carga para aliviar la ansiedad de espera. El cargador Three.js admite la consulta de progreso de carga.

  • La interfaz de Three.js cambia con frecuencia entre las diferentes versiones. Preste atención a la diferencia de versión cuando lo use y preste atención a la compatibilidad de la interfaz cuando tenga un problema con Google.

  • Three.js es engorroso para realizar el efecto de luz de los objetos y consume rendimiento, por lo que se puede evitar tanto como sea posible durante el diseño.

  • El movimiento de la cámara de Three.js no es lo suficientemente suave y puede probar Babylon.js para proyectos que se centren en la suavidad del cambio de cámara.

  • Algunos navegadores no son compatibles con videoTexture (reproducir video en el modelo), así que diseñe este tipo de función con cuidado o haga un buen trabajo de compatibilidad.

referencia:

Supongo que te gusta

Origin blog.csdn.net/vivo_tech/article/details/131717174
Recomendado
Clasificación