Retour au portfolio

Outils de production · De la 3D à la 2D

SpriteBaker

Un éditeur pour transformer modèles, animations et scènes 3D en sprites directionnels destinés à un pipeline de production 2D.

Produire des sprites à partir de la 3D exige des poses, une caméra, un éclairage et un cadrage cohérents. SpriteBaker rassemble ces choix dans un flux de composition, d'inspection et de capture : les PNG portent l'apparence, et le JSON décrit précisément l'utilisation de chaque image.

L’idée initiale était de faire fonctionner SpriteBaker dans le navigateur, ce qui a motivé le choix de WebGL2 et Three.js. J’ai ensuite fait évoluer le projet vers une application desktop en raison des limites du navigateur. Aujourd’hui, l’éditeur React/TypeScript et le moteur de rendu Three.js/WebGL2 sont intégrés à un hôte Windows en C#/.NET avec WebView2. Les ressources sont traitées localement, et les règles de capture restent indépendantes de l’interface et des capacités natives.

Le rendu utilise WebGL2 : Three.js organise la scène et des shaders GLSL exécutent les styles et les passes d’image sur le GPU. La viewport, le Sprite Preview et la capture partagent les stratégies de rendu pour que l’inspection corresponde au résultat exporté.

  • TypeScript
  • React
  • Three.js
  • WebGL2
  • C# / .NET
  • WebView2
Personnage dans la vue 3D avec guides de capture et anneau de directions, hiérarchie du modèle dans l’Outliner, propriétés de scène et Timeline avec images de bake.

Présentation

Une scène, un plan de capture, des sorties vérifiables

Le travail commence par un modèle GLB, glTF ou FBX, ses matériaux et ses clips. La scène peut réunir personnage, équipement et accessoires, suivre un os et ajouter des clés de transformation. Les images PNG/JPEG peuvent également recevoir styles, contour et fond dans une capture à image unique.

Layout, Animate, Materials et Bake & Export organisent la création. La vue 3D permet l'exploration ; Sprite Preview montre la caméra et le pipeline de capture. Avant la génération, l'outil calcule sprites, pages et budget mémoire. Six images dans huit directions représentent 48 sprites uniques, même si chacun apparaît dans plusieurs sorties.

  1. Composer et préparer

    Importer des ressources locales et ajuster relations, matériaux et transformations en préservant les fichiers sources.

  2. Sélectionner et inspecter

    Choisir clips, images, directions et style ; vérifier le cadrage et le sprite qui sera capturé.

  3. Capturer et livrer

    Exécuter le plan et exporter les feuilles PNG, les métadonnées JSON, un ZIP ou les fichiers dans un dossier local.

01 · Frontières du code

Des responsabilités distinctes pour le domaine, le GPU et l'interface

Le monorepo Frontend sépare trois packages : core, renderer et web. Core calcule échantillonnage, directions, disposition, budgets et métadonnées sans React, Three.js, DOM ni réseau. Renderer possède les chargeurs, l'évaluation des poses, la caméra et les ressources WebGL2. L'application organise interactions, sélections et travaux de capture.

Les dépendances suivent web → renderer → core, avec un accès direct de web à core. Les points d'entrée publics évitent les dépendances aux fichiers internes d'un autre package. Composition et petites interfaces soutiennent Strategy pour les styles, Factory pour les chargeurs et une façade de capture, sans classe centrale responsable de toute la scène.

CoucheResponsabilitéDécision
core · TypeScriptImages, angles, CapturePlan, feuilles et JSONRègles de domaine indépendantes du GPU
renderer · Three.js / WebGL2Importation, pose, matériaux et pixelsCycle de vie explicite des ressources
web · ReactEspaces de travail, état et orchestrationScène/GPU hors du rendu React
Desktop · C# / WPFWebView2, fichiers et optimisationPort DesktopHost et messages versionnés
API · ASP.NET CoreFondation de services et contrôles de santéIndépendante de l'éditeur et de la capture

02 · Éditeur DCC

Quatre espaces pour un flux de travail continu

Chaque workspace réorganise des zones avec leur éditeur et leur en-tête. Layout réunit vue 3D, Timeline, Outliner et Properties. Animate ajoute clips, Sprite Preview et Dope Sheet. Materials rapproche bibliothèques de textures, slots et aperçu. Bake & Export place l'inspection du sprite à côté du Sheet Viewer et des propriétés de sortie.

