WebGL con Three.js Modelos y Animación

Los gráficos 3D en el navegador han sido un tema candente desde que fueron presentados. Pero si tuviera que crear sus aplicaciones utilizando WebGL antiguo, llevaría mucho tiempo. Es por eso que han surgido algunas bibliotecas realmente útiles. Three.js es uno de los más populares, y en esta serie te mostraré cómo hacer el mejor uso posible para crear impresionantes experiencias 3D para tus usuarios..

Espero que tengas un conocimiento básico del espacio 3D antes de comenzar a leer este tutorial, ya que no explicaré temas como coordenadas y vectores.


Preparación

Como de costumbre, comenzaremos desde el código que creó anteriormente. Descargue y descomprima los activos que proporcioné y estará listo para comenzar.


Paso 1: una palabra acerca de exportar modelos en Blender

Antes de comenzar la parte de programación, explicaré algo con lo que muchas personas tienen problemas. Cuando haya creado un modelo en Blender y desee exportarlo al formato Three.js, debe tener en cuenta lo siguiente:

  • Primero, quita la crianza. El exportador Three.js no exportará animaciones si lo dejas (esto también se aplica al Modificador de Armadura)
  • Segundo grupo de vértices. Si quieres que el hueso mueva los vértices, debes agruparlos y nombrar al grupo con el nombre del hueso..
  • Tercero, solo puedes tener una animación.. Esto puede parecer un gran problema, pero explicaré la solución más adelante..

Además, al exportar debe asegurarse de que estas opciones estén seleccionadas en el exportador: Desuello, Huesos y Animacion esqueletica.


Paso 2: Importando el Modelo

Al igual que con casi todo en Three.js, la importación de modelos es muy simple. Hay una clase especial, THREE.JSONLoader Eso hará todo por nosotros. Por supuesto, solo carga los modelos JSON, pero se recomienda usarlos, así que solo cubriré este cargador (otros funcionan de la misma manera). Vamos a inicializarlo primero:

 var loader = new THREE.JSONLoader; animacion var

No hay argumentos necesarios. También necesitamos definir Una variable para la animación, para que podamos acceder a ella más adelante. Ahora podemos cargar el modelo:

 loader.load ('./ model.js', función (geometría, materiales) var skinnedMesh = new THREE.SkinnedMesh (geometry, new THREE.MeshFaceMaterial (materiales)); skinnedMesh.position.y = 50; skinnedMesh.scale. set (15, 15, 15); scene.add (skinnedMesh); animate (skinnedMesh););

los carga El método acepta dos parámetros: una ruta al modelo y una función de devolución de llamada. Se llamará a esta función cuando se cargue el modelo (por lo tanto, mientras tanto, puede mostrar una barra de carga al usuario). Se llamará a una función de devolución de llamada con dos parámetros: la geometría del modelo y sus materiales (estos se exportan con ella). En la devolución de llamada, estamos creando la malla, pero esta vez es TRES., que soporta animaciones.

A continuación, movemos el modelo 50 unidades hacia arriba para colocarlo en la parte superior de nuestro cubo, escalarlo 15 veces (porque tiendo a crear modelos pequeños en Blender) y agregarlo a la escena. A continuación llamamos al animar Función que configurará y reproducirá la animación..


Paso 3: Animación

Ahora configuramos la animación. Esta es la fuente de la animar función:

 function animate (skinnedMesh) var materials = skinnedMesh.material.materials; para (var k en materiales) materiales [k] .skinning = true;  THREE.AnimationHandler.add (skinnedMesh.geometry.animation); animación = nuevo THREE.Animation (skinnedMesh, "ArmatureAction", THREE.AnimationHandler.CATMULLROM); animación.play (); 

Primero tenemos que habilitar el skinning (animaciones) en todos los materiales del modelo. A continuación, tenemos que agregar la animación del modelo a TRES.AnimaciónHandler y crea el TRES.Animacion objeto. Los parámetros están en el siguiente orden: la malla para animar, el nombre de la animación en el modelo y el tipo de interpolación (útil cuando tiene un modelo complicado como un cuerpo humano, donde desea que la malla se doble sin problemas). Finalmente, jugamos la animación..

Pero si abre el navegador ahora, verá que el modelo no se está moviendo:

Para arreglar esto, tenemos que agregar una línea a nuestro hacer función, justo debajo de la sístema de partículas rotación:

 if (animation) animation.update (delta);

Esto actualizará el tiempo en la animación, por lo que TRES.AnimaciónHandler sabe qué marco hacer. Ahora abra el navegador y debería ver la curva superior del cubo hacia la izquierda y hacia la derecha:


