Détails Techniques
Documentation éducative et historique sur le fonctionnement du systÚme qui alimente ce site
Transformations de Motifs
Counter-Strike 2 et Counter Strike Global Offensive utilisent une seule texture de base (comme Case Hardened) pour gĂ©nĂ©rer des centaines de variantes de skins d'apparence unique grĂące Ă un systĂšme de transformations alĂ©atoires. Ceci est rĂ©alisĂ© via un mĂ©canisme dĂ©terministe basĂ© sur une graine â une clĂ© pour comprendre et reproduire les motifs Blue Gem en dehors du jeu.
Pourquoi l'appelle-t-on Paint "Seed" ?
Pour gĂ©nĂ©rer une variĂ©tĂ© de textures de maniĂšre cohĂ©rente mais alĂ©atoire, Valve utilise un gĂ©nĂ©rateur uniforme pseudo-alĂ©atoire intĂ©grĂ© au moteur Source. Comme les ordinateurs sont des machines dĂ©terministes, ils nĂ©cessitent une valeur initiale â une graine â pour produire du hasard. Dans CS2, chaque skin se voit attribuer un paint seed allant de 1 Ă 999. Cette graine initialise le gĂ©nĂ©rateur de nombres alĂ©atoires, qui produit ensuite un ensemble spĂ©cifique de valeurs utilisĂ©es pour appliquer des transformations Ă la texture.
Parce que cet algorithme est dĂ©terministe et uniforme sur toutes les plateformes, un paint seed donnĂ© produira toujours la mĂȘme transformation â garantissant que le skin a l'air identique sur chaque systĂšme.
TL;DR : Le paint seed initialise le générateur pseudo-aléatoire de Valve pour définir comment la texture de base est positionnée, tournée et mise à l'échelle pour les couches de motif, d'usure et de saleté.
Comment sont calculées les transformations de textures ?
Pour comprendre comment CS2 randomise l'apparence des skins, il est utile de comprendre le mapping UV : chaque modÚle d'arme a une disposition UV qui définit comment une texture 2D s'enroule autour du maillage 3D. Valve applique la texture à cette carte UV, puis utilise le paint seed pour randomiser sa translation, rotation et échelle.
Cela affecte non seulement le motif principal (comme les taches de couleur Case Hardened), mais aussi les superpositions d'usure et de saletĂ© â des textures qui ajoutent des rayures, du vieillissement et de la crasse.
Si le style d'un skin n'utilise pas de déplacement aléatoire (par exemple, possiblement des skins de couleur unie comme Asiimov), il ne sera pas affecté par ce systÚme.
UV Mapping Concept
Hover over the cube faces or UV map to see how 3D surfaces map to 2D texture coordinates
3D Model
UV Map (Unfolded)
Ătape par Ă©tape : Paint Seed â Transformation
1. Déterminer l'échelle de base
Chaque arme et style de peinture a une échelle spécifique, généralement définie dans le fichier items_game.txt de Valve. L'échelle de base est calculée à partir de la longueur de l'arme et de l'échelle UV, selon le style de peinture :
if (paint_style == 3 || paint_style == 6) {
    scale = weapon_length * 0.027777778;
} else {
    scale = uv_scale;
}Par exemple, le Karambit a :
- WeaponLength = 9.813000
- UVScale = 0.438000
- â rĂ©sultant en une Ă©chelle de base de 0.438
2. Générer des valeurs aléatoires
Une fois l'échelle de base connue, le paint seed est utilisé pour générer 11 valeurs float pseudo-aléatoires, qui définissent comment chaque couche de texture est appliquée :
| Couche de texture | ParamĂštres |
|---|---|
| Motif | échelle, translationX, translationY, rotation |
| Usure | échelle à multiplicateur, translationX, translationY, rotation |
| Saleté | échelle à multiplicateur, translationX, translationY, rotation |
Ces floats sont générés dans un ordre et des plages fixes :
Motif
- translateX â 0.0 â 1.0
- translateY â 0.0 â 1.0
- rotate â 0.0 â 360.0
Usure
- scaleMult â 1.6 â 1.8
- translateX â 0.0 â 1.0
- translateY â 0.0 â 1.0
- rotate â 0.0 â 360.0
Saleté
- scaleMult â 1.6 â 1.8
- translateX â 0.0 â 1.0
- translateY â 0.0 â 1.0
- rotate â 0.0 â 360.0
These values are applied independently to each layer using the following logic:
Transform Order: Scale â Translate â Rotate(Repeated for pattern, wear, and grunge)Exemple : Karambit | Case Hardened â Paint Seed 633
En utilisant la logique ci-dessus, le paint seed 633 sur un Karambit donne :
- Base Scale: 0.438
- Translate X: 0.471 â shifts the pattern ~47% left
- Translate Y: 0.624 â shifts the pattern ~62% up
- Rotation: 96.7° counterclockwise
Les couches d'usure et de saleté obtiennent leurs propres valeurs, également dérivées de la graine mais avec des multiplicateurs et angles différents.
Remaining Mystery: Rotation Center
Pendant longtemps, une question est restĂ©e : oĂč exactement se trouve le pivot de rotation ? Alors que les angles <180° semblaient tourner autour du coin supĂ©rieur gauche de l'UV, les angles plus Ă©levĂ©s se comportaient de maniĂšre incohĂ©rente lors des tentatives de simulation du rĂ©sultat en dehors du jeu.
From Reddit to pattern.wiki
La premiĂšre tentative de rĂ©tro-ingĂ©nierie de ce systĂšme est venue du cĂ©lĂšbre post Reddit de Step7750 en 2016. Ce post a exposĂ© l'idĂ©e de base du fonctionnement des transformations basĂ©es sur la graine â et pendant des annĂ©es, il a servi de rĂ©fĂ©rence de facto pour la communautĂ©.
Finalement, des sites comme Broskins et csfloat.com ont construit des systĂšmes de prĂ©visualisation fonctionnels â mais la logique rĂ©elle utilisĂ©e par Valve restait non documentĂ©e pour le public.
Cela a changĂ© dĂ©but 2024, quand pattern.wiki a publiĂ© une analyse complĂšte du processus de transformation â incluant des valeurs spĂ©cifiques, des mathĂ©matiques et des exemples visuels. C'Ă©tait un bond en avant majeur.
What We Clarified
While pattern.wiki's implementation clearly works in practice, their description of the transform order and rotation pivot didn't fully align with how Source behaves under the hood. Through testing and debugging, we clarified a few subtle (but important) points:
- All transforms are applied around the origin (0, 0) â not after translation
- The effective matrix order is: Tâ Ă R Ă S Ă Tâ
Template Transform Application (Finalized Model)
To sample the correct area of the texture using a paint seed, we apply a sequence of affine transformations â each one modifying the UV coordinates before sampling the base texture.
Step-by-Step Transform Chain
1. Translation centrée
Décaler le motif en utilisant les décalages du paint seed, mais centrer la transformation autour de l'origine UV :
translate(offsetX - 0.5, offsetY - 0.5)2. Ăchelle (autour de l'origine)
Mettre Ă l'Ă©chelle uniformĂ©ment le motif en utilisant l'Ă©chelle de base â autour de l'origine (0, 0) :
scale(scaleX, scaleY)3. Rotation (autour de l'origine)
Faire tourner le motif dans le sens antihoraire depuis l'origine :
rotate(rotation)4. Décalage supplémentaire (ajustement final)
AprÚs rotation et échelle, appliquer un décalage final qui compense la rotation basée sur le coin :
invScale = 0.5 / scaleangle = -rotationDeg * (Ï / 180)extraX = invScale * cos(angle) - invScale * sin(angle)extraY = (extraX * sin(angle)) + (invScale * cos(angle))translate(extraX, extraY)SĂ©quence de matrice finale
En termes affines, cela crée une matrice de transformation complÚte :
A = Tâ Ă R Ă S Ă TâOu en langage simple :
- Centrer le décalage UV
- Appliquer l'échelle
- Tourner autour de l'origine
- Corriger avec un décalage supplémentaire
Les UV finaux transformés sont ensuite enveloppés en utilisant modulo :
uv_final = (A Ă uv_coords) % 1.0Pour mieux comprendre cette approche, vous pouvez jouer avec notre studio de transformation de textures qui applique exactement ces transformations en direct dans votre propre navigateur.
