Entendendo a Renderização Raymarching do WebGL 2.0
Um mergulho na tecnologia Raymarching do WebGL 2.0: aprenda a usar campos de distância assinada SDF para renderização volumétrica em tempo real e entenda como essa técnica leva a GPU ao limite.

Um mergulho profundo em raymarching WebGL 2.0, SDFs e renderização volumétrica em tempo real
O WebGL 2.0 desbloqueia um poderoso conjunto de recursos de GPU, permitindo técnicas avançadas de renderização que tradicionalmente exigiam APIs nativas. Entre essas, o raymarching se destaca como um dos métodos mais expressivos e matematicamente elegantes para renderizar cenas complexas com geometria mínima.
Este artigo explora os conceitos fundamentais por trás do raymarching WebGL 2.0, explica como os Campos de Distância Assinada (SDFs) permitem renderização eficiente e mostra como essa técnica pode extrair desempenho surpreendente da GPU.
1. O que é Raymarching?
Raymarching é um método de renderização onde, em vez de projetar geometria na tela, disparamos um raio da câmera por pixel, movemo-lo passo a passo através de uma cena virtual e avaliamos distâncias até que o raio atinja uma superfície ou alcance um alcance máximo.
1.1 Como o Raymarching Funciona (Diagrama Visual)
Câmera
|
| raio
v
+--------------------------------- Pixel da Tela
|
| passo de marcha 1 (distância d1)
|
|---------> passo de marcha 2 (distância d2)
|
|-----------------------> passo de marcha 3 ...
|
Superfície atingida quando distância < ε
Raymarching é essencialmente um loop:
for (int i = 0; i < MAX_STEPS; i++) {
float dist = sdf(currentPos);
if (dist < EPSILON) hitSurface();
currentPos += rayDir * dist;
}
O ingrediente mágico é a função SDF que passamos.
2. O que são Campos de Distância Assinada (SDFs)?
Um Campo de Distância Assinada é uma função que retorna:
> 0 distância fora do objeto
= 0 exatamente na superfície
< 0 distância dentro do objeto
2.1 Diagrama SDF
fora
+------------+
| d = 0.5 |
| |
dentro | SDF | superfície d = 0
d < 0 | |
| d = -0.3 |
+------------+
2.2 Exemplo: SDF de Esfera
float sdSphere(vec3 p, float r) {
return length(p) - r;
}
Ao combinar essas formas básicas com operações booleanas (união, subtração, interseção), você pode construir cenas complexas sem qualquer geometria tradicional.
3. Por que usar Raymarching SDF no WebGL 2.0?
3.1 Benefícios
Sem buffers de vértices ou malhas necessários Tudo é calculado matematicamente no fragment shader.
Detalhe geométrico infinito SDFs definem superfícies suaves e contínuas.
Objetos dinâmicos e deformáveis Anima facilmente formas com matemática.
Cenas compactas Uma cena 3D completa pode ser definida usando apenas algumas linhas de GLSL.
3.2 Recursos do WebGL 2.0 que tornam isso possível
- Floats de alta precisão
- Suporte completo a shaders GLSL ES 3.0
- UBOs (buffers uniformes)
- Texturas float
- Loops e ramificações mais flexíveis
Isso permite raymarching estável e de alto desempenho que era difícil no WebGL 1.0.
4. Construindo um Raymarcher WebGL 2.0 Passo a Passo
4.1 Configuração do Raio da Cena
Calcule um raio para cada pixel:
vec3 rayOrigin = cameraPos;
vec3 rayDir = normalize(uv.x * camRight + uv.y * camUp + camForward);
4.2 O Loop de Raymarch
float marchRay(vec3 ro, vec3 rd) {
float totalDist = 0.0;
for (int i = 0; i < MAX_STEPS; i++) {
vec3 p = ro + rd * totalDist;
float d = map(p); // sua função SDF
if (d < EPSILON) break; // acerto
if (totalDist > MAX_DISTANCE) break; // erro
totalDist += d;
}
return totalDist;
}
4.3 Definindo a Cena SDF
float map(vec3 p) {
float s = sdSphere(p, 1.0);
float box = sdBox(p - vec3(2.0, 0.0, 0.0), vec3(0.7));
return min(s, box); // união
}
4.4 Cálculo da Normal
Usando aproximação de gradiente:
vec3 calcNormal(vec3 p) {
const vec2 e = vec2(0.001, 0.0);
return normalize(vec3(
map(p + e.xyy) - map(p - e.xyy),
map(p + e.yxy) - map(p - e.yxy),
map(p + e.yyx) - map(p - e.yyx)
));
}
4.5 Modelo de Iluminação
Sombreamento difuso simples:
float diffuse = max(dot(normal, lightDir), 0.0);
5. Renderizando Volumes (Névoa, Nuvens, Fumaça)
Raymarching SDF pode ser estendido para renderização volumétrica, onde cada passo contribui com cor e densidade em vez de parar em uma superfície.
5.1 Diagrama de Volume
Raio →
[baixa densidade] [média] [alta densidade] [opaco]
+--------+---------+---------+-------+
amostra1 amostra2 amostra3 amostra4
5.2 Modelo de Acumulação de Volume
vec3 color = vec3(0);
float absorption = 1.0;
for (int i = 0; i < STEPS; i++) {
float density = computeDensity(p);
vec3 sampleColor = density * vec3(0.6, 0.7, 1.0);
color += sampleColor * absorption;
absorption *= (1.0 - density * 0.1);
p += rd * STEP_SIZE;
}
Raymarching de volumes é mais caro, mas as melhorias de desempenho do WebGL 2.0 (especialmente em GPUs móveis) tornam nuvens, névoa e nebulosas em tempo real viáveis.
6. Técnicas de Otimização de Desempenho
Raymarching pode ser pesado, então otimizações são essenciais.
6.1 Técnicas Principais
Culling de Distância Pule grandes áreas vazias confiando em distâncias SDF precisas.
Volumes Delimitadores Teste se o raio sequer entra na região onde os SDFs existem.
Tamanho de Passo Adaptativo Use passos menores perto de superfícies, passos maiores em espaço aberto.
Saída Antecipada Pare de marchar assim que a superfície for atingida.
Reduzir MAX_STEPS Valores típicos variam de 64–128 para renderização em tempo real.
Use uniforms e buffers do WebGL 2.0 com eficiência Mova valores que não mudam para fora dos loops.
7. Estrutura de Código para um Projeto WebGL 2.0
Exemplo de layout de diretório:
shader/
raymarch.vert
raymarch.frag
src/
webgl2-context.js
camera.js
renderer.js
index.html
Seções típicas de fragment shader:
// 1. Configuração de Câmera/Raio
// 2. Definições SDF
// 3. Funções de Material e Iluminação
// 4. Loop de Raymarch
// 5. Saída de Cor Final
8. Quando Você Deve Usar Raymarching?
Raymarching se destaca quando você quer:
- Formas suaves infinitas
- Fractais
- Cenas de ficção científica
- Sombras suaves de distância assinada
- Geometria procedural
- Efeitos volumétricos (nuvens, névoa, raios de deus)
Evite raymarching quando você precisa:
- Muitas malhas complexas detalhadas
- Personagens realistas com skinning
- Cenas dinâmicas grandes com milhares de objetos
Raymarching é melhor para mundos procedurais e efeitos visuais estilizados.
9. Conclusão
O raymarching WebGL 2.0 traz renderização avançada em tempo real para o navegador usando nada mais que matemática e GLSL. Com SDFs, você pode criar cenas 3D complexas sem um único buffer de vértices. Embora a técnica seja computacionalmente intensiva, otimização cuidadosa permite visuais expressivos que rivalizam com aplicações GPU nativas.
Raymarching representa uma interseção única de matemática, arte e programação GPU, tornando-o uma das técnicas mais emocionantes para explorar no desenvolvimento WebGL moderno.
Como isso se relaciona com o Volume Shader BM Test
Você leu a teoria — agora a ponte prática com a ferramenta. Veja como o que está acima se aplica ao Volume Shader BM Test.
Por que este teste é mais pesado que um demo 3D comum
Um demo WebGL típico desenha alguns milhares de polígonos. Este benchmark pede que a GPU rode um loop de raymarching por pixel — frequentemente mais de 1.000 iterações cada — sem geometria para encurtar o caminho. GPUs de mid-range que rodam jogos a 60 FPS frequentemente caem abaixo de 30 FPS em Heavy.
Por que o FPS cai em celulares
Celulares começam a fazer throttling assim que o SoC esquenta. Os primeiros 10 segundos parecem ótimos, depois o clock da GPU diminui. Ligue na tomada, rode em Light ou Medium e compare por estabilidade, não pelo pico de FPS. Veja o guia de teste GPU para celular.
Por que a primeira execução pode ser mais lenta (compilação de shader)
Na primeira carga o navegador precisa compilar GLSL em binário do driver, e em alguns drivers isso leva centenas de milissegundos — aparecendo como um pequeno engasgo no início. Descarte a primeira execução e use a segunda.
Como comparar resultados de forma justa
Mesmo modo, mesma aba em primeiro plano, mesma fonte de energia. Light, Medium e Heavy não podem ser comparados diretamente porque são cargas diferentes. Veja o guia de FPS.
O que fazer se o navegador estiver usando a GPU integrada
Em laptops com iGPU e dGPU, Chrome / Edge muitas vezes optam pela integrada para poupar bateria. Abra chrome://gpu e verifique GL_RENDERER. Se aparecer a iGPU, force o navegador para a GPU dedicada nas configurações gráficas do sistema. O guia de correção de lag detalha o processo.
Faça o teste
Você já tem a teoria. Rode o benchmark real — leva menos de um minuto.
Iniciar Volume Shader BM Test →