Volver al portfolio

Herramientas de producción · De 3D a 2D

SpriteBaker

Un editor para transformar modelos, animaciones y escenas 3D en sprites direccionales para un pipeline de producción 2D.

Producir sprites a partir de 3D exige coherencia entre poses, cámara, iluminación y encuadre. SpriteBaker reúne estas decisiones en un flujo de composición, inspección y bake: los PNG contienen la apariencia, y el JSON describe con precisión cómo utilizar cada frame.

La idea inicial era ejecutar SpriteBaker en el navegador, lo que motivó la elección de WebGL2 y Three.js. Después trasladé el proyecto al escritorio debido a las limitaciones del navegador. Hoy, el editor React/TypeScript y el renderizador Three.js/WebGL2 están integrados con un host Windows en C#/.NET con WebView2. Los assets se procesan localmente, y las reglas de captura permanecen independientes de la interfaz y de las capacidades nativas.

El renderizado utiliza WebGL2: Three.js organiza la escena y los shaders GLSL ejecutan los estilos y los pases de imagen en la GPU. La viewport, Sprite Preview y la captura comparten las estrategias de apariencia para que la inspección corresponda al resultado exportado.

  • TypeScript
  • React
  • Three.js
  • WebGL2
  • C# / .NET
  • WebView2
Personaje en la viewport con guías de captura y anillo de direcciones, jerarquía del modelo en el Outliner, propiedades de escena y Timeline con frames de bake.

Descripción general

Una escena, un plan de captura, salidas verificables

El trabajo comienza con un modelo GLB, glTF o FBX, sus materiales y clips. La escena puede combinar personaje, equipo y props, seguir un hueso y añadir keys de transformación. Las imágenes PNG/JPEG también pueden recibir estilos, outline y fondo mediante una captura de un solo frame.

Layout, Animate, Materials y Bake & Export organizan la creación. La viewport permite explorar; Sprite Preview muestra la cámara y el pipeline de captura. Antes de generar, la herramienta calcula sprites, páginas y presupuesto de memoria. Seis frames en ocho direcciones representan 48 sprites únicos, aunque cada uno aparezca en varias salidas.

  1. Componer y preparar

    Importar assets locales y ajustar relaciones, materiales y transformaciones conservando los archivos de origen.

  2. Seleccionar e inspeccionar

    Elegir clips, frames, direcciones y estilo; comprobar el encuadre y el sprite que se capturará.

  3. Capturar y entregar

    Ejecutar el plan y exportar hojas PNG, metadata JSON, un ZIP o archivos a una carpeta local.

01 · Límites del código

Responsabilidades propias para dominio, GPU e interfaz

El monorepo del Frontend separa tres paquetes: core, renderer y web. Core calcula muestreo, direcciones, layout, presupuestos y metadata sin React, Three.js, DOM ni red. Renderer posee los loaders, la evaluación de poses, la cámara y los recursos WebGL2. La aplicación organiza interacción, selecciones y jobs.

Las dependencias siguen web → renderer → core, con acceso directo de web a core. Los puntos de entrada públicos evitan depender de los archivos internos de otro paquete. Composición e interfaces pequeñas sostienen Strategy para estilos, Factory para loaders y una fachada de captura, sin una clase central responsable de toda la escena.

CapaResponsabilidadDecisión
core · TypeScriptFrames, ángulos, CapturePlan, hojas y JSONReglas de dominio independientes de la GPU
renderer · Three.js / WebGL2Importación, pose, materiales y píxelesCiclo de vida explícito de recursos
web · ReactWorkspaces, estado y orquestaciónEscena/GPU fuera del render de React
Desktop · C# / WPFWebView2, archivos y optimizaciónPuerto DesktopHost y mensajes versionados
API · ASP.NET CoreBase de servicios y health checksIndependiente del editor y del bake

02 · Editor DCC

Cuatro workspaces para un flujo continuo

Cada workspace reorganiza áreas con editor y cabecera propios. Layout reúne viewport, Timeline, Outliner y Properties. Animate añade clips, Sprite Preview y Dope Sheet. Materials acerca bibliotecas de texturas, slots y preview. Bake & Export coloca la inspección del sprite junto al Sheet Viewer y las propiedades de salida.

Las áreas se redimensionan con puntero y teclado. Menús, foco y campos numéricos siguen contratos accesibles; las keys comunican estados mediante forma y color. Las ediciones válidas se aplican inmediatamente, y un gesto de arrastre crea un paso de undo. Cambiar de workspace reutiliza renderizadores en lugar de recrear contextos WebGL.