Paso 4: Animaciones múltiples

Sí, hay una solución para una sola secuencia de animación en un modelo, pero requiere que la edites. La idea es que agregue cada animación a una secuencia, luego, cuando esa finaliza, comienza la siguiente. A continuación, después de que haya exportado su modelo, necesita cambiar el código de animación. Digamos que tenemos una animación permanente desde el principio hasta el tercer segundo, y una animación para caminar desde el tercer segundo hasta el final. Entonces en nuestro hacer En función de qué segundo es la animación, y si llega a la hora de finalización de la secuencia actual, deténgala y reprodúzcala desde el principio:

 var currentSequence = 'standing'; function (render) … if (animation) animation.update (delta); if (currentSequence == 'standing') if (animation.currentTime> 4) animation.stop (); animación.juego (falso, 0); // reproducir la animación no en bucle, desde 0s else if (currentSequence == 'walking') if (animation.currentTime <= 4 || animation.currentTime > 8) animación.stop (); animación.juego (falso, 4); // Reproducir la animación no en bucle, desde 4s…

Debes recordar iniciar las animaciones no en bucle y desde la hora correcta. Esto, por supuesto, será defectuoso si la velocidad de fotogramas del usuario es realmente baja, porque el delta será mayor y animación.currentTime puede ser mucho más alto que el límite para cualquier secuencia en particular, lo que resulta en reproducir parte de la siguiente secuencia. Pero solo se notará si los deltas son aproximadamente 300-500ms.

Ahora para cambiar el animar Para reproducir la animación de caminar, solo agregue estos argumentos a la animación.jugar función:

 animación.juego (falso, 0);

Además, permitamos que el usuario cambie entre animaciones usando el una llave. Agregue este código al final del archivo, justo antes de la hacer() llamada:

 document.addEventListener ('keyup', función (e) if (e.keyCode == 'A'.charCodeAt (0)) currentSequence = (currentSequence ==' standing '?' walking ':' standing '); );

Paso 5: Adjuntar al hueso

Esta técnica es particularmente útil en los juegos de rol, pero también puede aplicarse a otros géneros. Se trata de adjuntando Otro objeto en el hueso del objeto animado: ropa, armamento, etc..

Empecemos modificando nuestra loader.load llamar de vuelta. Agregue este código debajo de scene.add (skinnedMesh '):

 item = new THREE.Mesh (new THREE.CubeGeometry (100, 10, 10), new THREE.MeshBasicMaterial (color: 0xff0000)); item.position.x = 50; pivot = new THREE.Object3D (); pivot.scale.set (0.15, 0.15, 0.15); pivot.add (elemento); pivot.useQuaternion = true; skinnedMesh.add (pivote);

los ít la malla simula algo que puede adjuntar a un objeto animado. Para hacerlo girar alrededor de un punto específico, y no alrededor del centro, lo agregaremos a un pivote Objeto y muévelo 50 unidades (la mitad del ancho) hacia la derecha. Tenemos que escalarlo para 0.15, porque se agregará a la piel de malla que tiene una escala de 15. Finalmente, antes de agregarlo a nuestro objeto animado, le decimos que use cuaterniones..

Básicamente, los cuaterniones son un sistema numérico, pero como Three.js maneja todo por nosotros, no tiene que profundizar en este tema si no quiere (pero si lo hace, eche un vistazo a su página de Wikipedia). Se utilizan para rotar objetos sin el riesgo de bloqueo de cardán..

Ahora en el hacer Función que tenemos para actualizar la posición y rotación del objeto:

 pivot.position = new THREE.Vector3 (). getPositionFromMatrix (skinnedMesh.bones [2] .skinMatrix); pivot.quaternion.setFromRotationMatrix (skinnedMesh.bones [2] .skinMatrix);

Déjame explicarte lo que está pasando aquí. Primero, establecemos que la posición sea la misma que en el último hueso del modelo. Estamos usando el pielMatriz Propiedad para calcularlo. Luego usamos la misma propiedad para calcular el cuaternión para el pivotela rotación de. Después de eso, puede abrir el navegador y debería ver la viga roja adjunta a nuestro modelo:


Conclusión

Espero que hayas aprendido algunas nuevas técnicas interesantes de este tutorial. Como siempre, siéntase libre de experimentar con la aplicación que hemos creado. En el siguiente (y último) tutorial de esta serie, te mostraré el verdadero poder de OpenGL / WebGL-Shaders.