Les zones se redimensionnent au pointeur et au clavier. Menus, focus et champs numériques suivent des contrats accessibles ; les clés utilisent forme et couleur pour communiquer leur état. Une modification valide s'applique immédiatement, et un geste de glissement crée une étape d'annulation. Changer de workspace réutilise les moteurs de rendu et leurs contextes WebGL.

Clip d’animation dans la Dope Sheet, avec huit images de bake échantillonnées toutes les quatre images et la pose au curseur temporel affichée à côté.

03 · Composition et temps

Des ressources liées, des animations synchronisées

Chaque ressource conserve ses données et ses clips, avec un wrapper pour sa transformation et un attachement facultatif à un nœud d'une autre ressource. Une arme peut suivre la main du personnage tandis qu'un accessoire joue son propre clip au même temps absolu. Les clés de transformation des ressources et des pièces sont distinctes des images sélectionnées pour l'export.

L'échantillonnage utilise une fréquence globale et des temps absolus : un clip d'une seconde à 30 FPS possède les échantillons 0 à 29, sans doubler la fin de boucle. La vitesse de lecture ne concerne que l'inspection. Les clips externes exigent des pistes résolubles et un squelette compatible ; le retargeting reste une extension prévue.

04 · Contrat de sortie

Planifier avant de rendre

Le CapturePlan immuable fige paramètres normalisés, échantillons, directions, cadrage, cellules et estimations pendant le travail. L'ordre logique est animation, image puis angle ; dans les feuilles, chaque direction commence une ligne et ses images avancent de gauche à droite. Combined et Separate partagent les captures lorsque possible.

Les sorties peuvent comprendre la composition et des feuilles par ressource. Whole montre la ressource entière ; Cut out conserve l'occlusion des autres objets. Toutes utilisent des rectangles et une caméra compatibles. Le JSON versionné enregistre temps, durée, direction, pivot et placements ; fichiers, dimensions réelles des PNG, références et chevauchements sont vérifiés avant le téléchargement.

Résultat du bake dans le Sheet Viewer : huit images dans huit directions, soit 64 sprites, avec grille et commandes d’export PNG et JSON.
PNG exporté en Brushstroke : huit images × huit directions = 64 sprites de 128 × 128 px, avec une marge de 2 px, sur une feuille de 1056 × 1056 px. Chaque ligne correspond à une direction de 0° à 315° ; les colonnes montrent les images 0, 4, 8, 12, 16, 20, 24 et 28.
Crouch_Move_Loop · premier sprite dans le JSON exporté
{
    "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
        }
    ]
}

Entrée réelle du premier sprite de la feuille ci-dessus : image 0, direction 0°, temps, durée, pivot et placement dans la feuille. Les coordonnées sont exprimées en pixels depuis le coin supérieur gauche. Le JSON complet décrit aussi les 64 sprites, la caméra, le style Brushstroke, l’éclairage et les paramètres du bake.

05 · Stabilité visuelle

Un cadrage pour toutes les poses et directions

L'auto-fit mesure les sommets déformés par skinning et morphs dans les poses et directions sélectionnées, root motion compris. Un pivot de référence fixe et une caméra résolue pour le plan entier empêchent le personnage de changer d'échelle ou d'appui entre les images. Les captures orthographique et perspective partagent cette règle.

Orientation frontale, élévation, zoom et décalages appartiennent à la capture ; orbite, déplacement et zoom de la vue 3D appartiennent à l'exploration. Cadre, anneau des directions et grille aident à inspecter la scène sans entrer dans le PNG. Les angles sont explicites, sans imposer de points cardinaux à l'orientation importée, et l'aperçu signale les coupes intentionnelles.

Personnage Crouch_Move_Loop dans la caméra de capture, avec huit directions espacées de 45°, Outliner, propriétés et Timeline visibles.

06 · Stratégies d'apparence

Des styles avec des contrats de couleur et d'alpha

Chaque style définit son rendu et ses traitements. Les matériaux dérivés sont appliqués temporairement et restaurés à la fin, même en cas d'échec. Pixelated utilise une résolution interne et un agrandissement entier au plus proche voisin ; palette et motif Bayer stables évitent une quantification différente à chaque image. Hand Painted associe matériau, éclairage et correction des couleurs.

Normal Map capture des données linéaires dans l'espace caméra, avec inversion facultative des canaux rouge et vert. Emissive isole l'émission et traite les zones non émissives. Le pipeline distingue données et couleur sRGB, préserve l'alpha droit et met RGB à zéro sous alpha nul ; le fond uni est composé après les effets.