Clip de animación en el Dope Sheet, con ocho frames de bake muestreados cada cuatro frames y la pose en el playhead mostrada al lado.

03 · Composición y tiempo

Assets relacionados, animaciones sincronizadas

Cada asset conserva sus recursos y clips, con un wrapper para transformación y un anexo opcional a un nodo de otro asset. Un arma puede seguir la mano del personaje mientras otro prop reproduce su propio clip en el mismo tiempo absoluto. Las keys de transformación de assets y piezas se distinguen de los frames elegidos para exportar.

El muestreo utiliza FPS global y tiempos absolutos: un clip de un segundo a 30 FPS tiene muestras de 0 a 29, sin duplicar el final del loop. La velocidad de reproducción solo modifica la inspección. Los clips externos exigen tracks resolubles y compatibilidad del skeleton; el retargeting permanece como mejora planificada.

04 · Contrato de salida

Planificar antes de renderizar

El CapturePlan inmutable congela settings normalizados, muestras, direcciones, encuadre, celdas y estimaciones durante el job. El orden lógico es animación, frame y ángulo; en las hojas, cada dirección inicia una fila y sus frames avanzan de izquierda a derecha. Combined y Separate comparten capturas cuando es posible.

Las salidas pueden incluir composición y hojas por asset. Whole muestra el asset entero; Cut out conserva la oclusión de otros objetos. Todas utilizan rectángulos y cámara compatibles. El JSON versionado registra tiempo, duración, dirección, pivot y placements; archivos, dimensiones reales de PNG, referencias y solapamientos se verifican antes de habilitar las descargas.

Resultado del bake en el Sheet Viewer: ocho frames en ocho direcciones, un total de 64 sprites, con cuadrícula y controles de exportación PNG y JSON.
PNG exportado en Brushstroke: ocho frames × ocho direcciones = 64 sprites de 128 × 128 px, con padding de 2 px, en una hoja de 1056 × 1056 px. Cada fila corresponde a una dirección de 0° a 315°; las columnas muestran los frames 0, 4, 8, 12, 16, 20, 24 y 28.
Crouch_Move_Loop · primer sprite en el JSON exportado
{
    "id": "clip-0_f0_a0",
    "animationId": "clip-0",
    "frameIndex": 0,
    "timeSeconds": 0,
    "durationSeconds": 0.13333333333333333,
    "angleDegrees": 0,
    "pivot": {
        "x": 0.5,
        "y": 0.7324728096403346
    },
    "placements": [
        {
            "sheetId": "combined-001",
            "x": 2,
            "y": 2,
            "width": 128,
            "height": 128
        }
    ]
}

Entrada real del primer sprite de la hoja anterior: frame 0, dirección 0°, tiempo, duración, pivot y posición en la hoja. Las coordenadas son píxeles medidos desde la esquina superior izquierda. El JSON completo también registra los 64 sprites, la cámara, el estilo Brushstroke, la iluminación y los ajustes del bake.

05 · Estabilidad visual

Un encuadre para todas las poses y direcciones

Auto-fit mide vértices deformados por skinning y morphs en las poses y direcciones seleccionadas, incluido root motion. Un pivot de referencia fijo y una cámara resuelta para todo el plan evitan que el personaje cambie de escala o de apoyo entre frames. Las capturas ortográfica y en perspectiva comparten esta regla.

Frente, elevación, zoom y offsets pertenecen a la captura; orbit, pan y zoom de la viewport pertenecen a la exploración. Marco, anillo de direcciones y grid ayudan a inspeccionar la escena sin aparecer en el PNG. Los ángulos son explícitos, sin imponer nombres de brújula a la orientación importada, y el preview señala recortes intencionales.

Personaje Crouch_Move_Loop en la cámara de captura, con ocho direcciones en pasos de 45°, Outliner, propiedades y Timeline visibles.

06 · Estrategias de apariencia

Estilos con contratos explícitos de color y alpha

Cada estilo declara su render y procesamiento. Los materiales derivados se aplican temporalmente y se restauran al terminar, incluso si hay un fallo. Pixelated usa resolución interna y ampliación entera por nearest-neighbor; una paleta y un Bayer estables evitan cambiar la cuantización entre frames. Hand Painted combina material, luz y gradación.

