Classificação de Shaders na Unity
Na Unity, os shaders são categorizados em diferentes tipos com base em sua aplicação:
- Standard Surface Shader: Template para shaders de superfície com modelo de iluminação padrão.
- Unlit Shader: Shader básico vértice/fragmento sem iluminação integrada.
- Image Effect Shader: Template para efeitos pós-processamento na tela.
- Compute Shader: Utilizado para cálculos paralelos na GPU, fora do pipeline de renderização convencional.
- Ray Tracing Shader: Destinado a efeitos de ray tracing.
O foco principal aqui será nos shaders Unlit, que são fundamentais para aprender a estrutura básica.
Estrutura Geral de um Shader
Um shader na Unity segue uma hierarquia específica. Ao criar um Stadnard Surface Shader, sua estrutura é composta principalmente por seções como nome do shader, propriedades, subshaders e fallback.
Nome do Shader
O nome do shader determina o caminho de acesso pelos materiais e é usado em referências entre shaders.
Seção de Propriedades
Esta seção define atributos externos que podem ser configurados através do inspector do material, permitindo alterações dinâmicas nos dados do shader.
A estrutura de uma propriedade segue o padrão:
// _nomeVariavel ("Nome Exibido", tipo) = valorPadrao [_opcoes]
// _nomeVariavel: Nome interno da variável, geralmente prefixado com underline.
// Nome Exibido: Rótulo visível no painel de materiais.
// tipo: Tipo de dado (número, cor/vetor, textura).
// valorPadrao: Valor inicial atribuído ao material.
Os tipos de propriedades incluem:
Tipos Numéricos
Valores como inteiros, floats e ranges são suportados. Inteiros são convertidos automaticamente para floats.
_contInteiro ("Valor Inteiro", Int) = 0
_contFlutuante ("Valor Flutuante", Float) = 0.0
_contIntervalo ("Valor Intervalo", Range(1,2)) = 1.5
Tipos de Cor e Vetor
Cores (RGBA) e vetores (XYZW) ambos usam quatro componentes.
_corPrincipal ("Cor Principal", Color) = (1,1,1,1) // Valores de 0 a 1
_vetorDirecao ("Vetor Direção", Vector) = (1,1,1,1) // Valores ilimitados
Texturas
Diversos tipos de texturas são suportados, como 2D, arrays de texturas, cubemaps e 3D.
// Exemplo de textura 2D
_texturaDifusa ("Textura Difusa", 2D) = "white" {}
Valores padrão comuns incluem "white" (branco), "black" (preto), "gray" (cinza), "bump" (mapa de normais) e "red" (vermelho).
Seção SubShader
Cada shader pode conter múltiplos subshaedrs para compatibilidade com diferentes hardware. O Unity testa cada subshader sequencialmente até encontrar um que seja suportado.
Um subshader é composto por:
- Tags (Etiquetas): Definem como e quando o objeto é renderizado.
- Estados de Renderização: Controlam aspectos como culling, teste de profundidade e blending.
- Passagens (Pass): Implementações de código que são executadas durente a renderização. Cada passagem renderiza o objeto uma vez; múltiplas passagens podem ser usadas para efeitos avançados, mas devem ser minimizadas para otimizar desempenho.
Tags no SubShader
As tags incluem configurações como fila de renderização, tipo de renderização, e controle de batching e sombras.
Tags {
"Queue" = "Geometry" // Fila para objetos opacos
"RenderType" = "Opaque" // Classifica o shader para substituição
"DisableBatching" = "True" // Desativa batching para preservar espaço do modelo
"ForceNoShadowCasting" = "False" // Permite projeção de sombras
"IgnoreProjector" = "True" // Ignora projetores
}
Estados de Renderização
Esses estados controlam operações como culling, teste de profundidade e blending de cores.
- Culling: Determina quais faces são renderizadas. Exemplo:
Cull Back(padrão),Cull Front,Cull Off. - Teste de Profundidade: Gerencia a relação de oclusão entre objetos. O buffer de profundidade armazena valores de profundidade; pixels são renderizados com base na comparação. Exemplo:
ZWrite On(escreve no buffer),ZTest LEqual(menor ou igual, padrão). - Blending de Cores: Define como as cores são misturadas, útil para efeitos de transparência. Exemplo:
Blend One One(adição linear).
Esses estados podem ser definidos tanto no SubShader quanto em uma Passagem, afetando o escopo respectivo.
Passagem (Pass)
Cada passagem tem uma estrutura que inclui nome, tags, estados de renderização e código do shader.
Pass {
Name "NomeDaPassagem"
Tags { "LightMode" = "ForwardBase" } // Define o estágio de renderização
// Outros estados e código CG/HLSL aqui
}
Passagens podem ser referenciadas em outros shaders usando UsePass. O Unity converte nomes para maiúsculas, portanto referências devem usar letras maiúsculas.
Comandos especiais como GrabPass podem ser usados para capturar o conteúdo da tela em uma textura para uso subsequente.
GrabPass { "_NomeTexturaCapturada" }
Fallback
Se nenhum subshader for suportado, o shader fallback é usado como garantia para que o objeto seja renderizado de alguma forma.
FallBack "NomeShaderFallback"
Esta estrutura fornece a base para o desenvolvimento de shaders na Unity, permitindo a criação de efeitos visuais customizados.