Skip to content

Matérials (.rvmat) ​


Introdução ​

Um matérial no DayZ é a ponte entre um modelo 3D e sua aparência visual. Enquanto texturas fornecem dados brutos de imagem, o arquivo RVMAT (Real Virtuality Matérial) define como essas texturas são combinadas, qual shader as interpreta e quais propriedades de superfície o motor deve simular -- brilho, transparência, auto-iluminacao e mais. Toda face em todo modelo P3D no jogo referência um arquivo RVMAT, e entender como cria-los e configura-los é essencial para qualquer mod visual.

Este capítulo cobre o formato de arquivo RVMAT, tipos de shader, configuração de estágios de textura, propriedades de matérial, o sistema de troca de matérial por nível de dano, e exemplos práticos extraidos dos DayZ-Samples.


Sumário ​


Visao Geral do Formato RVMAT ​

Um arquivo RVMAT e um arquivo de configuração baseado em texto (não binário) que define um matérial. Apesar da extensão customizada, o formato e texto puro usando a sintaxe de configuração estilo Bohemia com classes e pares chave-valor.

Características Principais ​

  • Formato texto: Editavel em qualquer editor de texto (Notepad++, VS Code).
  • Vinculacao de shader: Cada RVMAT específica qual shader de renderizacao usar.
  • Mapeamento de textura: Define quais arquivos de textura são atribuidos a quais entradas do shader (diffuse, normal, specular, etc.).
  • Propriedades de superfície: Controla intensidade specular, brilho emissivo, transparência e mais.
  • Referênciado por modelos P3D: Faces no LOD Resolution do Object Builder recebem um RVMAT. O motor carrega o RVMAT e todas as texturas que ele referência.
  • Referênciado pelo config.cpp: hiddenSelectionsMaterials[] pode sobrescrever matériais em tempo de execução.

Convencao de Caminho ​

Arquivos RVMAT ficam junto com suas texturas, típicamente em um diretório data/:

MyMod/
  data/
    my_item.rvmat              <-- Material definition
    my_item_co.paa             <-- Diffuse texture (referenced by the RVMAT)
    my_item_nohq.paa           <-- Normal map (referenced by the RVMAT)
    my_item_smdi.paa           <-- Specular map (referenced by the RVMAT)

Estrutura do Arquivo ​

Um arquivo RVMAT tem uma estrutura consistente. Aqui esta um exemplo completo e anotado:

cpp
ambient[] = {1.0, 1.0, 1.0, 1.0};        // Ambient color multiplier (RGBA)
diffuse[] = {1.0, 1.0, 1.0, 1.0};        // Diffuse color multiplier (RGBA)
forcedDiffuse[] = {0.0, 0.0, 0.0, 0.0};  // Additive diffuse override
emmisive[] = {0.0, 0.0, 0.0, 0.0};       // Emissive (self-illumination) color
specular[] = {0.7, 0.7, 0.7, 1.0};       // Specular highlight color
specularPower = 80;                        // Specular sharpness (higher = tighter highlight)
PixelShaderID = "Super";                   // Shader program to use
VertexShaderID = "Super";                  // Vertex shader program

class Stage1                               // Texture stage: Normal map
{
    texture = "MyMod\data\my_item_nohq.paa";
    uvSource = "tex";
    class uvTransform
    {
        aside[] = {1.0, 0.0, 0.0};
        up[] = {0.0, 1.0, 0.0};
        dir[] = {0.0, 0.0, 0.0};
        pos[] = {0.0, 0.0, 0.0};
    };
};

class Stage2                               // Texture stage: Detail map (the base _co color comes from the model texture / hiddenSelectionsTextures[], not a Stage)
{
    texture = "MyMod\data\my_item_dt.paa";
    uvSource = "tex";
    class uvTransform
    {
        aside[] = {1.0, 0.0, 0.0};
        up[] = {0.0, 1.0, 0.0};
        dir[] = {0.0, 0.0, 0.0};
        pos[] = {0.0, 0.0, 0.0};
    };
};

class Stage3                               // Texture stage: Specular/Metallic map
{
    texture = "MyMod\data\my_item_smdi.paa";
    uvSource = "tex";
    class uvTransform
    {
        aside[] = {1.0, 0.0, 0.0};
        up[] = {0.0, 1.0, 0.0};
        dir[] = {0.0, 0.0, 0.0};
        pos[] = {0.0, 0.0, 0.0};
    };
};

