Normal map
Importez un sprite ou choisissez-en un dans la galerie. Nous lisons sa forme 3D pour créer une normal map d'éclairage dynamique.
Générateur de normal maps
Pour sprites 2D et pixel art. Tous les autres générateurs de normal maps devinent la profondeur à partir de la luminosité. Ils passent un filtre de bords sur votre image et espèrent. Celui-ci est un modèle IA entraîné sur de la vraie géométrie 3D. Il lit la forme réelle de votre sprite (un torse bombé, un bras levé, une pomme ronde) et encode la vraie direction de surface dans la map. La silhouette revient au pixel près, et les animations sont traitées frame par frame, sans scintillement.
Comment fonctionne le générateur de normal maps
- Importez un sprite ou choisissez-en un dans votre galerie. Les frames vont de 32 à 256 px par côté.
- Pour une sprite sheet, réglez la grille pour que chaque frame soit lue séparément. Jusqu'à 24 frames par passage.
- Réglez le détail supplémentaire. 0 reste le plus fidèle à la forme 3D, plus haut réinjecte l'ombrage que vous avez dessiné.
- Choisissez le format de votre moteur. OpenGL pour Godot, Unity, Phaser et WebGL, DirectX pour Unreal.
- Générez, passez le curseur sur l'aperçu éclairé pour vérifier, puis téléchargez en <name>_n.png.
Sprite source


Sa normal map, éclairée


Pourquoi les générateurs basés sur la luminosité se trompent
Presque tous les générateurs de normal maps en ligne font la même chose. Ils lisent votre image comme une height map, traitent les pixels clairs comme hauts et les pixels foncés comme bas, puis calculent la pente entre voisins. Sur la photo d'un mur de briques, ça marche, parce que là, la luminosité suit vraiment la profondeur.
Sur un dessin, ça s'écroule. Une ceinture de cuir foncée sur une tunique claire devient une tranchée. Un reflet blanc sur un casque devient une pointe. L'éclairage de contour, que les artistes utilisent sans arrêt pour détacher un personnage du fond, devient une lèvre en relief autour de toute la silhouette. Vous finissez par vous battre contre l'outil. Aplatir votre propre ombrage, peindre des height maps grises à la main, ou accepter un éclairage qui cloche dès que la lumière bouge.
Ce modèle a été entraîné sur des rendus de vrais objets 3D jumelés à leurs vraies normales. Il ne regarde jamais la luminosité pour deviner la hauteur. Il regarde la forme que les pixels représentent. Un torse bombé reste un torse bombé, ombré clair ou foncé, et la ceinture reste plate contre le corps, là où elle doit être.
Voyez le même sprite passé dans tous les générateurs de normal maps sur le blog de Sprite AI (sprite-ai.art), côte à côte avec les résultats éclairés.
Fonctions du générateur de normal maps
- Un modèle IA entraîné sur de la vraie géométrie 3D, pas un filtre de bords appliqué à la luminosité
- Silhouette au pixel près. L'alpha de la map suit votre source 1:1, rien ne déborde du contour
- Sprite sheets et animations traitées frame par frame, jusqu'à 24 frames par passage
- Déterministe. La même frame donne toujours la même map, et les animations ne scintillent jamais
- Aperçu éclairé en direct. Déplacez une lumière sur votre sprite dans le navigateur avant de télécharger
- Canal vert OpenGL ou DirectX, pour Unity, Godot, Unreal, Phaser, GameMaker et WebGL brut
- Fichiers nommés <name>_n.png, la convention que la plupart des moteurs détectent tout seuls
Ajouter la map dans Unity, Godot et Unreal
Tous les moteurs 2D gèrent ça à peu près pareil. Le sprite garde sa texture de couleur, la normal map l'accompagne comme deuxième texture, et une lumière dans la scène fait le reste. La seule vraie différence entre moteurs, c'est le sens du canal vert.
- Godot : déposez la map dans la case Normal Map de la CanvasTexture de votre Sprite2D, puis ajoutez une PointLight2D. Sortie OpenGL par défaut.
- Unity : à l'importation, réglez le Texture Type de la map sur Normal map, assignez-la à un matériau Sprite (Diffuse) ou à un shader URP Lit, et ajoutez une lumière 2D. Sortie OpenGL.
- Unreal : assignez la map à l'entrée Normal de votre matériau et réglez sa compression sur Normalmap. Unreal lit le vert vers le bas, donc cochez DirectX avant de télécharger.
- Phaser, PixiJS et WebGL brut : chargez la map comme deuxième texture nommée <name>_n.png. Le pipeline Light2D de Phaser la détecte tout seul. Sortie OpenGL.
Ce que fait le curseur de détail
Le détail est un réglage d'apparence, pas de qualité. À 0, vous obtenez la lecture honnête de la forme par le modèle, et c'est ce qu'on recommande partout où l'éclairage doit tenir sur un cycle jour-nuit complet.
Montez-le et la map réinjecte le détail fin que vous avez dessiné. Écailles, rivets, plis de tissu, la texture au pixel près que la forme 3D sous-jacente ignore. Mesurée contre de vraies normales, l'erreur grimpe tout du long. Vous échangez la vérité géométrique contre le caractère du dessin à la main. Bon échange sur un accessoire décoratif, mauvais sur un personnage qui traverse un couloir éclairé aux torches. Partez de 0 et montez seulement si le résultat éclairé a l'air trop lisse.
Détail 0