StyleStratégie
OriginalMatériaux pris en charge par le chargeur sous l'éclairage de capture
PixelatedBasse résolution, correction, Bayer facultatif et palette fixe
Hand PaintedLumière en bandes, textures adoucies et contrôle des reflets
Normal MapNormales encodées comme données pour l'éclairage 2D
EmissiveÉmission du matériau avec masque par seuil
BrushstrokeTouches procédurales utilisant couleur et flux de la forme

Styles · une pose, plusieurs rendus

Sélectionnez un style pour voir son résultat. Chaque option présente une image distincte du même modèle et de la même pose.

Sprite rendu dans le style Original
Sprite rendu dans le style Pixelated
Sprite rendu dans le style Hand Painted
Sprite rendu dans le style Normal Map
Sprite rendu dans le style Emissive
Sprite rendu dans le style Brushstroke

07 · Cohérence temporelle

Des touches de pinceau qui suivent la surface

Brushstroke repeint la capture avec des pinceaux procéduraux, une sous-couche adoucie et des graines déterministes. Sur les modèles, les graines sont distribuées sur la surface au repos et suivent skinning et morphs. Le flux suit la tangente UV ou l'orientation de surface, maintenant la peinture attachée à la forme pendant l'animation et les changements de direction.

Dry, Fat, Feathery, Streaky et Grunge enrichissent la bibliothèque avec couches, empâtement, alignement à la lumière et mélange de couleurs RYB. Images, contours et ombres utilisent des graines en espace image. Planification et composition de la vue 3D restent sur le GPU ; la capture exportée applique le style aux dimensions choisies pour le sprite.

Brushstroke · surface et pinceaux

Sélectionnez un pinceau pour comparer son rendu Brushstroke.

Aperçu Brushstroke avec le pinceau Default
Aperçu Brushstroke avec le pinceau Dry
Aperçu Brushstroke avec le pinceau Fat
Aperçu Brushstroke avec le pinceau Feathery
Aperçu Brushstroke avec le pinceau Streaky
Aperçu Brushstroke avec le pinceau Grunge

08 · Édition réversible

Modifier les matériaux en préservant leur origine

Materials permet d'attribuer des textures par slot, de sélectionner les canaux des maps regroupées et d'ajuster la convention des normales. Metallic et Roughness acceptent également des valeurs numériques sans texture. L'aperçu montre une sphère ou le modèle sous lumière Studio ou Capture, avec une miniature du matériau dans le sprite.

Les modifications entrent dans l'historique, invalident le résultat précédent et peuvent revenir au matériau d'origine. Les textures KTX2 comprimées obtiennent des miniatures peintes par le GPU via le moteur de l'aperçu matériau, avec cache par texture. Ce chemin préserve orientation et encodage des données sans ouvrir un contexte WebGL supplémentaire.

Matériau du personnage sur la sphère d’aperçu sous l’éclairage Studio, avec bibliothèque de textures et slots de couleur, roughness et normal visibles.
Le même matériau avec Capture light sélectionné : l’aperçu utilise l’éclairage de capture, tandis que le résultat du sprite apparaît à côté.

09 · Direction artistique

L'éclairage de scène et sa relation au style

Jusqu'à huit lumières point ou spot complètent l'éclairage de capture. Couleur, intensité, rayon, douceur et cône sont réglables, avec gizmos et volumes de debug dans la vue 3D. Affected by render style décide si leur contribution est quantifiée ou repeinte avec le sujet, ou ajoutée après le style.

Les god rays utilisent la couverture de la silhouette pour créer des faisceaux en espace écran ; ils nécessitent de l'espace dans le cadrage et ne constituent pas une volumétrie avec profondeur. L'ombre au sol est une couche indépendante, dans le sprite ou sur des feuilles séparées. Marqueurs et volumes de debug restent dans la vue 3D.

Lumières · gizmo, portée et résultat

Sélectionnez un type de lumière pour voir son gizmo et sa portée.

Gizmo et portée de la lumière Spotlight
Gizmo et portée de la lumière Point light

10 · Interaction et coût

Éviter les calculs et synchronisations inutiles

Les passes de style de la vue 3D restent sur le GPU, Brushstroke compris, sans transfert de pixels vers le CPU à chaque image. Les cibles sont réutilisées et le coût de compilation initiale des shaders est traité séparément. Les matériaux dérivés comparent leur état effectif pour éviter les reconstructions dues à la seule version interne d'un matériau partagé.

Sprite Preview utilise le chemin de capture, mais regroupe les rafales de modifications : une capture en cours et une demande finale avec les paramètres les plus récents. Le scheduler du bake rend la main entre lots de préparation, sprites et pages. Ces stratégies réduisent les blocages tout en définissant clairement inspection interactive et livraison finale.

