IsItABlueGem LogoIsItABlueGem
Entrar

Insights Técnicos

Documentação educacional e histórica sobre como funciona o sistema que alimenta este site

Transformações de Padrões

Counter-Strike 2 e Counter Strike Global Offensive usam uma única textura base (como Case Hardened) para gerar centenas de variantes de skins com aparência única através de um sistema de transformações aleatórias. Isso é alcançado através de um mecanismo determinístico baseado em seed — uma chave para entender e reproduzir padrões Blue Gem fora do jogo.

Por que é chamado de "Seed" de Pintura?

Para gerar variedade de textura de forma consistente mas aleatória, a Valve emprega um gerador uniforme pseudo-aleatório incorporado ao Source Engine. Como os computadores são máquinas determinísticas, eles precisam de um valor inicial — uma seed — para produzir aleatoriedade. No CS2, cada skin recebe uma paint seed variando de 1 a 999. Esta seed inicializa o gerador de números aleatórios, que então produz um conjunto específico de valores usados para aplicar transformações à textura.

Como este algoritmo é determinístico e uniforme em todas as plataformas, uma determinada paint seed sempre produzirá a mesma transformação — garantindo que a skin pareça idêntica em todos os sistemas.

Resumo: A paint seed inicializa o gerador pseudo-aleatório da Valve para definir como a textura base é posicionada, rotacionada e escalada para as camadas de padrão, desgaste e sujeira.

Como as Transformações de Textura são Calculadas?

Para entender como o CS2 randomiza as aparências das skins, ajuda entender o mapeamento UV: cada modelo de arma tem um layout UV que define como uma textura 2D envolve a malha 3D. A Valve aplica a textura a este mapa UV e então usa a paint seed para randomizar sua translação, rotação e escala.

Isso afeta não apenas o padrão principal (como as manchas de cor do Case Hardened), mas também as sobreposições de desgaste e sujeira — texturas que adicionam arranhões, envelhecimento e sujeira.

Se o estilo de uma skin não usa deslocamento aleatório (por exemplo, possivelmente skins de cor sólida como Asiimov), ela não será afetada por este sistema.

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

Passo a Passo: Paint Seed → Transformação

1. Determinar Escala Base

Cada arma e estilo de pintura tem uma escala específica, geralmente definida no items_game.txt da Valve. A escala base é calculada a partir do comprimento da arma e da escala UV, dependendo do estilo de pintura:

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

Por exemplo, o Karambit tem:

  • WeaponLength = 9.813000
  • UVScale = 0.438000
  • → resultando em uma escala base de 0.438

2. Gerar Valores Aleatórios

Uma vez que a escala base é conhecida, a paint seed é usada para gerar 11 valores float pseudo-aleatórios, que definem como cada camada de textura é aplicada:

Camada de TexturaParâmetros
Padrãoescala, translaçãoX, translaçãoY, rotação
Desgasteescala × multiplicador, translaçãoX, translaçãoY, rotação
Sujeiraescala × multiplicador, translaçãoX, translaçãoY, rotação

Esses floats são gerados em ordem e intervalos fixos:

Padrão
  • translateX → 0.0 – 1.0
  • translateY → 0.0 – 1.0
  • rotate → 0.0 – 360.0
Desgaste
  • scaleMult → 1.6 – 1.8
  • translateX → 0.0 – 1.0
  • translateY → 0.0 – 1.0
  • rotate → 0.0 – 360.0
Sujeira
  • 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)

Exemplo: Karambit | Case Hardened — Paint Seed 633

Usando a lógica acima, paint seed 633 em um Karambit produz:

  • 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

As camadas de desgaste e sujeira obtêm seus próprios valores, também derivados da seed mas com diferentes multiplicadores e ângulos.

Remaining Mystery: Rotation Center

Por muito tempo, uma questão permaneceu: onde exatamente está o pivô de rotação? Enquanto ângulos <180° pareciam girar em torno do canto superior esquerdo do UV, ângulos maiores se comportavam inconsistentemente ao tentar simular o resultado fora do jogo.

From Reddit to pattern.wiki

A primeira tentativa de engenharia reversa deste sistema veio do famoso post no Reddit de Step7750 em 2016. Esse post estabeleceu a ideia básica de como as transformações baseadas em seed funcionam — e por anos, serviu como a referência de facto para a comunidade.

Eventualmente, sites como Broskins e csfloat.com construíram sistemas de visualização funcionais — mas a lógica real usada pela Valve permaneceu não documentada para o público.

Isso mudou no início de 2024, quando pattern.wiki publicou uma análise completa do processo de transformação — incluindo valores específicos, matemática e exemplos visuais. Foi um grande avanço.

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. Translação Centralizada

Deslocar o padrão usando os deslocamentos da paint seed, mas centralizar a transformação em torno da origem UV:

translate(offsetX - 0.5, offsetY - 0.5)
2. Escala (em torno da origem)

Escalar uniformemente o padrão usando a escala base — em torno da origem (0, 0):

scale(scaleX, scaleY)
3. Rotação (em torno da origem)

Girar o padrão no sentido anti-horário a partir da origem:

rotate(rotation)
4. Deslocamento Extra (ajuste final)

Após rotação e escala, aplicar um deslocamento final que compensa a rotação baseada em canto:

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

Sequência Final de Matriz

Em termos afins, isso cria uma matriz de transformação completa:

A = T₂ × R × S × T₁

Ou em português simples:

  1. Centralizar deslocamento UV
  2. Aplicar escala
  3. Girar em torno da origem
  4. Corrigir com deslocamento extra

Os UVs transformados finais são então envolvidos usando módulo:

uv_final = (A × uv_coords) % 1.0

Para entender melhor esta abordagem, você pode experimentar nosso estúdio de transformação de textura que aplica exatamente essas transformações ao vivo em seu próprio navegador.

© 2025 isitabluegem. Todos os direitos reservados.

Não afiliado à Valve Corporation. Skins CS2 e conteúdo relacionado são propriedade da Valve Corporation.