Détail 1,5


Détail 5


Bump map vs normal map
Une bump map est en niveaux de gris et stocke un nombre par pixel, la hauteur de ce point. Une normal map stocke la direction de surface elle-même, trois valeurs par pixel, une par axe. C'est la direction qu'une lumière a besoin de connaître, donc les normal maps rendent plus précisément et à moindre coût. Voilà pourquoi elles ont remplacé le bump mapping presque partout en graphisme temps réel. La plupart des générateurs construisent encore une bump map à l'interne avant de la convertir, avec toutes les erreurs de luminosité qui viennent avec. Celui-ci prédit les normales directement et ne touche jamais à une height map.
Normal maps pour pixel art et sprites 2D
Le pixel art est le cas le plus dur pour un générateur de normal maps, et c'est la raison d'être de ce modèle. Un personnage de 48 px n'a presque aucun dégradé à lire. Les outils basés sur la luminosité ont besoin de rampes douces pour estimer une pente, et le pixel art n'en a pas, exprès. Il a des paliers de couleur nets, du dithering voulu et des contours d'un pixel de large.
Deux choses comptent à cette échelle. La silhouette doit rester exacte, parce qu'à 48 px, un seul pixel qui déborde du contour devient une frange lumineuse dès qu'une lumière s'approche. Et la map doit tenir d'une frame à l'autre, parce qu'un cycle de marche où la normale du torse tremble entre les frames scintille, même si chaque frame est bonne prise seule.
Les deux sont réglés ici. Le canal alpha est copié tel quel de votre source plutôt que recalculé, et le modèle est déterministe. La frame 3 d'un cycle de marche reçoit le même traitement à chaque passage. Les tailles vont de 32 à 256 px par frame, ce qui couvre à peu près tout l'art de jeu 2D. Sous 32 px, il ne reste plus assez de pixels pour qu'un modèle lise une forme.
Autres outils pixel art gratuits
Éditeur de pixel art
Créez et modifiez vos sprites pixel art dans le navigateur. Canevas sur mesure, outils de dessin, export PNG ou SVG.
Créateur de sprite sheets
Déposez vos images et regroupez-les en une sprite sheet. Réglez colonnes, espacement et échelle. Exportez un PNG ou un atlas JSON.
Découpe de sprite sheet
Découpez une sprite sheet en frames. Grille détectée automatiquement. Chaque frame se télécharge en PNG, dans un ZIP.
FAQ
Une texture qui stocke la direction de la surface plutôt que la couleur. Votre moteur de jeu s'en sert pour calculer comment la lumière frappe chaque pixel. Un sprite plat réagit alors aux torches, aux cycles jour-nuit et aux effets de sorts comme s'il avait du relief.
La teinte mauve-bleu, c'est la couleur de « face à la caméra ». Chaque canal stocke un axe de la direction de surface (rouge = X, vert = Y, bleu = Z). Une surface presque plate pointe vers le spectateur, et ça s'encode dans ce bleu lavande familier.
Une bump map (ou height map) est en niveaux de gris et stocke un seul nombre par pixel, la hauteur de ce point. Le moteur doit ensuite en déduire une direction en comparant les voisins. Une normal map stocke la direction elle-même, trois valeurs par pixel, une par axe. C'est plus précis et moins coûteux à rendre, et c'est pourquoi il a remplacé le bump mapping presque partout. La plupart des générateurs construisent encore une bump map avant de la convertir. Celui-ci saute cette étape et prédit les normales directement.
Ça dépend du moteur, et c'est l'erreur la plus fréquente. Les moteurs de style OpenGL (Godot, Unity, Phaser, WebGL) attendent un vert qui pointe vers le haut. Les moteurs de style DirectX (Unreal) l'attendent vers le bas. Choisissez le mauvais et votre éclairage s'inverse. Les reliefs ressemblent à des creux. Réglez-le avant de télécharger et vous n'y penserez plus jamais.
Enregistrez la map à côté de votre sprite sous le nom <name>_n.png, le nommage que la plupart des moteurs détectent tout seuls. Assignez-la comme texture normale (ou bump) dans le matériau du sprite, puis ajoutez une lumière. Godot, Unity et WebGL veulent la sortie OpenGL par défaut. Unreal veut l'option DirectX.
Oui. Réglez la grille et chaque frame est traitée séparément, puis remise dans la même disposition. La map se charge dans votre moteur exactement comme l'animation. Le modèle est déterministe, donc les frames ne scintillent jamais. Jusqu'à 24 frames par passage.
Ce sont des outils à filtre. Ils estiment la profondeur à partir de la luminosité. Une ceinture foncée devient un creux, un contour clair devient une arête, et vous passez votre temps à corriger ça avec des curseurs. Ils sont aussi manuels. Pour un bon résultat, il faut dessiner vous-même les passes de hauteur, d'occlusion et de spéculaire. Ici, un seul modèle entraîné sur de vrais rendus 3D reconstruit la forme que les pixels représentent, en une passe. Un volume reste un volume, peu importe comment vous l'avez ombré.
Sprites, personnages, accessoires, objets, créatures et art 2D dessiné en général, de 32 à 256 px par frame. C'est là qu'un modèle entraîné sur la géométrie devance le plus un filtre de luminosité, parce que dans l'art dessiné, la luminosité ne suit plus la profondeur. Les textures PBR répétables en 1K ou 2K sont un autre travail et sortent de la plage de tailles.
De 32 à 256 px par côté, par frame. C'est la plage sur laquelle le modèle a été entraîné et validé. Pour une sheet, chaque frame doit juste tenir dans la plage. Tout ce qui en sort est refusé avant que le modèle tourne, donc une mauvaise taille ne coûte jamais un jeton.
Il y a un forfait gratuit, donc vous pouvez générer des normal maps sans payer. Les nouveaux comptes reçoivent des jetons gratuits et chaque forfait ajoute une allocation mensuelle. Au-delà, une map coûte un jeton par frame. Un sprite seul, c'est un jeton. Un cycle de marche de 12 frames, c'est douze. Les entrées refusées (mauvaise taille, grille qui ne divise pas également) ne prennent jamais de jeton.