“Fascinado com o potencial de usar código e matemática para construir beleza visual.” — Inigo Quilez, cofundador do Shadertoy

Imagine criar uma floresta procedural, um oceano que respira, nebulosas cósmicas ou um corredor infinito, tudo sem uma única imagem, sem um único polígono modelado, apenas equações matemáticas avaliadas pixel a pixel em tempo real. Isso é shader art: uma das formas mais radicais, minimalistas e poderosas de expressão visual na computação.

Este texto é um guia completo para quem quer entender e começar a praticar essa arte.

O que é um shader?

Na arquitetura moderna de GPUs, um shader é um pequeno programa que roda diretamente na placa de vídeo. Ao contrário de código JavaScript ou Python, que roda em sequência na CPU, shaders rodam em milhares de threads paralelas simultâneas, uma para cada pixel da tela.

Existem dois tipos principais:

  • Vertex Shader: processa a posição de vértices (geometria 3D)
  • Fragment Shader: processa a cor de cada pixel individualmente

Shader art se concentra quase sempre no fragment shader. A pergunta que você responde, para cada pixel, é simples e poderosa:

“Dada a posição (x, y) deste pixel e o tempo t, qual é a sua cor?”

É essa simplicidade brutal que torna a área fascinante. Toda a complexidade visual emerge de funções matemáticas aplicadas a coordenadas.

GLSL: a linguagem

GLSL (OpenGL Shading Language) é a linguagem usada para escrever shaders para OpenGL e WebGL. Ela tem sintaxe similar ao C, mas com tipos especiais para vetores e matrizes, além de funções matemáticas nativas muito úteis.

Estrutura básica

O shader mais simples do mundo, que pinta tudo de vermelho:

void main() {
  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // R, G, B, Alpha
}

Um pouco mais interessante, um gradiente baseado na posição do pixel:

uniform vec2 u_resolution; // tamanho da tela (passado pela CPU)
 
void main() {
  vec2 uv = gl_FragCoord.xy / u_resolution.xy; // normaliza para [0.0, 1.0]
  gl_FragColor = vec4(uv.x, uv.y, 0.5, 1.0);
}

Agora com animação, usando o tempo como parâmetro:

uniform vec2 u_resolution;
uniform float u_time; // segundos desde o início
 
void main() {
  vec2 uv = gl_FragCoord.xy / u_resolution.xy;
  float r = 0.5 + 0.5 * sin(u_time);
  float g = uv.x;
  float b = uv.y;
  gl_FragColor = vec4(r, g, b, 1.0);
}

Uniforms: a ponte CPU GPU

Uniforms são variáveis passadas da CPU para todos os threads da GPU simultaneamente. Elas são somente leitura dentro do shader. Os mais comuns são:

UniformTipoO que representa
u_resolutionvec2Largura e altura da tela em pixels
u_timefloatSegundos desde o início da execução
u_mousevec2Posição do mouse em pixels
u_frameintNúmero do frame atual

No Shadertoy, os mesmos conceitos têm nomes um pouco diferentes, como iResolution, iTime e iMouse, mas a lógica é a mesma.

Tipos fundamentais do GLSL

float  f = 0.5;
vec2   v2 = vec2(1.0, 2.0);
vec3   v3 = vec3(1.0, 0.0, 0.0);
vec4   v4 = vec4(v3, 1.0);
mat2   m2 = mat2(1,0, 0,1);
 
vec3 cor = vec3(0.8, 0.3, 0.1);
float vermelho = cor.r;
vec2 rg = cor.rg;
vec3 bgr = cor.bgr;

O swizzling é uma das features mais elegantes do GLSL. Você pode reordenar ou repetir componentes livremente: cor.rrr, uv.yx, p.xzx.

Funções matemáticas essenciais

sin(x), cos(x)
abs(x)
fract(x)
floor(x)
mod(x, y)
mix(a, b, t)
smoothstep(e0, e1, x)
clamp(x, 0.0, 1.0)
length(v)
dot(a, b)
normalize(v)