Propriedades de Nivel Superior ​

Estas são declaradas antes das classes Stage e controlam o comportamento geral do matérial:

PropriedadeTipoDescrição
ambient[]float[4]Multiplicador de cor de luz ambiente. {1,1,1,1} = total, {0,0,0,0} = sem ambiente.
diffuse[]float[4]Multiplicador de cor de luz difusa. Geralmente {1,1,1,1}.
forcedDiffuse[]float[4]Override aditivo de difuso. Geralmente {0,0,0,0}.
emmisive[]float[4]Cor de auto-iluminacao. Valores nao-zero fazem a superfície brilhar. Nota: Bohemia usa a grafia errada emmisive, não emissive.
specular[]float[4]Cor e intensidade do reflexo specular.
specularPowerfloatNitidez dos reflexos speculares. Faixa 1-200. Maior = mais apertado, reflexao mais focada.
PixelShaderIDstringNome do programa de pixel shader.
VertexShaderIDstringNome do programa de vertex shader.

Tipos de Shader ​

Os valores PixelShaderID e VertexShaderID determinam qual pipeline de renderizacao processa o matérial. Ambos geralmente devem ser configurados com o mesmo valor.

Shaders Disponíveis ​

ShaderCaso de UsoEstagios de Textura Necessarios
SuperSuperficies opacas padrão (armas, roupas, itens)Normal, Diffuse, Specular/Metallic
MultiTerreno multicamada e superfícies complexasMultiplos pares diffuse/normal
GlassSuperficies transparentes e semi-transparentesDiffuse com alfa
CalmWaterSuperficies de agua com reflexao e refracaoTexturas especiais de agua
TerrainXSuperficies de solo do terreno (pixel shader; o vertex shader e Terrain)Satélite, mascara, camadas de matérial
NormalMapSuperficie simplificada com normal mapNormal, Diffuse
NormalMapSpecularMapNormal map com specularNormal, Diffuse, Specular
SuperHairRenderizacao de cabelo de personagemDiffuse com alfa, translucencia especial
SkinPele de personagem com espalhamento subsuperficialDiffuse, Normal, Specular
AlphaShadow / AlphaNoShadowTransparencia por alfa (folhagem, cercas) com ou sem projecao de sombraDiffuse com alfa

Shader Super (Mais Comum) ​

O shader Super e o shader padrão de renderizacao baseada em física usado para a grande maioria dos itens no DayZ. Ele espera estes estágios de textura principais (correspondendo a rvmats vanilla reais como DZ\weapons\ammunition\data\00buck_box.rvmat):

Stage1 = Normal map (_nohq)
Stage2 = Detail map (_dt)
Stage3 = Specular/Metallic map (_smdi)

A cor base (_co) não é atribuida atraves de um Stage no shader Super -- ela vem da textura base do modelo ou de hiddenSelectionsTextures[].

Se você esta criando um item de mod (arma, roupa, ferramenta, container), você quase sempre usara o shader Super.

Shader Glass ​

O shader Glass lida com superfícies transparentes. Ele le o alfa da textura diffuse para determinar a transparência:

cpp
PixelShaderID = "Glass";
VertexShaderID = "Glass";

class Stage1
{
    texture = "MyMod\data\glass_nohq.paa";
    uvSource = "tex";
    class uvTransform { /* ... */ };
};

class Stage2
{
    texture = "MyMod\data\glass_ca.paa";    // Note: _ca suffix for color+alpha
    uvSource = "tex";
    class uvTransform { /* ... */ };
};

Estagios de Textura ​

Cada classe Stage no RVMAT atribui uma textura a uma entrada específica do shader. O número do estágio determina qual função a textura desempenha.

Atribuicoes de Estagio para o Shader Super ​

EstagioFunção da TexturaSufixo TípicoDescrição
Stage1Normal map_nohqDetalhe de superfície, relevos, sulcos
Stage2Mapa de detalhe_dtDetalhe fino de superfície (a cor base _co e fornecida pela textura base do modelo / hiddenSelectionsTextures[], não por um Stage)
Stage3Mapa specular / metálico_smdiBrilho, propriedades metálicas, detalhe
Stage4Ambient Shadow_asOclusao ambiental pre-assada (opcional)
Stage5Mapa macro_mcVariacao de cor em larga escala (opcional)
Stage6Mapa de detalhe_deMicro-detalhe com repetição (opcional)
Stage7Mapa emissivo / de luz_liAuto-iluminacao (opcional)

