Fragment Shader é um estágio programável do pipeline gráfico que determina a cor final de cada fragmento (pixel) de uma imagem. De acordo com Khronos Group, 2025, o shader de fragmentos recebe dados interpolados do Vertex Shader e realiza cálculos de iluminação, texturização e efeitos de cor. Fragment Shader é invocado para cada pixel, tornando-o o estágio mais intensivo em recursos do pipeline gráfico.
Principais pontos
Fragment Shader (shader de fragmentos ou pixels) é um estágio programável do pipeline gráfico que calcula a cor final de cada fragmento da imagem. Um fragmento é um pixel potencial que se torna um pixel visível na tela após passar pelos testes de profundidade e stencil.
O Fragment Shader é executado após a rasterização, quando os primitivos 3D (triângulos) já foram convertidos em um conjunto de fragmentos. O shader recebe atributos interpolados — coordenadas de textura, normais, cores que foram calculadas no Vertex Shader para os vértices do triângulo e interpoladas linearmente para cada pixel dentro do triângulo.
Antes do advento dos shaders programáveis (antes do DirectX 8 / OpenGL 2.0), o cálculo da cor dos pixels era realizado por um pipeline fixo com um conjunto limitado de operações. O Fragment Shader programável surgiu em 2001 e expandiu radicalmente as capacidades gráficas: os desenvolvedores obtiveram controle total sobre a cor de cada pixel, permitindo implementar iluminação fotorrealista, materiais complexos e pós-efeitos.
Fragment Shader é lançado pela GPU para cada fragmento gerado pelo rasterizador. Cada invocação do shader processa um fragmento, lê seus dados de entrada, executa código do usuário e escreve o valor de saída — a cor do fragmento no formato RGBA.
Os dados de entrada do Fragment Shader incluem atributos interpolados do Vertex Shader (coordenadas de textura, normais, cores), variáveis uniform (fontes de luz, matrizes) e samplers de textura. Os dados de saída são o vetor de cor (gl_FragColor no OpenGL ES 2.0 ou uma variável definida pelo usuário no ES 3.0), que é escrito no buffer de cor.
#version 300 es
precision mediump float;
in vec2 vTexCoord;
uniform sampler2D uTexture;
out vec4 fragColor;
void main() {
fragColor = texture(uTexture, vTexCoord);
}
Fragment Shader é responsável pela qualidade visual da imagem. Todos os efeitos que o usuário vê na tela — cor, sombras, reflexos, transparência — são calculados neste estágio do pipeline gráfico.
A operação mais frequente é amostrar a cor de uma textura usando coordenadas UV interpoladas. Sampler2D e a função texture() permitem obter a cor de um pixel de um atlas de texturas. A filtragem (bilinear, trilinear, anisotrópica) é controlada através de parâmetros do sampler e afeta a nitidez da imagem em diferentes ângulos de visão.
O modelo de iluminação Phong é calculado no Fragment Shader por pixel, proporcionando realces mais suaves do que a iluminação por vértices (sombreado Gouraud). A iluminação Phong inclui três componentes: ambiente, difusa e especular.
// Fragment shader with Phong lighting
in vec3 vNormal;
in vec3 vPosition;
uniform vec3 uLightDir;
uniform vec3 uLightColor;
void main() {
vec3 norm = normalize(vNormal);
float diff = max(dot(norm, uLightDir), 0.0);
fragColor = vec4(uLightColor * diff, 1.0);
}
O Fragment Shader permite aplicar pós-processamento: correção de cor através de tabelas LUT, desfoque (blur), efeito de brilho (bloom) e tonemapping para renderização HDR. Todos esses efeitos funcionam no nível do pixel e são executados em tempo real.
O desempenho do Fragment Shader é o principal fator que limita os FPS em jogos móveis modernos. Como o shader é invocado para cada pixel, mesmo um pequeno aumento na complexidade do código pode levar a uma queda notável na taxa de quadros.
Para GPUs móveis (Qualcomm Adreno, ARM Mali) recomenda-se: usar mediump precision para variáveis float, combinar amostragens de textura, aplicar testes early-z para descartar fragmentos invisíveis antes da execução do shader.
| Método | Descrição | Ganho |
|---|---|---|
| Mediump precision | Precisão de 16 bits em vez de 32 bits | Até 2x de velocidade |
| Early-Z | Teste de profundidade antes do shader | Redução de invocações |
| Texture atlasing | Uma textura em vez de várias | Menos trocas |
Ambos os tipos de shaders são programáveis pelo desenvolvedor, mas trabalham em diferentes estágios do pipeline e resolvem diferentes tarefas. Fragment Shader é significativamente mais intensivo em recursos devido ao número de invocações.
| Parâmetro | Fragment Shader | Vertex Shader |
|---|---|---|
| Número de invocações | Milhões (resolução da tela) | Milhares (número de vértices) |
| Dados de entrada | Atributos interpolados | Atributos de vértices |
| Função principal | Cálculo da cor do fragmento | Transformação de geometria |
| Acesso a texturas | Completo (múltiplos samplers) | Limitado |
| Impacto no desempenho | Alto (depende da resolução) | Moderado (depende da geometria) |
Fragment Shader pode ser simples (amostragem de textura) ou complexo (iluminação multicamada). Vamos considerar dois exemplos práticos: texturização básica e um efeito gradiente usando tempo.
#version 300 es
precision mediump float;
in vec2 vTexCoord;
in vec3 vColor;
uniform sampler2D uDiffuseMap;
out vec4 fragColor;
void main() {
vec4 texColor = texture(uDiffuseMap, vTexCoord);
fragColor = texColor * vec4(vColor, 1.0);
}
#include <metal_stdlib>
using namespace metal;
struct FragmentIn {
float2 texCoord;
float3 normal;
};
fragment float4
fragmentMain(FragmentIn in [[stage_in]],
texture2d<float> tex [[texture(0)]]) {
constexpr sampler s(filter = linear);
float4 color = tex.sample(s, in.texCoord);
return color;
}
Perguntas frequentes
Fragment Shader é um miniprograma na GPU que determina qual será a cor de cada pixel na tela. Se o Vertex Shader determina a forma do objeto, então o Fragment Shader determina como esse objeto se parece — textura, iluminação, cor.
Fragment Shader é invocado para cada pixel na tela. Em um dispositivo com resolução de 2532x1170 (iPhone) isso é quase 3 milhões de invocações por quadro. A 60 FPS o shader executa 180 milhões de vezes por segundo, exigindo enorme poder computacional.
No Fragment Shader implementam-se: texturização, iluminação (Phong, PBR), sombras, reflexos, refrações, bloom, profundidade de campo, correção de cor, filtros LUT e geração procedural de texturas.
Use mediump precision para float, reduza o número de amostragens de textura, aplique early-z culling, combine operações de shader e evite desvios condicionais dentro do shader.
São a mesma coisa. O termo Fragment Shader é usado em OpenGL / Vulkan, enquanto Pixel Shader é usado na terminologia do Direct3D (Microsoft). Funcionalmente são idênticos: ambos calculam a cor de cada fragmento/pixel.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também