Normal Map captura datos lineales en espacio de cámara, con inversión opcional de los canales rojo y verde. Emissive aísla la emisión y trata zonas no emisivas. El pipeline distingue datos de color sRGB, conserva alpha recto y pone RGB a cero bajo alpha cero; el fondo sólido se compone después de los efectos.

EstiloEstrategia
OriginalMateriales compatibles con el loader bajo iluminación de captura
PixelatedBaja resolución, gradación, Bayer opcional y paleta fija
Hand PaintedLuz en bandas, textura suavizada y control de brillos
Normal MapNormales codificadas como datos para iluminación 2D
EmissiveEmisión del material con máscara por threshold
BrushstrokePinceladas procedurales con color y flujo de la forma

Estilos · una pose, varias renderizaciones

Selecciona un estilo para ver su resultado. Cada opción presenta una imagen independiente del mismo modelo y pose.

Sprite renderizado con el estilo Original
Sprite renderizado con el estilo Pixelated
Sprite renderizado con el estilo Hand Painted
Sprite renderizado con el estilo Normal Map
Sprite renderizado con el estilo Emissive
Sprite renderizado con el estilo Brushstroke

07 · Coherencia temporal

Pinceladas que siguen la superficie

Brushstroke repinta la captura con pinceles procedurales, una base suavizada y semillas deterministas. En modelos, las semillas se distribuyen sobre la superficie en reposo y siguen skinning y morphs. El flujo sigue la tangente UV o la orientación de superficie, manteniendo la pintura vinculada a la forma al animar o cambiar de dirección.

Dry, Fat, Feathery, Streaky y Grunge amplían la biblioteca con capas, impasto, alineación a la luz y mezcla de color RYB. Imágenes, outline y sombra utilizan semillas en espacio de imagen. La planificación y composición de la viewport se ejecutan en GPU; la captura exportada aplica el estilo en las dimensiones elegidas para el sprite.

Brushstroke · superficie y pinceles

Selecciona un pincel para comparar su resultado en Brushstroke.

Preview de Brushstroke con el pincel Default
Preview de Brushstroke con el pincel Dry
Preview de Brushstroke con el pincel Fat
Preview de Brushstroke con el pincel Feathery
Preview de Brushstroke con el pincel Streaky
Preview de Brushstroke con el pincel Grunge

08 · Edición reversible

Materiales editables conservando su origen

Materials permite asignar texturas por slot, seleccionar canales de mapas empaquetados y ajustar la convención de normales. Metallic y Roughness también aceptan valores numéricos sin textura. El preview muestra esfera o modelo bajo luz Studio o Capture, junto a una miniatura del material en el sprite.

Las ediciones entran en el historial de la escena, invalidan el resultado anterior y pueden volver al material original. Las texturas KTX2 comprimidas reciben miniaturas pintadas por GPU mediante el renderizador del preview de material, con caché por textura. Esta ruta conserva orientación y codificación de datos sin abrir otro contexto WebGL.

Material del personaje en la esfera de preview con iluminación Studio, biblioteca de texturas y slots de color, roughness y normal visibles.
El mismo material con Capture light seleccionado: el preview usa la iluminación de captura, mientras el resultado del sprite aparece al lado.

09 · Dirección de arte

Luz de escena con control sobre la estilización

Hasta ocho luces point o spot complementan la iluminación de captura. Color, intensidad, radio, suavidad y cono son ajustables, con gizmos y volúmenes de debug en la viewport. Affected by render style decide si la contribución se cuantiza o repinta junto al sujeto, o se suma después del estilo.

Los god rays utilizan la cobertura de la silueta para crear haces en espacio de pantalla; necesitan espacio en el encuadre y no equivalen a volumetría con profundidad. La sombra de suelo es una capa independiente, dentro del sprite o en hojas separadas. Marcadores y volúmenes de debug quedan limitados a la viewport.

Luces · gizmo, alcance y resultado

Selecciona un tipo de luz para ver su gizmo y alcance.

Gizmo y alcance de la luz Spotlight
Gizmo y alcance de la luz Point light

10 · Interacción y coste

Evitar trabajo y sincronización innecesarios

Los pases de estilo de la viewport se ejecutan en GPU, incluido Brushstroke, sin transferencias de píxeles a la CPU en cada frame. Los targets se reutilizan y el coste inicial de shaders se trata por separado. Los materiales derivados comparan su estado efectivo para evitar reconstrucciones causadas únicamente por la versión interna de un material compartido.