Propriedades do Estagio ​

Cada estágio contem:

cpp
class Stage1
{
    texture = "path\to\texture.paa";    // Path relative to P: drive
    uvSource = "tex";                    // UV source: "tex" (model UVs) or "tex1" (2nd UV set)
    class uvTransform                    // UV transformation matrix
    {
        aside[] = {1.0, 0.0, 0.0};     // U-axis scale and direction
        up[] = {0.0, 1.0, 0.0};        // V-axis scale and direction
        dir[] = {0.0, 0.0, 0.0};       // Not typically used
        pos[] = {0.0, 0.0, 0.0};       // UV offset (translation)
    };
};

UV Transform para Repetição ​

Para repetir uma textura (repeti-la em uma superfície), modifique os valores aside e up:

cpp
class uvTransform
{
    aside[] = {4.0, 0.0, 0.0};     // Tile 4x horizontally
    up[] = {0.0, 4.0, 0.0};        // Tile 4x vertically
    dir[] = {0.0, 0.0, 0.0};
    pos[] = {0.0, 0.0, 0.0};
};

Isso é comumente usado para matériais de terreno e superfícies de edificios onde a mesma textura de detalhe se repete.


Propriedades do Matérial ​

Controle Specular ​

Os valores specular[] e specularPower trabalham juntos para definir quao brilhante uma superfície aparece:

Tipo de Matérialspecular[]specularPowerAparencia
Plastico fosco{0.1, 0.1, 0.1, 1.0}10Opaco, reflexo amplo
Metal desgastado{0.3, 0.3, 0.3, 1.0}40Brilho moderado
Metal polido{0.8, 0.8, 0.8, 1.0}120Reflexo brilhante e apertado
Cromado{1.0, 1.0, 1.0, 1.0}200Reflexao tipo espelho
Borracha{0.02, 0.02, 0.02, 1.0}5Quase sem reflexo
Superficie molhada{0.6, 0.6, 0.6, 1.0}80Liso, reflexo medio-nítido

Emissivo (Auto-Iluminacao) ​

Para fazer uma superfície brilhar (LEDs, telas, elementos luminosos):

cpp
emmisive[] = {0.2, 0.8, 0.2, 1.0};   // Green glow

A cor emissiva e adicionada a cor final do pixel independentemente da iluminacao. Um mapa emissivo _li em um estágio posterior de textura pode mascara quais partes da superfície brilham.

Renderizacao em Dois Lados ​

Para superfícies finas que devem ser visíveis de ambos os lados (bandeiras, folhagem, tecido):

cpp
renderFlags[] = {"NoZWrite"};

renderFlags[] e uma propriedade de nível superior do RVMAT (um irmao de ambient[] e PixelShaderID). Os valores vanilla são em PascalCase, como "NoZWrite", "NoAlphaWrite", "NoColorWrite" e "AddBlend". Não existe uma flag "twoSided" -- a renderizacao em dois lados e controlada em outro lugar (por exemplo nas propriedades de face do Object Builder), não atraves de renderFlags[].


Niveis de Saude (Troca de Matérial por Dano) ​

Itens do DayZ degradam ao longo do tempo. O motor suporta troca automática de matérial em diferentes limiares de dano, definidos no config.cpp usando o array healthLevels[]. Isso cria a progressao visual de pristino até arruinado.

Estrutura do healthLevels[] ​

cpp
class MyItem: Inventory_Base
{
    // ... other config ...

    class DamageSystem
    {
        class GlobalHealth
        {
            class Health
            {
                hitpoints = 100;
                healthLevels[] =
                {
                    // {health_threshold, {"material_set"}},

                    {1.0, {"MyMod\data\my_item.rvmat"}},           // Pristine (100% health)
                    {0.7, {"MyMod\data\my_item_worn.rvmat"}},       // Worn (70% health)
                    {0.5, {"MyMod\data\my_item_damaged.rvmat"}},     // Damaged (50% health)
                    {0.3, {"MyMod\data\my_item_badly_damaged.rvmat"}},// Badly Damaged (30% health)
                    {0.0, {"MyMod\data\my_item_ruined.rvmat"}}       // Ruined (0% health)
                };
            };
        };
    };
};