Signed Distance Fields (SDFs): formas sem geometria

A técnica mais poderosa do shader art moderno são as Signed Distance Fields (SDFs), funções que retornam a distância assinada de um ponto à superfície de uma forma.

  • Positivo: o ponto está fora da forma
  • Zero: o ponto está exatamente na superfície
  • Negativo: o ponto está dentro da forma

Para desenhar um círculo:

float sdCircle(vec2 p, float raio) {
  return length(p) - raio;
}
 
void main() {
  vec2 uv = (gl_FragCoord.xy - u_resolution * 0.5) / u_resolution.y;
  float d = sdCircle(uv, 0.3);
 
  vec3 cor = d < 0.0 ? vec3(1.0, 0.8, 0.0) : vec3(0.05);
  gl_FragColor = vec4(cor, 1.0);
}

A força das SDFs está em como elas se combinam:

float opUnion(float d1, float d2) { return min(d1, d2); }
float opSubtract(float d1, float d2) { return max(-d1, d2); }
float opIntersect(float d1, float d2) { return max(d1, d2); }
float opSmoothUnion(float d1, float d2, float k) {
  float h = clamp(0.5 + 0.5 * (d2 - d1) / k, 0.0, 1.0);
  return mix(d2, d1, h) - k * h * (1.0 - h);
}

Inigo Quilez catalogou SDFs de dezenas de formas 3D, de esferas e caixas até toros, cápsulas, pirâmides e fractais, sempre com a mesma lógica combinável.

Raymarching: renderização 3D sem polígonos

O raymarching é uma técnica de renderização que usa SDFs para criar cenas 3D inteiras sem geometria modelada. O algoritmo é elegante:

  1. Para cada pixel, lança um raio a partir da câmera.
  2. Avança pelo raio na distância retornada pelo SDF mais próximo.
  3. Se a distância for menor que um epsilon, houve colisão.
  4. Calcula cor, iluminação e sombras a partir da normal da superfície.
float map(vec3 p) {
  float esfera = length(p) - 1.0;
  float chao = p.y + 1.5;
  return min(esfera, chao);
}
 
float march(vec3 ro, vec3 rd) {
  float t = 0.0;
  for (int i = 0; i < 100; i++) {
    vec3 p = ro + rd * t;
    float d = map(p);
    if (d < 0.001) break;
    t += d;
    if (t > 100.0) break;
  }
  return t;
}

Com raymarching é possível renderizar esferas, fractais 3D, fluidos, nuvens volumétricas, terrenos procedurais e animações inteiras em código puro, direto no fragment shader.

As plataformas: onde a magia acontece

Shadertoy

Criado em 2013 por Inigo Quilez e Pol Jeremias, o Shadertoy é a plataforma mais estabelecida para compartilhar fragment shaders. É ao mesmo tempo uma galeria, um laboratório e um arquivo vivo de técnicas.

Site: shadertoy.com

FragCoord.xyz

Lançado em fevereiro de 2026 por XorDev, o FragCoord.xyz surgiu como uma evolução moderna dessa cultura, com suporte a múltiplas linguagens, debugger, sliders customizáveis e exportação de shaders como HTML autônomo.

Site: fragcoord.xyz

Grandes nomes da área

Inigo Quilez

Uma das figuras centrais do shader art moderno. Além do Shadertoy, publicou dezenas de textos técnicos sobre rendering, SDFs, fractais, iluminação e otimização em tempo real.

XorDev

Conhecido pelos shaders compactos, pela cultura de shader golf e pelo trabalho educacional em torno de gráficos minimalistas e experimentação rápida.

Patricio Gonzalez Vivo

Autor do The Book of Shaders e criador do glslCanvas, uma das portas de entrada mais acessíveis para quem quer embutir shaders GLSL em páginas web.

kishimisu

Criador de conteúdo que ajudou a popularizar a entrada de iniciantes em shader art com vídeos e demonstrações mais amigáveis.

