Documentation → Étape 2

Étape 2 — Isoler un layer

Comment récupérer une texture seule, sans le corps, sans les autres vêtements, et sans avoir à soustraire quoi que ce soit.

L'idée de départ, et pourquoi elle était déjà bonne

L'intuition était : « on part d'un skin transparent, on ne met que le vêtement qui nous intéresse, en gris ou blanc, et on télécharge tout comme ça ». Puis, pour les motifs superposés : « on prend le t-shirt avec motif, on soustrait le t-shirt sans motif, et il reste le motif seul ».

La première moitié est exactement la bonne approche. La seconde s'avère inutile — pour deux raisons distinctes, l'une plus satisfaisante que l'autre.

1. La base none renvoie un canevas vide

Le groupe base_textures contient 18 entrées, dont deux qui sautent aux yeux : none et transparent. Test des deux, sans aucun vêtement :

RequêtePoidsPixels opaquesVerdict
/create-skin/none/white/wide/? 114 o 0 totalement vide
/create-skin/transparent/white/wide/? 457 o 134 pas vide du tout
Conséquence

Avec base_texture=none, tout ce qui apparaît dans le PNG appartient exclusivement au layer demandé. L'isolation est parfaite dès la requête : aucune soustraction n'est nécessaire.

2. Le piège de la base transparent

Contrairement à ce que son nom laisse croire, transparent n'est pas un canevas vide : elle dépose 134 pixels, dont 64 en semi-transparence. La plupart ont un canal alpha de 3 sur 255 — invisibles à l'œil, mais bien présents dans les données.

Base transparent, rendu normal
Tel quel : on ne voit à peu près rien.
Base transparent, alpha amplifié
Le même PNG, alpha forcé à 255 : une signature apparaît.

Les teintes dominantes sont violettes (#5500aa, #4d0a81, #650f96) — les couleurs de Lunar Eclipse Studios. Il s'agit très vraisemblablement d'une signature de paternité.

À retenir

Pour un archivage propre, il faut utiliser none et surtout pas transparent. Un choix de base fait à l'intuition sur le seul nom aurait contaminé les 272 textures avec 134 pixels parasites.

3. Les motifs : déjà des layers à part entière

C'est ici que la soustraction devient inutile. Le manifest distingue deux groupes séparés : top_textures (le vêtement) et top_designs_textures (le motif imprimé dessus), chacun avec son propre paramètre de couleur.

Un motif peut donc être demandé sans vêtement en dessous :

/create-skin/none/white/wide/?top_texture=none
    &top_designs_texture=cake&top_designs_color=%24ffffff
T-shirt seul
T-shirt seul — 468 px
Motif seul
Motif seul — 44 px
Les deux
Les deux ensemble — 468 px

Vérification de la composition, pixel à pixel :

pixels du motif        : 44
pixels t-shirt seul    : 424
pixels du t-shirt qui diffèrent entre les deux rendus : 0
Composition confirmée

Le motif remplace simplement les pixels du t-shirt, sans transparence partielle ni fusion. En dehors de son emprise, le t-shirt est identique au bit près. La superposition est un empilement opaque classique — donc reproductible localement sans aucune ambiguïté.

4. Séparer les deux zones colorisables

70 cosmétiques sur 272 portent uses_secondary_color: true. Pour distinguer la zone primaire de la secondaire, on exploite l'orthogonalité des canaux RVB : on demande la zone primaire en rouge pur et la secondaire en bleu pur.

top_texture=chef_shirt
  &top_color=%24ff0000            → zone primaire   (R seul)
  &top_color_secondary=%240000ff  → zone secondaire (B seul)
Carte des zones du chef_shirt
primaire 778 px · secondaire 42 px · ni l'un ni l'autre 10 px

5. Une erreur qu'il a fallu corriger

Premier essai de classification : je faisais varier seulement la couleur primaire et je déclarais « fixe » tout pixel qui ne bougeait pas. Résultat apparent :

LayerPrétendus « fixes »Couleurs
bottom/jeans7#050505#181818
headwear/cap26#591390, #68199d

Ces couleurs n'étaient pas arbitraires. definedOptions précise bottom_color_secondary: "black" et headwear_color_secondary: "purple". Je ne mesurais pas des pixels fixes : je mesurais la zone secondaire laissée à sa valeur par défaut.

Leçon de méthode

Un paramètre qu'on ne fait pas varier n'est pas un paramètre absent. Il fallait trois rendus — les deux couleurs à une valeur de référence, puis chacune modifiée à tour de rôle — pour attribuer chaque pixel à sa zone sans ambiguïté.

6. Les pixels réellement fixes existent

Avec la méthode corrigée, la catégorie « fixe » se vide presque partout — mais pas totalement :

LayerPrimaireSecondaireFixes
top/basic46080
top/chef_shirt7784210
bottom/jeans40080
headwear/cap170280

Le chef_shirt conserve 10 pixels immuables, en deux teintes (#576368 et #3f4e54, 5 pixels chacune) : un détail que l'auteur a délibérément soustrait à la recolorisation. Un moteur local doit les recopier tels quels.

Détail inattendu

Le top/basic déclare uses_secondary_color: false et possède pourtant 8 pixels réagissant à la couleur secondaire. Ces 8 pixels se retrouvent dans tous les layers testés — leur nature est élucidée à l'étape 3.

Recette finale d'isolation

https://starlightskins.lunareclipse.studio/create-skin/none/white/wide/
  ?<groupe>_texture=<nom>
  &<groupe>_color=%24800000            (rouge : marque la zone primaire)
  &<groupe>_color_secondary=%24000080  (bleu : marque la zone secondaire)

Deux rendus par variante suffisent à décomposer complètement un layer : le premier avec ce couple rouge/bleu, le second avec un couple vert/rouge. Un pixel primaire est rouge puis vert ; un pixel secondaire est bleu puis rouge ; un pixel fixe est identique dans les deux.

Les valeurs sont volontairement à 128 et non à 255 : au-delà, le slot le plus clair (×1,348) dépasse 255 et se retrouve écrêté, ce qui détruit l'information. C'est le sujet de l'étape suivante.