Como Funciona ​

  1. O motor monitora o valor de saude do item (0.0 a 1.0).
  2. Quando a saude cai abaixo de um limiar, o motor troca o matérial para o RVMAT correspondente.
  3. Cada RVMAT pode referênciar texturas diferentes -- típicamente variantes progressivamente mais danificadas.
  4. A troca é automática. Nenhum código de script é necessário.

Progressao de Textura de Dano ​

Uma progressao típica de dano:

NivelSaudeMudanca Visual
Pristino1.0Aparencia limpa, novo de fabrica
Desgastado0.7Arranhoes leves, desgaste menor
Danificado0.5Arranhoes visíveis, descoloracao, sujeira
Muito Danificado0.3Desgaste pesado, ferrugem, rachaduras, tinta descascando
Arruinado0.0Severamente degradado, aparência quebrada

Criando Matériais de Dano ​

Para cada nível de dano, crie um RVMAT separado que referência texturas progressivamente mais danificadas:

data/
  my_item.rvmat                    --> my_item_co.paa (clean)
  my_item_worn.rvmat               --> my_item_worn_co.paa (light damage)
  my_item_damaged.rvmat            --> my_item_damaged_co.paa (moderate damage)
  my_item_badly_damaged.rvmat      --> my_item_badly_damaged_co.paa (heavy damage)
  my_item_ruined.rvmat             --> my_item_ruined_co.paa (destroyed)

Dica: Você nem sempre precisa de texturas únicas para cada nível de dano. Uma otimizacao comum e compartilhar os normal maps e specular maps entre todos os níveis e mudar apenas a textura diffuse:

my_item.rvmat           --> my_item_co.paa
my_item_worn.rvmat      --> my_item_co.paa  (same diffuse, lower specular)
my_item_damaged.rvmat   --> my_item_damaged_co.paa
my_item_ruined.rvmat    --> my_item_ruined_co.paa

Usando Matériais de Dano Vanilla ​

Itens vanilla não usam um conjunto de overlays genericos nomeados por nível. Em vez disso, cada nível de saude aponta para um RVMAT específico do item (típicamente <item>.rvmat, <item>_damage.rvmat e <item>_destruct.rvmat), reutilizando o mesmo arquivo entre níveis adjacentes. O único matérial generico em DZ\data\data\ e default_destruct.rvmat (junto com default.rvmat):

cpp
healthLevels[] =
{
    {1.0, {"MyMod\data\my_item.rvmat"}},
    {0.7, {"MyMod\data\my_item.rvmat"}},
    {0.5, {"MyMod\data\my_item_damage.rvmat"}},
    {0.3, {"MyMod\data\my_item_damage.rvmat"}},
    {0.0, {"DZ\data\data\default_destruct.rvmat"}}
};

Como Matériais Referênciam Texturas ​

A conexao entre modelos, matériais e texturas forma uma cadeia:

P3D Model (Object Builder)
  |
  |--> Face assigned to RVMAT
         |
         |--> Stage1.texture = "path\to\normal_nohq.paa"
         |--> Stage2.texture = "path\to\color_co.paa"
         |--> Stage3.texture = "path\to\specular_smdi.paa"

Resolução de Caminho ​

Todos os caminhos de textura em arquivos RVMAT são relativos a raiz da unidade P::

cpp
// Correct: relative to P: drive
texture = "MyMod\data\textures\my_item_co.paa";

// This means: P:\MyMod\data\textures\my_item_co.paa

Quando empacotado em um PBO, o prefixo do caminho deve corresponder ao prefixo do PBO:

PBO prefix: MyMod
Internal path: data\textures\my_item_co.paa
Full reference: MyMod\data\textures\my_item_co.paa

Override de hiddenSelectionsMatérials ​

O config.cpp pode sobrescrever qual matérial e aplicado a uma seleção nomeada em tempo de execução:

cpp
class MyItem_Green: MyItem
{
    hiddenSelections[] = {"camo"};
    hiddenSelectionsTextures[] = {"MyMod\data\my_item_green_co.paa"};
    hiddenSelectionsMaterials[] = {"MyMod\data\my_item_green.rvmat"};
};

