Технические Подробности
Образовательная и историческая документация о том, как работает система, поддерживающая этот сайт
Трансформации Паттернов
Counter-Strike 2 и Counter Strike Global Offensive используют одну базовую текстуру (например, Case Hardened) для генерации сотен уникально выглядящих вариантов скинов через систему случайных трансформаций. Это достигается с помощью детерминированного механизма на основе сида — ключа к пониманию и воспроизведению паттернов синих самоцветов вне игры.
Почему это называется "Сид" раскраски?
Чтобы генерировать разнообразие текстур последовательным, но случайным образом, Valve использует псевдослучайный равномерный генератор, встроенный в движок Source. Поскольку компьютеры — детерминированные машины, им требуется начальное значение — сид — для создания случайности. В CS2 каждому скину назначается сид раскраски от 1 до 999. Этот сид инициализирует генератор случайных чисел, который затем производит определенный набор значений, используемых для применения трансформаций к текстуре.
Поскольку этот алгоритм детерминирован и единообразен на всех платформах, данный сид раскраски всегда будет давать одну и ту же трансформацию — гарантируя, что скин выглядит одинаково на каждой системе.
Кратко: Сид раскраски инициализирует псевдослучайный генератор Valve для определения того, как базовая текстура позиционируется, поворачивается и масштабируется для слоев паттерна, износа и грязи.
Как вычисляются трансформации текстур?
Чтобы понять, как CS2 рандомизирует внешний вид скинов, полезно понимать UV-маппинг: каждая модель оружия имеет UV-развертку, которая определяет, как 2D-текстура оборачивается вокруг 3D-меша. Valve применяет текстуру к этой UV-карте, а затем использует сид раскраски для рандомизации ее перемещения, по ворота и масштаба.
Это влияет не только на основной паттерн (например, цветовые пятна 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)
Пошагово: Сид раскраски → Трансформация
1. Определение базового масштаба
Каждое оружие и стиль раскраски имеют определенный масштаб, обычно определенный в файле items_game.txt от Valve. Базовый масштаб вычисляется из длины оружия и UV-масштаба, в зависимости от стиля раскраски:
if (paint_style == 3 || paint_style == 6) {
scale = weapon_length * 0.027777778;
} else {
scale = uv_scale;
}Например, у Керамбита:
- WeaponLength = 9.813000
- UVScale = 0.438000
- → результирующий базовый масштаб 0.438
2. Генерация случайных значений
Когда базовый масштаб известен, сид раскраски используется для генерации 11 псевдослучайных значений с плавающей точкой, которые определяют, как применяется каждый слой текстуры:
| Слой текстуры | Параметры |
|---|---|
| Паттерн | масштаб, смещениеX, смещениеY, поворот |
| Износ | масштаб × множитель, смещениеX, смещениеY, поворот |
| Грязь | масштаб × множитель, смещениеX, смещениеY, поворот |
Эти числа генерируются в фиксированном порядке и диапазонах:
Паттерн
- 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)Пример: Керамбит | Case Hardened — Сид раскраски 633
Используя вышеописанную логику, сид раскраски 633 на Керамбите дает:
- 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. Центрированное смещение
Сдвиг паттерна с использованием смещений сида раскраски, но центрирование трансформации вокруг 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Чтобы лучше понять этот подход, вы можете поиграть с нашей студией трансформации текстур, которая применяет именно эти трансформации вживую в вашем браузере.
