IsItABlueGem LogoIsItABlueGem
Logga in

Tekniska Detaljer

Utbildnings- och historisk dokumentation om hur systemet som driver denna webbplats fungerar

Mönstertransformationer

Counter-Strike 2 och Counter Strike Global Offensive använder en enda bastextur (som Case Hardened) för att generera hundratals unikt utseende skin-varianter genom ett system av randomiserade transformationer. Detta uppnås via en deterministisk, frö-baserad mekanism — en nyckel till att förstå och reproducera Blue Gem-mönster utanför spelet.

Varför kallas det ett Paint "Seed"?

För att generera texturvariation på ett konsekvent men randomiserat sätt använder Valve en pseudo-slumpmässig enhetlig generator inbyggd i Source Engine. Eftersom datorer är deterministiska maskiner kräver de ett initialt värde — ett frö — för att producera slumpmässighet. I CS2 tilldelas varje skin ett paint seed från 1 till 999. Detta frö initialiserar slumptalsgeneratorn, som sedan producerar en specifik uppsättning värden som används för att tillämpa transformationer på texturen.

Eftersom denna algoritm är deterministisk och enhetlig över alla plattformar kommer ett givet paint seed alltid att ge samma transformation — vilket säkerställer att skinnet ser identiskt ut på varje system.

TL;DR: Paint seed initialiserar Valves pseudo-slumpmässiga generator för att definiera hur bastexturen positioneras, roteras och skalas för mönster-, slitage- och smutslagren.

Hur beräknas texturtransformationer?

För att förstå hur CS2 randomiserar skin-utseenden hjälper det att förstå UV-mappning: varje vapenmodell har en UV-layout som definierar hur en 2D-textur wrappas runt 3D-meshen. Valve tillämpar texturen på denna UV-karta och använder sedan paint seed för att randomisera dess translation, rotation och skala.

Detta påverkar inte bara huvudmönstret (som Case Hardened färgfläckar), utan också slitage- och smutsöverläggen — texturer som lägger till repor, åldrande och smuts.

Om en skins stil inte använder slumpmässig förskjutning (t.ex. möjligen enfärgade skins som Asiimov), kommer den inte att påverkas av detta system.

UV Mapping Concept

Hover over the cube faces or UV map to see how 3D surfaces map to 2D texture coordinates

3D Model

1
2
3
4
5
6

UV Map (Unfolded)

5
4
1
3
6
2

Steg-för-steg: Paint Seed → Transformation

1. Bestäm basskala

Varje vapen och målningsstil har en specifik skala, vanligtvis definierad i Valves items_game.txt. Basskalan beräknas från vapenlängden och UV-skalan, beroende på målningsstilen:

if (paint_style == 3 || paint_style == 6) {
    scale = weapon_length * 0.027777778;
} else {
    scale = uv_scale;
}

Till exempel har Karambit:

  • WeaponLength = 9.813000
  • UVScale = 0.438000
  • → vilket resulterar i en basskala på 0.438

2. Generera slumpmässiga värden

När basskalan är känd används paint seed för att generera 11 pseudo-slumpmässiga float-värden, som definierar hur varje texturlager tillämpas:

TexturlagerParametrar
Mönsterskala, translateX, translateY, rotation
Slitageskala × multiplikator, translateX, translateY, rotation
Smutsskala × multiplikator, translateX, translateY, rotation

Dessa floats genereras i fast ordning och intervall:

Mönster
  • translateX → 0.0 – 1.0
  • translateY → 0.0 – 1.0
  • rotate → 0.0 – 360.0
Slitage
  • scaleMult → 1.6 – 1.8
  • translateX → 0.0 – 1.0
  • translateY → 0.0 – 1.0
  • rotate → 0.0 – 360.0
Smuts
  • 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)

Exempel: Karambit | Case Hardened — Paint Seed 633

Med ovanstående logik ger paint seed 633 på en Karambit:

  • 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

Slitage- och smutslagren får sina egna värden, också härledda från fröet men med olika multiplikatorer och vinklar.

Remaining Mystery: Rotation Center

Under lång tid kvarstod en fråga: var exakt är rotationspunkten? Medan <180° vinklar verkade rotera runt UV:ns övre vänstra hörn, betedde sig högre vinklar inkonsekvent när man försökte simulera resultatet utanför spelet.

From Reddit to pattern.wiki

Det tidigaste försöket att bakåtkonstruera detta system kom från det berömda Reddit-inlägget av Step7750 tillbaka 2016. Det inlägget lade ut grundidén om hur frö-baserade transformationer fungerar — och i åratal fungerade det som de facto-referens för communityn.

Till slut byggde sajter som Broskins och csfloat.com fungerande förhandsgranskningssystem — men den faktiska logiken som Valve använde förblev odokumenterad för allmänheten.

Det ändrades i början av 2024, när pattern.wiki publicerade en fullständig nedbrytning av transformationsprocessen — inklusive specifika värden, matematik och visuella exempel. Det var ett stort steg framåt.

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. Centrerad translation

Förskjut mönstret med paint seedets offsets, men centrera transformationen runt UV-origo:

translate(offsetX - 0.5, offsetY - 0.5)
2. Skala (runt origo)

Enhetligt skala mönstret med basskalan — runt origo (0, 0):

scale(scaleX, scaleY)
3. Rotation (runt origo)

Rotera mönstret moturs från origo:

rotate(rotation)
4. Extra offset (slutlig justering)

Efter rotation och skala, tillämpa en slutlig offset som kompenserar för den hörnbaserade rotationen:

invScale = 0.5 / scale
angle = -rotationDeg * (π / 180)
extraX = invScale * cos(angle) - invScale * sin(angle)
extraY = (extraX * sin(angle)) + (invScale * cos(angle))
translate(extraX, extraY)

Slutlig matrissekvens

I affina termer skapar detta en fullständig transformationsmatris:

A = T₂ × R × S × T₁

Eller på ren svenska:

  1. Centrera UV-offset
  2. Tillämpa skala
  3. Rotera runt origo
  4. Korrigera med extra offset

De slutliga transformerade UV:erna wrappas sedan med modulo:

uv_final = (A × uv_coords) % 1.0

För att bättre förstå detta tillvägagångssätt kan du leka med vår texturtransformationsstudio som tillämpar exakt dessa transformationer live i din egen webbläsare.

© 2025 isitabluegem. Non-commercial CS2 pattern analysis tool.

Not affiliated with Valve Corporation. CS2 skins and related content are property of Valve Corporation.