Isso permite criar variantes de item (esquemas de cor, padroes de camuflagem) que compartilham o mesmo modelo P3D mas usam matériais diferentes.


Criando um RVMAT do Zero ​

Passo a Passo: Item Opaco Padrão ​

  1. Crie seus arquivos de textura:

    • my_item_co.paa (cor diffuse)
    • my_item_nohq.paa (normal map)
    • my_item_smdi.paa (specular/metallic)
  2. Crie o arquivo RVMAT (texto puro):

cpp
ambient[] = {1.0, 1.0, 1.0, 1.0};
diffuse[] = {1.0, 1.0, 1.0, 1.0};
forcedDiffuse[] = {0.0, 0.0, 0.0, 0.0};
emmisive[] = {0.0, 0.0, 0.0, 0.0};
specular[] = {0.5, 0.5, 0.5, 1.0};
specularPower = 60;
PixelShaderID = "Super";
VertexShaderID = "Super";

class Stage1
{
    texture = "MyMod\data\my_item_nohq.paa";
    uvSource = "tex";
    class uvTransform
    {
        aside[] = {1.0, 0.0, 0.0};
        up[] = {0.0, 1.0, 0.0};
        dir[] = {0.0, 0.0, 0.0};
        pos[] = {0.0, 0.0, 0.0};
    };
};

class Stage2
{
    texture = "MyMod\data\my_item_co.paa";
    uvSource = "tex";
    class uvTransform
    {
        aside[] = {1.0, 0.0, 0.0};
        up[] = {0.0, 1.0, 0.0};
        dir[] = {0.0, 0.0, 0.0};
        pos[] = {0.0, 0.0, 0.0};
    };
};

class Stage3
{
    texture = "MyMod\data\my_item_smdi.paa";
    uvSource = "tex";
    class uvTransform
    {
        aside[] = {1.0, 0.0, 0.0};
        up[] = {0.0, 1.0, 0.0};
        dir[] = {0.0, 0.0, 0.0};
        pos[] = {0.0, 0.0, 0.0};
    };
};
  1. Atribua no Object Builder:

    • Abra seu modelo P3D.
    • Selecione faces no LOD Resolution.
    • Clique direito --> Face Properties.
    • Navegue até seu arquivo RVMAT.
  2. Teste no jogo via file patching ou build de PBO.


Exemplos Reais ​

DayZ-Samples Test_ClothingRetexture ​

Os DayZ-Samples oficiais incluem um exemplo Test_ClothingRetexture que demonstra o fluxo de trabalho padrão de matérial:

cpp
// From DayZ-Samples retexture example
ambient[] = {1.0, 1.0, 1.0, 1.0};
diffuse[] = {1.0, 1.0, 1.0, 1.0};
forcedDiffuse[] = {0.0, 0.0, 0.0, 0.0};
emmisive[] = {0.0, 0.0, 0.0, 0.0};
specular[] = {0.3, 0.3, 0.3, 1.0};
specularPower = 50;
PixelShaderID = "Super";
VertexShaderID = "Super";

class Stage1
{
    texture = "DZ_Samples\Test_ClothingRetexture\data\tshirt_nohq.paa";
    uvSource = "tex";
    class uvTransform
    {
        aside[] = {1.0, 0.0, 0.0};
        up[] = {0.0, 1.0, 0.0};
        dir[] = {0.0, 0.0, 0.0};
        pos[] = {0.0, 0.0, 0.0};
    };
};

class Stage2
{
    texture = "DZ_Samples\Test_ClothingRetexture\data\tshirt_co.paa";
    uvSource = "tex";
    class uvTransform
    {
        aside[] = {1.0, 0.0, 0.0};
        up[] = {0.0, 1.0, 0.0};
        dir[] = {0.0, 0.0, 0.0};
        pos[] = {0.0, 0.0, 0.0};
    };
};

class Stage3
{
    texture = "DZ_Samples\Test_ClothingRetexture\data\tshirt_smdi.paa";
    uvSource = "tex";
    class uvTransform
    {
        aside[] = {1.0, 0.0, 0.0};
        up[] = {0.0, 1.0, 0.0};
        dir[] = {0.0, 0.0, 0.0};
        pos[] = {0.0, 0.0, 0.0};
    };
};