Sprite Preview utiliza la ruta de captura, pero agrupa ráfagas de edición: una captura en curso y una petición final con los settings más recientes. El scheduler del bake cede control entre lotes de preparación, sprites y páginas. Estas estrategias reducen bloqueos y mantienen definidos la inspección interactiva y el resultado final.

11 · Memoria y E/S

Leer los datos necesarios por intervalos

El host Windows ofrece E/S nativa mediante DesktopHost; renderer y core siguen utilizando contratos de archivo. En GLB, cabecera y JSON se leen primero y cada bufferView llega por intervalo. glTF aplica la misma ruta a buffers locales. En escritorio, MemoryMappedFile entrega estos intervalos en SharedBuffers de solo lectura.

La concurrencia limita lecturas y bytes en vuelo. El puente valida versión, origen, petición y tamaño, entrega IDs opacos y libera buffers en todas las rutas. Los arrays de geometría y texturas necesarios para bounds, captura y recuperación de contexto permanecen en CPU. Leer por intervalos reduce intermediarios; no elimina el coste GPU de una escena grande.

12 · Copias locales

Optimización GPU con integridad y caché controlada

Optimize for GPU genera una copia de GLB/glTF con gltfpack fijado por versión y hash: geometría meshopt y texturas KTX2, con UASTC o ETC1S para base color. El original se conserva. La clave de caché incluye contenido, herramienta, receta y parámetros; el archivo sidecar verifica tamaño y SHA-256 de la copia antes de reutilizarla.

La caché tiene límite configurable, 10 GiB por defecto, eliminación por uso más antiguo y reservas que protegen las copias en uso. Los decoders vienen en el bundle. El instalador por usuario conserva preferencias y caché al actualizar y pregunta si debe eliminar los datos al desinstalar. La optimización consume memoria propia y no garantiza reducir el pico del renderer.

13 · Continuidad del trabajo

Generar conservando el trabajo anterior

Importación y generación tienen estados separados. Si falla la sustitución de un asset, el anterior permanece disponible; cuando se solicitan varias importaciones, solo la más reciente puede ocupar la escena. Durante el bake, el plan queda congelado y las ediciones de escena esperan a que termine, con cancelación disponible.

Cancelar o interrumpir una generación descarta las salidas parciales y conserva el último resultado completo. Los cambios de cámara, materiales o settings indican que la hoja necesita otro bake. Los problemas de contexto WebGL permiten reiniciar el renderer y retomar el trabajo, con mensajes que identifican lo que debe corregirse.

14 · Extensión del producto

Servicios preparados sin acoplar el bake

La API en ASP.NET Core y PostgreSQL establece una base para futuros servicios. Expone información de la aplicación y health checks, distingue proceso activo de base accesible y devuelve fallos mediante Problem Details.

El editor y la aplicación de escritorio no dependen de esta API para importar, renderizar o exportar. Los assets siguen siendo locales, mientras preferencias pequeñas y presets propios se versionan por separado. Persistencia de escena, biblioteca de assets, cuentas y cloud storage necesitan contratos y entregas específicos antes de formar parte del producto.

Próximos pasos

Lo consolidado y lo que queremos mejorar

La base consolidada reúne cuatro workspaces, composición de modelos, keys por pieza, materiales editables, seis estilos, luces, hojas por asset, exportación PNG/JSON/ZIP y presets Unity RTS. Windows añade diálogos nativos, lectura por intervalos, copias optimizadas y caché gestionada. Cada capacidad conserva los contratos de captura y los archivos de origen.

Las mejoras planificadas incluyen proyectos y recipes persistidos, biblioteca de assets, retargeting, OBJ, packing avanzado y exportadores específicos de engines. El objetivo es recuperar configuraciones de producción, reutilizar assets y ampliar integraciones manteniendo previsibles el tiempo, la cámara y la metadata.

Otras mejoras incluyen reducir el trabajo síncrono de captura, mejorar el uso de memoria en escenas grandes y ampliar la compatibilidad. WebGPU es una opción para necesidades concretas de compute. Estas líneas están planificadas; los servicios de storage y la restauración completa de proyectos todavía requieren implementación propia.

Contacto

Ciudad de Québec, QC, Canadá / Disponible para oportunidades

Estoy abierto a oportunidades en desarrollo de software, programación de herramientas y gameplay, así como a puestos de artista 3D junior. Si mi experiencia encaja con tu equipo, estaré encantado de conversar a través de mis perfiles sociales.