evvvvil

Artista da demoscene e programador de WebGL e Three.js, conhecido por live coding de shaders em palco.

nimitz

Um dos nomes mais respeitados do Shadertoy, com shaders cinemáticos e volumétricos que viraram referência técnica.

O movimento: a demoscene

Tudo isso tem raízes na Demoscene, subcultura que surgiu na Europa dos anos 1980 e 1990. O que começou com intros criadas por grupos de cracking evoluiu para uma cultura de competição de arte computacional em tempo real, com demos feitas sob restrições extremas como 4 KB, 64 KB ou shaders escritos ao vivo.

O Shader Showdown da Revision é talvez o símbolo mais forte dessa tradição: dois programadores no palco, uma DJ tocando e o público acompanhando o código virar imagem em tempo real.

Shader golf: a arte do mínimo

Code Golf é o exercício de escrever código que faz algo com o menor número de caracteres possível. Em shaders, isso vira uma estética própria.

Por que praticar?

  • Compreensão profunda da linguagem e dos atalhos possíveis
  • Otimização e eliminação de computação redundante
  • Substituições algébricas que ampliam o repertório mental
  • Prazer criativo de produzir imagem complexa com quase nada

Técnicas de golf

// Versão legível
vec2 uv = (gl_FragCoord.xy - u_resolution * 0.5) / u_resolution.y;
gl_FragColor = vec4(sin(u_time), uv.x, uv.y, 1.0);
 
// Versão golfada
O=vec4(sin(T),P,1);

Ferramentas: online

PlataformaURLDestaques
Shadertoyshadertoy.comMaior comunidade, milhares de shaders públicos com código aberto
FragCoord.xyzfragcoord.xyzMais moderno, com GLSL, HLSL, WebGPU e export HTML
The Book of Shaders Editoreditor.thebookofshaders.comEditor integrado ao livro, com foco didático
ShaderGifshadergif.comFoco em exportar shaders como GIFs animados

Ferramentas: offline e desktop

FerramentaTipoPlataformaDestaques
KodeLifeApp desktopWin/Mac/Linux/iOS/AndroidPopular entre VJs e live coders; sintaxe parecida com a do Shadertoy
SHADERedApp desktop open-sourceWin/LinuxIDE com debugger, compute shaders e import de modelos
glslViewerCLIWin/Mac/Linux/RPiFluxo por linha de comando e integração com scripts
VSCode + glsl-canvasExtensãoQualquerPreview ao vivo no editor e export HTML
VSCode + Shader ToyExtensãoQualquerCompatibilidade com a sintaxe do Shadertoy
Shader EditorApp mobileAndroidOpen source, com preview ao vivo
ShaderlyApp mobileiOS/iPadEditor GLSL móvel

Como embutir shaders no seu site

Existem três abordagens principais para colocar shader art em produção num site.

1. glslCanvas

<script src="https://cdn.jsdelivr.net/npm/glslCanvas@0.2.6/dist/GlslCanvas.min.js"></script>
 
<canvas class="glslCanvas"
  data-fragment="
    uniform vec2 u_resolution;
    uniform float u_time;
    void main() {
      vec2 uv = gl_FragCoord.xy / u_resolution.xy;
      gl_FragColor = vec4(uv, 0.5 + 0.5 * sin(u_time), 1.0);
    }
  "
  width="800" height="600">
</canvas>

É o caminho mais simples para levar um fragment shader para uma página web.

2. WebGL2 nativo

<canvas id="c"></canvas>
<script>
const gl = document.getElementById('c').getContext('webgl2');
// compile vertex + fragment shaders, link programa, passar uniforms no requestAnimationFrame
</script>

Aqui você ganha controle total sobre uniforms customizados, múltiplos buffers e texturas.

3. Export HTML do FragCoord.xyz

O FragCoord.xyz permite exportar qualquer shader como um arquivo .html autônomo com WebGL2 embutido, pronto para ser hospedado ou carregado como iframe.