Matérial de Arma Metalica ​

Um cano de arma polido com alta resposta metalica:

cpp
ambient[] = {1.0, 1.0, 1.0, 1.0};
diffuse[] = {1.0, 1.0, 1.0, 1.0};
forcedDiffuse[] = {0.0, 0.0, 0.0, 0.0};
emmisive[] = {0.0, 0.0, 0.0, 0.0};
specular[] = {0.9, 0.9, 0.9, 1.0};        // High specular for metal
specularPower = 150;                        // Tight, focused highlight
PixelShaderID = "Super";
VertexShaderID = "Super";

// ... Stage definitions with weapon textures ...

Matérial Emissivo (Tela Brilhante) ​

Um matérial para a tela de um dispositivo que emite luz:

cpp
ambient[] = {1.0, 1.0, 1.0, 1.0};
diffuse[] = {1.0, 1.0, 1.0, 1.0};
forcedDiffuse[] = {0.0, 0.0, 0.0, 0.0};
emmisive[] = {0.05, 0.3, 0.05, 1.0};      // Soft green glow
specular[] = {0.5, 0.5, 0.5, 1.0};
specularPower = 80;
PixelShaderID = "Super";
VertexShaderID = "Super";

// ... Stage definitions including _li emissive map in Stage7 ...

Erros Comuns ​

1. Ordem de Stage Errada ​

Sintoma: Textura aparece embaralhada, normal map mostra como cor, cor mostra como relevos. Correção: Garanta que Stage1 = normal, Stage2 = detalhe, Stage3 = macro, Stage5 = specular (para o shader Super). A cor base _co vem da textura do modelo / hiddenSelectionsTextures[], não de um Stage. Veja a tabela de Atribuicoes de Estagio acima.

2. Grafia Errada de emmisive ​

Sintoma: Emissivo não funciona. Correção: Bohemia usa emmisive (m duplo, s único). Usar a grafia correta em ingles emissive não funciona. Essa e uma peculiaridade historica conhecida.

3. Incompatibilidade de Caminho de Textura ​

Sintoma: Modelo aparece com matérial cinza padrão ou magenta. Correção: Verifique se os caminhos de textura no RVMAT correspondem exatamente aos locais dos arquivos relativos a unidade P:. Caminhos usam barras invertidas. Confira capitalizacao -- alguns sistemas são case-sensitive.

4. Atribuicao de RVMAT Ausente no P3D ​

Sintoma: Modelo renderiza sem matérial (cinza flat ou shader padrão). Correção: Abra o modelo no Object Builder, selecione faces e atribua o RVMAT via Face Properties.

5. Usando Shader Errado para Itens Transparentes ​

Sintoma: Textura transparente aparece opaca, ou toda a superfície desaparece. Correção: Use o shader Glass, AlphaShadow ou AlphaNoShadow em vez de Super para superfícies transparentes. Use texturas com sufixo _ca com canais alfa adequados.


Boas Práticas ​

  1. Comece a partir de um exemplo funcional. Copie um RVMAT dos DayZ-Samples ou de um item vanilla e modifique. Comecar do zero convida erros de digitacao.

  2. Mantenha matériais e texturas juntos. Armazene o RVMAT no mesmo diretório data/ que suas texturas. Isso torna a relacao obvia e simplifica o gerenciamento de caminhos.

  3. Use o shader Super a menos que tenha um motivo para não usar. Ele lida com 95% dos casos de uso corretamente.

  4. Crie matériais de dano mesmo para itens simples. Jogadores percebem quando itens não degradam visualmente. No mínimo, use os matériais de dano padrão vanilla para os níveis de saude mais baixos.

  5. Teste o specular no jogo, não apenas no Object Builder. A iluminacao do editor e a iluminacao no jogo produzem resultados muito diferentes. O que parece perfeito no Object Builder pode ser muito brilhante ou muito opaco sob a iluminacao dinamica do DayZ.

  6. Documente suas configurações de matérial. Quando encontrar valores de specular/power que funcionam bem para um tipo de superfície, registre-os. Você reutilizara essas configurações em muitos itens.


AnteriorAcimaPróximo
4.2 Modelos 3DParte 4: Formatos de Arquivo & DayZ Tools4.4 Audio

Released under CC BY-SA 4.0 | Code examples under MIT License