פרטים טכניים
תיעוד חינוכי והיסטורי על אופן הפעולה של המערכת המפעילה את האתר הזה
טרנספורמציות דפוסים
Counter-Strike 2 ו-Counter Strike Global Offensive משתמשים בטקסטורת בסיס אחת (כמו Case Hardened) ליצירת מאות וריאנטים ייחודיים של סקינים באמצעות מערכת של טרנספורמציות אקראיות. זה מושג באמצעות מנגנון דטרמיניסטי מבוסס זרע — מפתח להבנה ושחזור דפוסי Blue Gem מחוץ למשחק.
למה זה נקרא Paint "Seed"?
כדי ליצור מגוון טקסטורות בצורה עקבית אך אקראית, Valve משתמשת במחולל פסאודו-אקראי אחיד המובנה במנוע Source. מכיוון שמחשבים הם מכונות דטרמיניסטיות, הם דורשים ערך התחלתי — זרע — כדי לייצר אקראיות. ב-CS2, כל סקין מקבל paint seed בין 1 ל-999. זרע זה מאתחל את מחולל המספרים האקראיים, שמייצר סט ספציפי של ערכים המשמשים להחלת טרנספורמציות על הטקסטורה.
מכיוון שהאלגוריתם הזה דטרמיניסטי ואחיד בכל הפלטפורמות, paint seed נתון תמיד יניב את אותה טרנספורמציה — מה שמבטיח שהסקין נראה זהה בכל מערכת.
TL;DR: ה-paint seed מאתחל את המחולל הפסאודו-אקראי של Valve כדי להגדיר איך טקסטורת הבסיס ממוקמת, מסובבת ומשונה בקנה מידה עבור שכבות הדפוס, הבלאי והל כלוך.
איך מחושבות טרנספורמציות טקסטורות?
כדי להבין איך CS2 יוצר אקראיות במראה הסקינים, עוזר להבין מיפוי UV: לכל דגם נשק יש פריסת UV שמגדירה איך טקסטורה דו-ממדית נכרכת סביב הרשת התלת-ממדית. Valve מחילה את הטקסטורה על מפת UV זו ואז משתמשת ב-paint seed כדי לבצע אקראיות בתרגום, סיבוב וקנה מידה שלה.
זה משפיע לא רק על הדפוס הראשי (כמו כתמי הצבע של Case Hardened), אלא גם על שכבות הבלאי והלכלוך — טקסטורות שמוסיפות שריטות, הזדקנות ולכלוך.
אם הסגנון של סקין לא משתמש בהזזה אקראית (למשל, אולי סקינים בצבע אחיד כמו Asiimov), הוא לא יושפע מהמערכת הזו.
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)
שלב אחר שלב: Paint Seed → טרנספורמציה
1. קביעת קנה המידה הבסיסי
לכל נשק וסגנון צביעה יש קנה מידה ספציפי, בדרך כלל מוגדר בקובץ items_game.txt של Valve. קנה המידה הבסיסי מחושב מאורך הנשק וקנה מידת UV, בהתאם לסגנון הצביעה:
if (paint_style == 3 || paint_style == 6) {
scale = weapon_length * 0.027777778;
} else {
scale = uv_scale;
}לדוגמה, ל-Karambit יש:
- WeaponLength = 9.813000
- UVScale = 0.438000
- → מה שמביא לקנה מידה בסיסי של 0.438
2. יצירת ערכים אקראיים
ברגע שקנה המידה הבסיסי ידוע, ה-paint seed משמש ליצירת 11 ערכי float פסאודו-אקראיים, שמגדירים איך כל שכבת טקסטורה מוחלת:
| שכבת טקסטורה | פרמטרים |
|---|---|
| דפוס | קנה מידה, הזזהX, הזזהY, סיבוב |
| בלאי | קנה מידה × מכפיל, הזזהX, הזזהY, סיבוב |
| לכלוך | קנה מידה × מכפיל, הזזהX, הזזהY, סיבוב |
ערכי ה-float האלה נוצרים בסדר וטווחים קבועים:
דפוס
- translateX → 0.0 – 1.0
- translateY → 0.0 – 1.0
- rotate → 0.0 – 360.0
בלאי
- scaleMult → 1.6 – 1.8
- translateX → 0.0 – 1.0
- translateY → 0.0 – 1.0
- rotate → 0.0 – 360.0
לכלוך
- 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)דוגמה: Karambit | Case Hardened — Paint Seed 633
בשימוש בלוגיקה למעלה, paint seed 633 על 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
שכבות הבלאי והלכלוך מקבלות ערכים משלהן, גם הם נגזרים מהזרע אבל עם מכפילים וזוויות שונות.
Remaining Mystery: Rotation Center
במשך זמן רב, נותרה שאלה אחת: איפה בדיוק נקודת הסיבוב? בעוד שזוויות <180° נראו מסתובבות סביב הפינה השמאלית העליונה של ה-UV, זוויות גבוהות יותר התנהגו בצורה לא עקבית כשניסו לדמות את התוצאה מחוץ למשחק.
From Reddit to pattern.wiki
הניסיון המוקדם ביותר להנדס לאחור את המערכת הזו הגיע מהפוסט המפורסם ב-Reddit של Step7750 ב-2016. הפוסט הזה הציג את הרעיון הבסיסי של איך טרנספורמציות מבוססות זרע עובדות — ובמשך שנים, הוא שימש כהפניה בפועל עבור הקהילה.
בסופו של דבר, אתרים כמו Broskins ו-csfloat.com בנו מערכות תצוגה מקדימה עובדות — אבל הלוגיקה האמיתית שבה השתמשה Valve נשארה לא מתועדת לציבור.
זה השתנה בתחילת 2024, כאשר pattern.wiki פרסם ניתוח מלא של תהליך הטרנספורמציה — כולל ערכים ספציפיים, מתמטיקה ודוגמאות חזותיות. זו הייתה קפיצה משמעותית קדימה.
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. הזזה ממורכזת
הזז את הדפוס באמצעות ההיסטים של ה-paint seed, אבל מרכז את הטרנספורמציה סביב ראשית ה-UV:
translate(offsetX - 0.5, offsetY - 0.5)2. קנה מידה (סביב הראשית)
שנה קנה מידה אחיד של הדפוס באמצעות קנה המידה הבסיסי — סביב הראשית (0, 0):
scale(scaleX, scaleY)3. סיבוב (סביב הראשית)
סובב את הדפוס נגד כיוון השעון מהראשית:
rotate(rotation)4. היסט נוסף (התאמה סופית)
אחרי סיבוב וקנה מידה, החל היסט סופי שמפצה על הסיבוב המבוסס על פינה:
invScale = 0.5 / scaleangle = -rotationDeg * (π / 180)extraX = invScale * cos(angle) - invScale * sin(angle)extraY = (extraX * sin(angle)) + (invScale * cos(angle))translate(extraX, extraY)רצף מטריצה סופי
במונחים אפיניים, זה יוצר מטריצת טרנספורמציה מלאה:
A = T₂ × R × S × T₁או בעברית פשוטה:
- מרכז היסט UV
- החל קנה מידה
- סובב סביב הראשית
- תקן עם היסט נוסף
ה-UV המותמרים הסופיים נעטפים לאחר מכן באמצעות מודולו:
uv_final = (A × uv_coords) % 1.0כדי להבין טוב יותר את הגישה הזו, אתה יכול לשחק עם סטודיו טרנספורמציית הטקסטורות שלנו שמחיל בדיוק את הטרנספורמציות האלה בזמן אמת בדפדפן שלך.
