Fragment Shader es una etapa programable del pipeline gráfico que determina el color final de cada fragmento (píxel) de una imagen. Según Khronos Group, 2025, el shader de fragmentos recibe datos interpolados del Vertex Shader y realiza cálculos de iluminación, texturizado y efectos de color. Fragment Shader se invoca para cada píxel, lo que lo convierte en la etapa más intensiva en recursos del pipeline gráfico.
Puntos clave
Fragment Shader (shader de fragmentos o píxeles) es una etapa programable del pipeline gráfico que calcula el color final de cada fragmento de la imagen. Un fragmento es un píxel potencial que se convierte en un píxel visible en la pantalla después de pasar las pruebas de profundidad y stencil.
Fragment Shader se ejecuta después de la rasterización, cuando los primitivos 3D (triángulos) ya se han convertido en un conjunto de fragmentos. El shader recibe atributos interpolados — coordenadas de textura, normales, colores que se calcularon en el Vertex Shader para los vértices del triángulo y se interpolaron linealmente para cada píxel dentro del triángulo.
Antes de la aparición de los shaders programables (antes de DirectX 8 / OpenGL 2.0), el cálculo del color de los píxeles se realizaba mediante un pipeline fijo con un conjunto limitado de operaciones. El Fragment Shader programable apareció en 2001 y expandió radicalmente las capacidades gráficas: los desarrolladores obtuvieron control total sobre el color de cada píxel, lo que permitió implementar iluminación fotorrealista, materiales complejos y post-efectos.
Fragment Shader es lanzado por la GPU para cada fragmento generado por el rasterizador. Cada invocación del shader procesa un fragmento, lee sus datos de entrada, ejecuta código de usuario y escribe el valor de salida — el color del fragmento en formato RGBA.
Los datos de entrada de Fragment Shader incluyen atributos interpolados del Vertex Shader (coordenadas de textura, normales, colores), variables uniform (fuentes de luz, matrices) y samplers de textura. Los datos de salida son el vector de color (gl_FragColor en OpenGL ES 2.0 o una variable definida por el usuario en ES 3.0), que se escribe en el búfer de color.
#version 300 es
precision mediump float;
in vec2 vTexCoord;
uniform sampler2D uTexture;
out vec4 fragColor;
void main() {
fragColor = texture(uTexture, vTexCoord);
}
Fragment Shader es responsable de la calidad visual de la imagen. Todos los efectos que el usuario ve en la pantalla — color, sombras, reflejos, transparencia — se calculan en esta etapa del pipeline gráfico.
La operación más frecuente es muestrear el color de una textura utilizando coordenadas UV interpoladas. Sampler2D y la función texture() permiten obtener el color de un píxel de un atlas de texturas. El filtrado (bilineal, trilineal, anisotrópico) se controla mediante parámetros del sampler y afecta la nitidez de la imagen en diferentes ángulos de visión.
El modelo de iluminación Phong se calcula en Fragment Shader por píxel, proporcionando reflejos más suaves que la iluminación por vértices (sombreado Gouraud). La iluminación Phong incluye tres componentes: ambiente, difusa y 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);
}
Fragment Shader permite aplicar post-procesamiento: corrección de color mediante tablas LUT, desenfoque (blur), efecto de resplandor (bloom) y tonemapping para renderizado HDR. Todos estos efectos funcionan a nivel de píxel y se ejecutan en tiempo real.
El rendimiento de Fragment Shader es el principal factor que limita los FPS en los juegos móviles modernos. Dado que el shader se invoca para cada píxel, incluso un pequeño aumento en la complejidad del código puede provocar una caída notable en la frecuencia de cuadros.
Para GPUs móviles (Qualcomm Adreno, ARM Mali) se recomienda: usar mediump precision para variables float, combinar muestreos de textura, aplicar pruebas early-z para descartar fragmentos invisibles antes de la ejecución del shader.
| Método | Descripción | Ganancia |
|---|---|---|
| Mediump precision | Precisión de 16 bits en lugar de 32 bits | Hasta 2x de velocidad |
| Early-Z | Prueba de profundidad antes del shader | Reducción de invocaciones |
| Texture atlasing | Una textura en lugar de varias | Menos cambios |
Ambos tipos de shaders son programables por el desarrollador, pero trabajan en diferentes etapas del pipeline y resuelven diferentes tareas. Fragment Shader es significativamente más intensivo en recursos debido al número de invocaciones.
| Parámetro | Fragment Shader | Vertex Shader |
|---|---|---|
| Número de invocaciones | Millones (resolución de pantalla) | Miles (número de vértices) |
| Datos de entrada | Atributos interpolados | Atributos de vértices |
| Función principal | Cálculo del color del fragmento | Transformación de geometría |
| Acceso a texturas | Completo (múltiples samplers) | Limitado |
| Impacto en el rendimiento | Alto (depende de la resolución) | Moderado (depende de la geometría) |
Fragment Shader puede ser simple (muestreo de textura) o complejo (iluminación multicapa). Consideremos dos ejemplos prácticos: texturizado básico y un efecto de gradiente usando tiempo.
#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;
}
Preguntas frecuentes
Fragment Shader es un miniprograma en la GPU que determina de qué color será cada píxel en la pantalla. Si Vertex Shader determina la forma del objeto, entonces Fragment Shader determina cómo se ve ese objeto — textura, iluminación, color.
Fragment Shader se invoca para cada píxel en la pantalla. En un dispositivo con una resolución de 2532x1170 (iPhone) esto es casi 3 millones de invocaciones por cuadro. A 60 FPS el shader se ejecuta 180 millones de veces por segundo, lo que requiere una enorme potencia computacional.
En Fragment Shader se implementan: texturizado, iluminación (Phong, PBR), sombras, reflejos, refracciones, bloom, profundidad de campo, corrección de color, filtros LUT y generación procedural de texturas.
Use mediump precision para float, reduzca el número de muestreos de textura, aplique early-z culling, combine operaciones de shader y evite saltos condicionales dentro del shader.
Son lo mismo. El término Fragment Shader se usa en OpenGL / Vulkan, mientras que Pixel Shader se usa en la terminología de Direct3D (Microsoft). Funcionalmente son idénticos: ambos calculan el color de cada fragmento/píxel.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también