11 · Mémoire et E/S

Lire les données nécessaires par intervalles

L'hôte Windows fournit les E/S natives via DesktopHost ; renderer et core continuent d'utiliser les contrats de fichier. Pour le GLB, en-tête et JSON sont lus d'abord, puis chaque bufferView arrive par intervalle. glTF suit le même chemin pour les buffers locaux. Sur desktop, MemoryMappedFile livre ces intervalles dans des SharedBuffers en lecture seule.

La concurrence limite lectures et octets en vol. Le pont valide version, origine, demande et taille, fournit des identifiants opaques et libère les buffers sur tous les chemins. Les tableaux de géométrie et textures nécessaires aux bounds, à la capture et à la récupération du contexte restent sur le CPU. La lecture par intervalles réduit les intermédiaires ; le coût GPU d'une grande scène demeure.

12 · Copies locales

Optimisation GPU, intégrité et cache maîtrisé

Optimize for GPU crée une copie GLB/glTF avec gltfpack fixé par version et hash : géométrie meshopt et textures KTX2, en UASTC ou ETC1S pour base color. L'original est préservé. La clé du cache inclut contenu, outil, recette et paramètres ; un fichier compagnon vérifie taille et SHA-256 de la copie avant réutilisation.

Le cache possède une limite configurable, de 10 GiB par défaut, une éviction selon l'usage le plus ancien et des réservations protégeant les copies utilisées. Les décodeurs sont livrés dans le bundle. L'installateur par utilisateur préserve préférences et cache lors des mises à jour, puis demande si les données doivent être supprimées à la désinstallation. L'optimisation consomme sa propre mémoire et ne garantit pas un pic moindre du renderer.

13 · Continuité du travail

Générer en préservant le travail précédent

Importation et génération ont des états distincts. Un remplacement échoué conserve la ressource précédente ; lorsque plusieurs importations sont demandées, seule la plus récente peut devenir active dans la scène. Pendant le bake, le plan est figé et les modifications de scène attendent la fin, avec possibilité d'annuler.

Annuler ou interrompre une génération écarte les sorties partielles et préserve le dernier résultat complet. Les changements de caméra, matériau ou paramètres signalent qu'un nouveau bake est nécessaire. En cas de problème de contexte WebGL, le moteur de rendu peut redémarrer et le travail reprendre, avec des messages indiquant ce qui doit être corrigé.

14 · Extension du produit

Une fondation de services indépendante de la capture

L'API ASP.NET Core et PostgreSQL prépare les services futurs. Elle expose les informations de l'application et les contrôles de santé, distingue processus actif et base accessible, et retourne les erreurs sous forme de Problem Details.

L'éditeur et l'application desktop ne dépendent pas de cette API pour importer, rendre ou exporter. Les ressources restent locales ; préférences légères et presets personnalisés sont versionnés séparément. Persistance de scène, bibliothèque de ressources, comptes et stockage cloud exigent des contrats et des livraisons spécifiques avant d'intégrer le produit.

Prochaines étapes

Les acquis et les améliorations souhaitées

La base établie réunit quatre workspaces, composition de modèles, clés par pièce, matériaux éditables, six styles, lumières, feuilles par ressource, export PNG/JSON/ZIP et presets Unity RTS. Windows ajoute dialogues natifs, lecture par intervalles, copies optimisées et cache géré. Chaque capacité préserve les contrats de capture et les fichiers sources.

Les améliorations prévues comprennent projets et recettes persistés, bibliothèque de ressources, retargeting, OBJ, packing avancé et exportateurs propres aux moteurs. L'objectif est de retrouver les réglages de production, réutiliser les ressources et étendre les intégrations tout en gardant temps, caméra et métadonnées prévisibles.

Les autres améliorations comprennent la réduction du travail synchrone de capture, une meilleure utilisation de la mémoire dans les grandes scènes et une compatibilité élargie. WebGPU est une possibilité pour des besoins concrets de compute. Ces pistes sont prévues ; services de stockage et restauration complète de projets nécessitent leur propre implémentation.

Contact

Québec, QC, Canada / Ouvert aux opportunités

Je suis ouvert aux possibilités en développement logiciel, en programmation d'outils et de gameplay, ainsi qu'aux postes d'artiste 3D junior. Si mon expérience peut répondre aux besoins de votre équipe, je serai heureux d'échanger avec vous sur mes réseaux sociaux.