Roteiro de aprendizado

Se você quer sair do zero até shader art mais avançado, este é um caminho eficiente:

Nível 1 — Fundamentos

  1. The Book of Shadersthebookofshaders.com
  2. kishimisu — “An Introduction to Shader Art Coding”
  3. LearnOpenGL — Shaderslearnopengl.com
  4. Pratique no FragCoord.xyz ou no Shadertoy

Nível 2 — Técnicas intermediárias

  1. Ruído procedural: Perlin, value noise e Voronoi
  2. SDFs 2D: formas básicas no material de Inigo Quilez e nos tutoriais do XorDev
  3. Transformações de espaço: rotação, escala, tile e mirror
  4. Paletas de cor com funções contínuas

Nível 3 — Arte avançada

  1. Raymarching com SDFs 3Dblog.maximeheckel.com/posts/painting-with-math-a-gentle-study-of-raymarching
  2. Artigos de Inigo Quileziquilezles.org/articles
  3. Shader Golfmini.gmshaders.com/p/code-golfing
  4. Demoscenepouet.net

Exemplo completo: gradiente animado com ruído

#ifdef GL_ES
precision mediump float;
#endif
 
uniform vec2 u_resolution;
uniform float u_time;
 
float hash(vec2 p) {
  return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);
}
 
float noise(vec2 p) {
  vec2 i = floor(p);
  vec2 f = fract(p);
  vec2 u = f * f * (3.0 - 2.0 * f);
 
  return mix(
    mix(hash(i), hash(i + vec2(1,0)), u.x),
    mix(hash(i + vec2(0,1)), hash(i + vec2(1,1)), u.x),
    u.y
  );
}
 
float fbm(vec2 p) {
  float v = 0.0, a = 0.5;
  for (int i = 0; i < 5; i++) {
    v += a * noise(p);
    p *= 2.0;
    a *= 0.5;
  }
  return v;
}
 
vec3 palette(float t) {
  vec3 a = vec3(0.5, 0.5, 0.5);
  vec3 b = vec3(0.5, 0.5, 0.5);
  vec3 c = vec3(1.0, 1.0, 1.0);
  vec3 d = vec3(0.00, 0.33, 0.67);
  return a + b * cos(6.28318 * (c * t + d));
}
 
void main() {
  vec2 uv = (gl_FragCoord.xy - u_resolution * 0.5) / u_resolution.y;
 
  vec2 warp = vec2(
    fbm(uv + vec2(u_time * 0.1)),
    fbm(uv + vec2(3.5, 9.2) + u_time * 0.08)
  );
 
  float f = fbm(uv + warp * 1.5);
  vec3 cor = palette(f + u_time * 0.05);
  cor *= 1.0 - length(uv) * 0.4;
 
  gl_FragColor = vec4(cor, 1.0);
}

Esse shader usa domain warping, técnica em que o ruído distorce o próprio espaço antes do cálculo final, criando superfícies orgânicas e mais vivas.

Por onde começar agora

  1. Abra o FragCoord.xyz ou o Shadertoy.
  2. Substitua o código padrão pelo gradiente animado acima.
  3. Mude números e parâmetros: uv * 3.0, u_time * 0.5, vec3(1.0, 0.0, 0.5).
  4. Instale a extensão glsl-canvas no VSCode para trabalhar offline.
  5. Leia o The Book of Shaders do começo.
  6. Quando tiver um resultado que te orgulha, exporte como HTML pelo FragCoord.xyz e coloque no seu site.

Se essa linha de exploração conversar com o lado de construção e experimentação da web, vale cruzar com Webmastery. Se a curiosidade for mais sobre protocolos, cultura de rede e caminhos alternativos da internet, a conversa segue bem em Protocolos e Redes Alternativas da Internet.

Shader art é uma das poucas formas de arte em que a ferramenta é a matemática, o canvas é a GPU e o limite real costuma ser a profundidade da sua própria curiosidade.