Resumen técnico
Last updated
Last updated
Needle Engine se compone a grandes rasgos de tres partes:
una serie de componentes y herramientas que permiten configurar escenas para Needle Engine, por ejemplo, desde el Unity Editor.
un exportador que convierte los datos de la escena y los componentes a glTF.
un runtime web que carga y ejecuta los archivos glTF producidos y sus extensiones.
El runtime web utiliza three.js para el renderizado, añade un sistema de componentes sobre el grafo de escena de three y conecta cargadores de extensiones para nuestras extensiones glTF personalizadas.
Efectivamente, esto convierte herramientas como Unity o Blender en potentes centros de desarrollo web espacial, añadiendo assets glTF al flujo de trabajo típico de HTML, CSS, JavaScript y bundling.
Modelos, texturas, animaciones, luces, cámaras y más se almacenan como en Needle Engine. Los datos personalizados se almacenan en . Estas cubren todo, desde componentes interactivos hasta física, secuenciación y lightmaps.
Un glTF de producción típico creado por Needle Engine utiliza las siguientes extensiones:
Otras extensiones compatibles:
Extensiones de materiales compatibles:
Nota: Los materiales que utilizan estas extensiones pueden exportarse desde Unity a través del material
PBRGraph
de UnityGLTF.
Nota: El audio y las variantes ya son compatibles en Needle Engine a través de
NEEDLE_components
yNEEDLE_persistent_assets
, pero existen algunas opciones para una mayor alineación con las propuestas existentes, comoKHR_audio
yKHR_materials_variants
.
Needle Engine almacena datos personalizados en archivos glTF a través de nuestras extensiones de proveedor. Estas extensiones están diseñadas para ser flexibles y permitir introducir datos relativamente arbitrarios en ellas. Es importante destacar que no se almacena código en estos archivos. Los componentes interactivos se restauran a partir de los datos en tiempo de ejecución. Esto tiene algunas similitudes con la forma en que funcionan los AssetBundles en Unity: el lado receptor de un asset necesita tener el código coincidente para los componentes almacenados en el archivo.
Actualmente no proporcionamos esquemas para estas extensiones, ya que todavía están en desarrollo. Los fragmentos JSON que se muestran a continuación demuestran el uso de extensiones mediante ejemplos e incluyen notas sobre las elecciones arquitectónicas y lo que podemos cambiar en futuras versiones.
Las referencias entre datos se construyen actualmente a través de una mezcla de índices a otras partes del archivo glTF y punteros JSON. Podríamos consolidar estos enfoques en una versión futura. También almacenamos GUIDs basados en cadenas para casos en los que el orden es difícil de resolver de otra manera (por ejemplo, dos componentes que se referencian mutuamente) que podríamos eliminar en el futuro.
Esta extensión contiene datos de componentes por nodo. Los nombres de los componentes se corresponden con nombres de tipo tanto en el lado JavaScript como en el C#. Se pueden añadir varios componentes con el mismo nombre al mismo nodo.
Nota: Almacenar solo el nombre del tipo de componente significa que actualmente los nombres de tipo deben ser únicos por proyecto. Estamos planeando incluir nombres de paquete en una versión futura para flexibilizar esta restricción a nombres de tipo de componente únicos por paquete en lugar de globalmente.
Nota: Actualmente no hay información de versionado en la extensión (a qué paquete npm pertenece un componente, contra qué versión de ese paquete se exportó). Estamos planeando incluir información de versionado en una versión futura.
Nota: Actualmente, todos los componentes están en el array
builtin_components
. Podríamos renombrar esto a simplementecomponents
en una versión futura.
Esta es una extensión raíz que define propiedades de iluminación ambiental por archivo glTF.
Nota: Esta extensión podría tener que definirse por escena en lugar de por archivo.
Esta es una extensión raíz que define un conjunto de lightmaps para el archivo glTF.
Nota: En este momento, esta extensión también contiene referencias a texturas de entorno. Estamos planeando cambiar eso en una versión futura.
Lightmap
0
Environment Map
1
Reflection Map
2
Nota: Podríamos cambiar eso en una versión futura y mover los datos relacionados con lightmaps a una entrada de extensión
NEEDLE_lightmap
por nodo.
Los componentes en NEEDLE_components
pueden referenciar datos a través de Punteros JSON. Los datos en NEEDLE_persistent_assets
son a menudo referenciados varias veces por diferentes componentes y, por lo tanto, se almacenan por separado en una extensión raíz. Por diseño, siempre son referenciados por algo más (o tienen referencias entre sí), y por lo tanto no almacenan información de tipo en absoluto: son simplemente fragmentos de datos JSON y los componentes que los referencian actualmente necesitan saber qué esperan.
Ejemplos de assets/datos almacenados aquí son:
AnimatorControllers, sus capas y estados
PlayableAssets (timelines), sus pistas y clips incrustados
SignalAssets
...
Los datos en persistent_assets
pueden referenciar otros persistent_assets
a través de Punteros JSON, pero por diseño no pueden referenciar NEEDLE_components
. Esto es similar a la separación entre "Datos de escena" y "Contenido de AssetDatabase" en Unity.
Nota: Podríamos incluir más información de tipo y versionado en el futuro.
Nota: Actualmente, los shaders de vértices y fragmentos siempre están incrustados como URI; planeamos mover esos datos a bufferViews más razonables en el futuro.
Nota: Aquí hay algunas propiedades redundantes que planeamos limpiar.
🏗️ En Construcción
🏗️ En Construcción
Aunque el proceso de compilación de Unity de C# a IL a C++ (a través de IL2CPP) a WASM (a través de emscripten) es ingenioso, también es relativamente lento. Construir incluso un proyecto simple a WASM lleva muchos minutos, y ese proceso se repite prácticamente con cada cambio de código. Algo de eso se puede evitar a través de un almacenamiento en caché inteligente y asegurándose de que las builds de desarrollo no intenten eliminar tanto código, pero aún así sigue siendo lento.
Tenemos un prototipo para alguna traducción a WASM, pero está lejos de estar completo y la velocidad de iteración sigue siendo lenta, por lo que no estamos investigando activamente este camino en este momento.
Al examinar los flujos de trabajo web modernos, descubrimos que los tiempos de recarga de código durante el desarrollo son despreciables, generalmente en rangos inferiores al segundo. Esto, por supuesto, cambia algo de rendimiento (interpretación de JavaScript sobre la marcha en lugar de optimización del compilador en tiempo de construcción) por flexibilidad, pero los navegadores se han vuelto muy buenos en sacar el máximo provecho de JavaScript.
Creemos que para la iteración y los flujos de trabajo de prueba estrictos, es beneficioso poder probar en el dispositivo y en la plataforma de destino (el navegador, en este caso) tan rápido y tan a menudo como sea posible, por lo que estamos omitiendo todo el modo Play de Unity, ejecutándonos efectivamente siempre en el navegador.
Nota: Un efecto secundario realmente agradable es evitar el paso lento de "recarga de dominio" que generalmente cuesta entre 15 y 60 segundos cada vez que se entra en el modo Play. Simplemente estás "en vivo" en el navegador en el momento en que presionas Play.
Página traducida automáticamente usando IA
Se pueden añadir más extensiones y extensiones personalizadas utilizando los callbacks de exportación de UnityGLTF (aún no documentado) y las de three.js.
Para la producción, comprimimos los assets glTF con . Las texturas utilizan etc1s
, uastc
, webp
o ninguna compresión, dependiendo del tipo de textura. Las mallas utilizan draco
por defecto, pero se pueden configurar para usar meshtopt
(por archivo glTF). Las extensiones personalizadas se pasan de forma opaca.
Consulte la página de para obtener más información.
Los datos en NEEDLE_components
pueden ser animados a través de la extensión , que actualmente no está ratificada.
Esta extensión contiene datos adicionales por nodo relacionados con el estado, las capas y las etiquetas. Las capas se utilizan tanto para el renderizado como para la física, de forma similar a como las manejan y .
Nota: Es posible que necesitemos explicar mejor por qué esto no es otra entrada en .
La forma en que se aplican los lightmaps se define en el componente MeshRenderer
dentro de la extensión por nodo:
Esta extensión se basa en la extensión , que ya no se mantiene, y la extiende en algunos puntos cruciales. Aunque la extensión original se especificó para WebGL 1.0, la estamos utilizando con WebGL 2.0 y hemos añadido una serie de tipos de uniformes.