Computer

Curso de Informática

profgabrielfelippe@gmail.com

Computação Gráfica

Explore de forma visual os conceitos fundamentais que fazem jogos, animações e interfaces gráficas funcionarem: curvas, transformações, rasterização, cor e projeção 3D.

Curvas e Superfícies de Bézier

0.350
Polígono de controle Curva de Bézier / pontos Pᵢ Construção (De Casteljau) Ponto B(t)

O que é isso?

Uma curva de Bézier é definida por um conjunto de pontos de controle (Pᵢ, em azul). A curva não passa pelos pontos do meio — eles apenas "puxam" sua forma através do polígono de controle (linhas tracejadas cinzas). O ponto inicial e final da curva sempre coincidem com o primeiro e o último ponto de controle.

Como a curva é construída

Mova o slider t devagar com "Construção" ativada e observe as linhas acinzentadas: esse é o Algoritmo de De Casteljau. Ele interpola linearmente entre cada par de pontos consecutivos, depois interpola entre os resultados, e assim sucessivamente, até sobrar um único ponto — o B(t) em vermelho.

Onde isso é usado?

Fontes tipográficas (as letras que você está lendo agora são feitas de curvas de Bézier), ferramentas vetoriais como Illustrator, Figma e Inkscape, curvas de "easing" em animações e jogos, estradas e trilhos em modelagem 3D, e o path do SVG que vimos na seção de vetor vs. raster.

0.500
0.500

Arraste um ponto de controle verticalmente para mudar sua altura. Arraste o fundo do canvas para girar a câmera. Use a roda do mouse para dar zoom.

Cor da malha = altura (baixo → alto) Rede de controle 4×4 Pontos da rede (parados) Ponto arrastado / S(u,v) Construção (u, v)
O que é isso?

Uma curva cúbica usa 4 pontos ao longo de 1 parâmetro (t). Uma superfície bicúbica usa uma malha de 4×4 = 16 pontos (a rede de controle, linhas tracejadas), controlada por dois parâmetros independentes — u e v — segundo S(u,v) = ΣΣ Bᵢ(u)·Bⱼ(v)·Pᵢⱼ. A malha colorida que preenche a superfície usa uma cor que varia com a altura (eixo y) de cada ponto: cinza-azulado nos vales, azul no meio, vermelho nos picos — puramente visual, para facilitar enxergar o relevo.

Como a superfície é construída

Ative "Construção (u, v)" e mexa nos sliders u e v: 1) fixando u, o De Casteljau roda em cada uma das 4 colunas da rede, gerando 4 pontos intermediários (cinza); 2) esses 4 pontos são então interpolados com v, usando o mesmo algoritmo, resultando no ponto final S(u,v) (vermelho) — o mesmo De Casteljau da curva 2D, só que aplicado duas vezes.

Onde isso é usado?

É a base de carrocerias de carros, cascos de navio e superfícies orgânicas em softwares como Blender, Maya e Rhino — qualquer forma 3D suave que precise ser editada arrastando poucos pontos de controle em vez de milhares de vértices individuais.

Arraste qualquer ponto P — a curva de Bézier muda inteira, enquanto só um pedaço da B-Spline se mexe.

Polígono de controle Bézier (controle global) B-Spline cúbica (controle local) Trecho afetado / ponto arrastado
O que é isso?

Os mesmos pontos de controle (ligados pelo polígono tracejado) geram uma Bézier (grau N−1, usando todos os pontos de uma vez) e uma B-Spline cúbica (que usa sempre 4 pontos vizinhos por vez, deslizando pela malha). A Bézier sempre passa pelos extremos; a B-Spline uniforme geralmente não toca em nenhum ponto de controle — ela só é "puxada" por eles.

Controle global vs. controle local

Arraste qualquer ponto P com "Destacar controle local" ativado: na Bézier, mover qualquer ponto muda a curva inteira — controle global, porque cada ponto tem peso em todo o intervalo t ∈ [0,1]. Já na B-Spline, o trecho destacado em vermelho é a única parte afetada — controle local, porque cada ponto só influencia uma janela vizinha de 4 pontos.

Onde isso é usado?

A Bézier é ótima para curvas curtas — ícones, letras, um único traço de assinatura — onde editar um ponto e ver tudo mudar é aceitável. B-Splines e NURBS são preferidas para formas longas e complexas (carrocerias, traçados de estrada, curvas de animação com muitos quadros-chave), já que editar uma parte não distorce o restante da curva.

Transformações Geométricas

0
0
0°
1.0x
0.0
A forma cinza tracejada é o objeto original; a forma azul é o resultado de aplicar, em ordem, escala → cisalhamento → rotação → translação — a mesma sequência de matrizes usada internamente por motores gráficos 2D.

Rasterização de Retas

2
3
17
12

0 pixels pintados pelo algoritmo de Bresenham

Monitores só têm pixels em posições inteiras. O algoritmo de Bresenham decide, usando apenas somas e comparações de inteiros, quais pixels melhor aproximam uma reta contínua — sem usar divisões ou números decimais.

Modelo de Cor RGB

39
62
116
#273E74
Cada pixel de tela é formado pela combinação de luz vermelha, verde e azul (RGB). É mistura aditiva: somar as três cores no máximo gera branco — o oposto da mistura de tintas, que é subtrativa.

Projeção 3D - Cubo Wireframe

25°
35°
500
Para desenhar um objeto 3D na tela 2D, cada vértice é rotacionado nos eixos X e Y e depois projetado com perspectiva: quanto mais distante da câmera (maior Z), menor e mais próximo do centro o ponto aparece na tela.

Sprite Sheets e Animação por Frames

6
8

Quadro 1 de 6

Um sprite sheet é uma única imagem contendo vários quadros de uma animação lado a lado. Para animar, o jogo recorta (via drawImage com um retângulo de origem) um quadro por vez e o exibe rapidamente em sequência — a mesma técnica usada em qualquer jogo 2D com personagens animados.

Tilemap (Mapa em Grade)

Jogos 2D costumam armazenar o cenário como uma matriz de números (0 = grama, 1 = água, etc.), onde cada número indica qual tile (ladrilho) desenhar naquela célula. Isso torna o mapa leve para guardar e fácil de editar — a base de qualquer editor de fases.

HSV vs RGB

220°
66%
46%
#273E74
RGB descreve cor como quantidades de luz vermelha, verde e azul — ótimo para telas, mas pouco intuitivo para escolher cores. HSV (Matiz, Saturação, Valor) separa "qual cor" (H), "quão viva" (S) e "quão clara/escura" (V) — por isso é o modelo usado na maioria dos seletores de cor de programas de desenho.

CMYK — Cor Subtrativa

75%
15%
0%
25%
#000000
Tintas não emitem luz — elas subtraem (absorvem) comprimentos de onda da luz branca que incide sobre o papel. Por isso a impressão usa um modelo subtrativo: Ciano, Magenta e Yellow (amarelo) somados no máximo deveriam gerar preto, mas tintas reais não são puras — sobra um marrom escuro sujo. Por isso existe o quarto canal, K (Key/preto), aplicado direto como tinta preta.
Aditivo (luz) vs. Subtrativo (tinta)

Em RGB, começar do preto (tela apagada) e somar luz vermelha, verde e azul caminha em direção ao branco. Em CMYK, começar do branco (papel) e somar tinta caminha em direção ao preto — cada tinta filtra uma faixa de cor da luz refletida. O diagrama acima mostra os três círculos de tinta se sobrepondo sobre o papel branco: onde C e M se cruzam vira um azul escuro; onde os três se cruzam, o resultado já deveria ser preto.

Por que existe o canal K?

Pigmentos de tinta reais não são perfeitamente puros, então C+M+Y no máximo produz um marrom-acinzentado, não um preto neutro — e ainda encharcaria o papel com três camadas de tinta. Impressoras adicionam um cartucho de tinta preta pura (K) só para texto e sombras profundas: mais barato, mais neutro e seca mais rápido do que empilhar as três cores.

Conversão RGB ↔ CMYK

Com R, G, B normalizados entre 0 e 1: K = 1 − max(R,G,B), C = (1−R−K)/(1−K), M = (1−G−K)/(1−K), Y = (1−B−K)/(1−K). Para voltar: R = (1−C)·(1−K), G = (1−M)·(1−K), B = (1−Y)·(1−K), cada uma multiplicada por 255.

Onde isso é usado?

Todo material impresso — jornais, embalagens, pôsteres — separa a imagem em quatro chapas ou cartuchos: C, M, Y e K. É também por isso que cores muito vivas e saturadas na tela (gamute RGB, feito de luz) às vezes "somem" ao imprimir: o gamute CMYK, limitado pelas tintas físicas disponíveis, é menor, e alguns tons de RGB simplesmente não têm tinta equivalente.

Detecção de Colisão

Arraste as duas formas para testar a colisão

AABB (Axis-Aligned Bounding Box) verifica colisão comparando as bordas de dois retângulos alinhados aos eixos — rápido e muito usado para hitboxes de personagens. A colisão entre círculos é ainda mais simples: basta comparar a distância entre os centros com a soma dos raios.

Campo de Visão e Raycasting 2D

90°
0°
320

Arraste o guarda (azul) e o alvo (círculo) para testar a detecção

O cone de cima é o campo de visão usado em jogos de furtividade: cada raio é lançado a partir do "guarda" e para ao atingir uma parede, formando a área efetivamente visível. O alvo só é "detectado" se estiver dentro do ângulo E sem paredes no caminho. A faixa de baixo usa as mesmas distâncias dos raios para desenhar colunas verticais — a técnica de raycasting que renderizava jogos como Wolfenstein 3D antes das GPUs 3D existirem.

Iluminação: Flat, Gouraud e Phong

15°
30°
45°
30°
24
Flat calcula uma única cor por face (visivelmente facetado). Gouraud calcula a luz só nos vértices e interpola a cor entre eles, suavizando a esfera. Phong vai além: aproxima o cálculo por pixel, permitindo o brilho especular (o ponto de luz refletida) — por isso é o padrão usado em motores de jogos modernos. Esta demo usa uma malha bem fina para simular o efeito por pixel do Phong com canvas 2D.

Ruído Perlin — Terreno Procedural

110
4
0.50
38%
O ruído Perlin gera números pseudoaleatórios que variam suavemente no espaço — diferente de ruído puramente aleatório, pontos vizinhos têm valores parecidos, criando formas orgânicas em vez de estática. Somar o ruído em várias oitavas (frequências dobrando, amplitude caindo pela persistência) adiciona detalhe fino sobre a forma geral, técnica chamada fBm (fractal Brownian motion). O valor resultante vira altura do terreno; comparando com o nível do mar, colorimos água, praia, grama, floresta, montanha e neve. É assim que jogos como Minecraft e No Man's Sky geram mundos inteiros sem armazenar um único pixel manualmente.

Anti-aliasing — Supersampling

7.5
0.30
4×4
Sem Anti-aliasing
Com Supersampling 4×4
Sem anti-aliasing, cada pixel é testado em um único ponto (seu centro): se cair dentro do círculo, pinta 100% preto; senão, 100% branco — daí o efeito de escada (jaggies) nas bordas curvas. Mexa no deslocamento sub-pixel e note como a borda "pula" de forma abrupta mesmo com um movimento minúsculo. O supersampling resolve isso testando N×N subamostras dentro de cada pixel e pintando um tom de cinza proporcional à cobertura (fração de amostras dentro da forma) — por isso a borda fica suave. É a técnica usada por MSAA/SSAA em placas de vídeo: quanto maior o N, mais suave a borda, mas o custo cresce com N² amostras por pixel — o clássico trade-off entre qualidade e desempenho.

SVG vs Canvas — Vetor vs Raster

5.0×
20°
Canvas (Raster / Bitmap)
SVG (Vetor)

      
O canvas guarda apenas uma grade fixa de pixels coloridos (50×50, propositalmente pequena aqui): ao ampliar, o navegador só consegue esticar esses mesmos pixels, então a borda vira "escada" — é raster/bitmap. O SVG, por outro lado, guarda cada forma como coordenadas e atributos matemáticos em uma marcação (o código abaixo, editável até no DevTools do navegador): a cada zoom, ele é recalculado e redesenhado na resolução atual da tela, sempre nítido — é vetorial. Isso vale tanto para polígonos (`<polygon>`) e círculos (`<circle>`) quanto para texto (`<text>`): diferente de uma fonte "desenhada" pixel a pixel, o texto em SVG continua nítido e selecionável em qualquer tamanho, porque é a mesma fonte vetorial do sistema sendo renderizada sob demanda. Por isso ícones, logos, textos e interfaces preferem SVG (redimensiona sem perda, arquivo leve, cada elemento é um nó no DOM que aceita CSS/JS), enquanto fotos e texturas com muito detalhe e gradientes complexos preferem raster (PNG/JPEG ou canvas), já que descrever cada nuance como fórmula geométrica seria inviável.

Convolução — Filtros de Imagem (Kernels)

0
Original
Resultado
Passe o mouse sobre a imagem Original para ver a janela do kernel deslizando pixel a pixel.
Um filtro de convolução desliza uma pequena matriz de números — o kernel — sobre cada pixel da imagem: em cada posição, multiplica os valores do kernel pelos pixels vizinhos correspondentes e soma tudo, gerando o novo valor daquele pixel. Um kernel de blur (caixa ou gaussiano) usa só pesos positivos que somam 1, misturando cada pixel com sua vizinhança e suavizando detalhes — repare como o xadrez no canto vira cinza uniforme. O sharpen faz o oposto: reforça o pixel central e subtrai os vizinhos, acentuando diferenças. Já o Sobel usa kernels cuja soma é zero — por isso a normalização não se aplica, e usamos um offset de 128 só para enxergar valores negativos como cinza médio: onde a imagem é uniforme o resultado fica perto de zero (cinza); onde há uma borda (mudança brusca de intensidade), o resultado dispara para valores bem altos ou bem baixos, "acendendo" o contorno. O modo combinado calcula Gx e Gy separadamente (Gy é só o Gx girado 90°) e mede a magnitude do gradiente com √(Gx² + Gy²) — a detecção de bordas clássica. Edite os números do kernel à mão e observe a imagem reagir em tempo real: esse mesmo produto entre kernel e vizinhança, repetido pixel a pixel, roda por trás do blur, sharpen e detecção de bordas de qualquer editor de imagem — e é também a operação central das primeiras camadas de uma rede neural convolucional (CNN).

B-Spline e NURBS — Curvas com Controle Local

1.0
0.350
Arraste os pontos, mude o grau e observe a curva.
Vetor de nós — a faixa esverdeada é o domínio válido de u; o trecho laranja é o intervalo de nó ativo agora.
Polígono de controle Curva B-Spline / NURBS Comparação não-racional (w = 1) Pontos de influência local Ponto na curva P(u)

O que é uma B-Spline?

Assim como a Bézier, uma B-Spline é gerada a partir de pontos de controle, mas em vez de um único polinômio usando todos os pontos de uma vez, ela costura vários pedaços polinomiais de grau p, cada um controlado por apenas p+1 pontos vizinhos. Essa costura é definida por um vetor de nós (knot vector) — uma sequência de valores de parâmetro que diz onde cada pedaço começa e termina.

Vetor de nós: uniforme vs. aberto (clamped)

No modo uniforme, os nós são igualmente espaçados (0, 1, 2, 3...) e a curva geralmente não toca o primeiro nem o último ponto de controle — repare os nós acinzentados fora da faixa verde na régua acima. No modo aberto/clamped, o primeiro e o último nó são repetidos p+1 vezes (multiplicidade máxima), o que "grudam" a curva aos pontos extremos — igual à Bézier. Aliás, quando o número de pontos é exatamente p+1, a B-Spline aberta é uma Bézier: ela é um caso particular.

Controle local e continuidade

Ative "Destacar pontos de influência local" e mexa o slider u: apenas p+1 pontos (destacados em laranja) afetam o trecho laranja da curva naquele instante — mover qualquer outro ponto não muda nada ali. Isso é controle local, a grande vantagem sobre a Bézier. Cada vez que um valor de nó se repete (multiplicidade), a curva perde um grau de suavidade nesse ponto — com multiplicidade p+1 (como nas pontas do modo clamped) a curva pode até formar um "bico".

NURBS: quando um peso vale mais que mil pontos

Ligue "Racional (NURBS)" e arraste o slider de peso de um ponto selecionado: valores maiores que 1 puxam a curva na direção daquele ponto; valores menores que 1 a empurram para longe. Essa curva "racional" (Non-Uniform Rational B-Spline) é a mesma B-Spline, mas cada ponto pesa diferente na média ponderada — P(u) = Σ Nᵢwᵢ Pᵢ / Σ Nᵢwᵢ. Isso importa porque nenhuma B-Spline puramente polinomial consegue desenhar um círculo ou uma elipse exatos — mas com os pesos certos, uma NURBS consegue, com erro zero.

Onde isso é usado?

NURBS é o formato padrão de curvas e superfícies em softwares de CAD industrial e modelagem (Rhino, CATIA, SolidWorks, carrocerias de carros e cascos de navio), justamente por representar formas orgânicas e arcos circulares perfeitos com a mesma matemática. B-Splines não-racionais aparecem em splines de câmera e caminhos de animação em motores de jogo, em fontes vetoriais e em qualquer ferramenta de edição de curvas onde mexer numa ponta não pode distorcer a curva inteira.

Compressão de Imagem — Quantização de Cores

3
Original
Quantizada
Uma imagem "sem compressão" guarda 24 bits por pixel (8 bits para cada canal R, G, B — até 16,7 milhões de cores possíveis). A quantização de cores reduz drasticamente quantas cores distintas existem na imagem, permitindo trocar "cada pixel guarda sua própria cor" por "cada pixel guarda apenas o índice de uma cor numa paleta pequena" — o princípio por trás de formatos indexados como GIF e PNG-8. Compare os dois métodos abaixo e observe as estatísticas de tamanho mudando em tempo real.
Quantização uniforme (redução de bits por canal)

A forma mais simples: em vez de 256 níveis (8 bits) por canal, arredondamos cada canal para apenas 2^bits níveis igualmente espaçados. Com 1 bit por canal sobram só 2×2×2 = 8 cores (as combinações de preto e branco puro por canal); com 8 bits voltamos à imagem original. É rápido e não exige analisar a imagem, mas desperdiça níveis em cores que nem aparecem na cena.

Paleta ótima (Median Cut)

Em vez de espaçar os níveis uniformemente, o algoritmo Median Cut primeiro observa quais cores a imagem realmente usa: coloca todas elas numa "caixa" no espaço RGB, encontra o canal com maior variação nessa caixa, ordena as cores por esse canal e corta a caixa ao meio (pela mediana ponderada por frequência). Repete o corte na caixa mais "cheia" até ter K caixas, e a cor final de cada caixa é a média das cores que caíram nela. O resultado é uma paleta de K cores escolhida sob medida para aquela imagem — por isso costuma ficar visivelmente melhor que a quantização uniforme para o mesmo número de cores.

Dithering: escondendo o banding

Reduzir cores cria banding — faixas visíveis onde deveria haver um degradê suave. O dithering de Floyd–Steinberg ataca isso espalhando o erro de cada pixel quantizado (a diferença entre a cor original e a mais próxima da paleta) para os vizinhos ainda não processados (7/16 para a direita, 3/16 diagonal inferior-esquerda, 5/16 abaixo, 1/16 diagonal inferior-direita). Isso não aumenta o número de cores usadas, mas engana o olho: padrões de pontos alternados simulam tons intermediários que a paleta não tem — a mesma técnica usada em jornais impressos em preto e branco e em imagens de 1 bit do Mac original.

Como ler as estatísticas

"Bits/pixel (índice)" é ⌈log₂(nº de cores)⌉ — quantos bits bastam para numerar cada cor da paleta. O tamanho comprimido soma esse índice por pixel mais a própria paleta (poucos bytes). Ative "Formas + ruído" com poucos bits para ver o pior caso: uma imagem cheia de cores quase únicas comprime muito menos do que um gradiente suave.

Onde isso é usado?

GIF e PNG-8 armazenam uma paleta de até 256 cores e um índice por pixel; jogos retrô como NES (54 cores no total) e Game Boy (4 tons de verde) eram limitados por hardware a paletas minúsculas; e a quantização de cores segue como etapa de pré-processamento em compressão com perdas, redução de tamanho de assets e conversão de imagens para telas e-ink ou displays de baixo custo.

Z-Buffer — Teste de Profundidade

35°
5.0
Cena renderizada (cor)
Buffer de profundidade (Z)
Passe o mouse sobre a cena renderizada para ler a profundidade (Z) de cada pixel.
Cada esfera é testada pixel a pixel, não objeto a objeto. Para cada pixel da tela, o Z-buffer guarda a menor distância (Z) já encontrada até a câmera; um novo fragmento só é pintado se o seu Z for menor que o valor já guardado naquele pixel — daí "teste de profundidade". É por isso que esferas se interpenetram corretamente mesmo vindo de objetos distintos desenhados em qualquer ordem. À direita, o próprio buffer de profundidade é visualizado em escala de cinza: quanto mais claro, mais perto da câmera; quanto mais escuro, mais longe (o azul de fundo marca pixels sem interseção, fora de qualquer esfera).
O algoritmo, passo a passo

Antes de renderizar, todo pixel do buffer de profundidade começa em "infinito" (nada foi desenhado ainda). Ao rasterizar cada objeto, para cada pixel que ele cobre calcula-se o seu Z naquele ponto e compara-se com o Z já armazenado: se o novo Z for menor (mais perto), o buffer de cor e o buffer de profundidade são atualizados; se for maior (mais longe), o fragmento é descartado — o objeto está atrás de algo que já foi desenhado ali. No fim, cada pixel guarda o objeto mais próximo, não importa a ordem em que os objetos chegaram à GPU.

Sem teste de profundidade: o problema

Clique em "Sem teste de profundidade" e gire a cena: cada esfera passa a ser desenhada por cima de tudo que veio antes dela na lista, mesmo quando está mais longe da câmera — o índice em um array vira "prioridade" no lugar da distância real. Repare que o buffer de profundidade também fica com saltos e recortes onde antes havia curvas suaves: sem comparação por pixel, nada garante consistência entre cor e distância. É o mesmo defeito do algoritmo do pintor (ordenar objetos inteiros do mais distante ao mais próximo, como na Seção de Iluminação): funciona bem para formas convexas isoladas, mas quebra assim que os objetos se interpenetram ou formam ciclos de oclusão (A na frente de B, B na frente de C, C na frente de A).

Custo e variações

O Z-buffer gasta memória extra: um valor de profundidade (tipicamente 16, 24 ou 32 bits) por pixel, além da cor. Em troca, dispensa qualquer ordenação prévia dos objetos — cada triângulo pode ser desenhado em paralelo, em qualquer sequência, o que combina perfeitamente com o processamento massivamente paralelo das GPUs. Variações comuns incluem o early-Z (descartar o fragmento antes até de calcular sua cor, economizando shading) e o Z-buffer invertido (guardar 1/Z em vez de Z), usado para distribuir melhor a precisão entre objetos próximos e distantes.

Onde isso é usado?

Todo pipeline gráfico de tempo real — jogos, engines como Unity e Unreal, e a própria composição de janelas do sistema operacional — resolve visibilidade com Z-buffer em hardware dedicado da GPU. É a alternativa direta ao ray tracing (que resolve visibilidade por raio, testando interseções para cada pixel individualmente, como a própria cena acima) e ao algoritmo do pintor (que depende de ordenar objetos inteiros e falha em cenas com interpenetração).

Sistema de Partículas — Fogo, Fumaça e Explosões

4
0
260
Clique em qualquer ponto da tela para detonar uma explosão. 0 partículas ativas.
Um sistema de partículas não simula fluido nenhum de verdade — ele só gerencia centenas de pontos independentes e simples (posição, velocidade, tempo de vida, cor, tamanho), atualizados a cada quadro por um punhado de forças (empuxo, vento, gravidade, arrasto) e desenhados como pequenos brilhos semitransparentes que se sobrepõem. A ilusão de fogo, fumaça ou uma explosão surge inteiramente da quantidade e da composição visual, não de física real — é a técnica clássica de efeitos visuais em jogos desde os anos 1980 (a primeira aplicação documentada foi a "Genesis Wave" em Star Trek II, de 1982).
Anatomia de uma partícula

Cada partícula guarda apenas um punhado de números: posição (x, y), velocidade (vx, vy), idade e tempo de vida máximo, tamanho inicial/final e a que "espécie" pertence (fogo, faísca ou fumaça). A cada quadro, forças são somadas à velocidade (v += a·dt) e a velocidade é somada à posição (x += v·dt) — o mesmo integrador simples usado em qualquer simulação física discreta. Quando a idade ultrapassa o tempo de vida, a partícula simplesmente é removida do array.

Interpolação ao longo da vida

Cor, tamanho e opacidade não são fixos: todos variam com t = idade / vidaMáxima, indo de 0 (nascimento) a 1 (morte). O fogo percorre uma rampa de cor branco → amarelo → laranja → vermelho → marrom escuro (quanto mais alta a temperatura simulada, mais para o branco/azul — por isso a base da chama é mais clara que a ponta). A fumaça faz o oposto: nasce quase invisível, ganha opacidade e tamanho no início, e dissolve lentamente enquanto se expande — simulando a difusão do gás no ar.

Mistura aditiva vs. normal

Fogo e faíscas usam globalCompositeOperation = "lighter": em vez de a cor de cima substituir a de baixo, as cores são somadas — por isso onde muitas chamas se sobrepõem o resultado estoura para branco, como luz de verdade se acumulando. Desative o glow no checkbox para ver a diferença: sem mistura aditiva, as partículas sobrepostas apenas escurecem umas às outras (blend normal), perdendo a sensação de incandescência. Fumaça nunca usa aditivo — fumaça bloqueia luz, não emite luz, então usa mistura normal (source-over) com opacidade baixa.

A explosão: três emissores de uma vez

Clicar na tela dispara três populações de partículas simultaneamente a partir do mesmo ponto: faíscas (rápidas, pequenas, sofrem gravidade e caem em arco), uma bola de fogo central (partículas grandes e de vida curtíssima, empurradas para fora em todas as direções) e uma pluma de fumaça que só aparece depois de um pequeno atraso — o mesmo atraso que você vê em vídeos reais de explosão, onde a fumaça sobe só depois que o clarão inicial já esfriou. Um anel de onda de choque (strokeStyle se expandindo e desvanecendo) reforça a leitura de impacto.

Onde isso é usado?

Motores de jogos (Unity, Unreal, Godot) e ferramentas de efeitos visuais para cinema (Houdini, Blender) têm sistemas de partículas dedicados exatamente com esses parâmetros — taxa de emissão, forças, curvas de cor/tamanho ao longo do tempo — muitas vezes acelerados por GPU para simular milhões de partículas por quadro (chuva, fumaça, magia, destroços). O princípio é o mesmo usado aqui: nenhuma partícula individual precisa ser realista, só o comportamento coletivo do sistema.

Editor de Imagem — Transformações e Filtros

0
0
0°
1.00x
0.00
100%
100%
100%
0°
0px
Carregue uma imagem (clique em Carregar imagem ou arraste um arquivo sobre o quadro) para começar. As transformações e filtros são aplicados em tempo real; o resultado pode ser baixado como PNG a qualquer momento.
Esta seção junta os dois temas anteriores — transformações geométricas (Seção 2) e filtros de convolução (Seção 14) — e os aplica sobre uma imagem de verdade, escolhida por você. Internamente, cada transformação geométrica ainda é a mesma composição de matrizes 2×3 usada pelo canvas.getContext('2d') (translação, rotação, escala e cisalhamento), enquanto os filtros de cor usam a propriedade ctx.filter, que aplica os mesmos filtros CSS (brightness, contrast, saturate, grayscale, blur etc.) diretamente aos pixels desenhados no canvas — sem precisar percorrer manualmente cada pixel com getImageData.
Ordem das transformações

Assim como na Seção 2, a ordem importa: aqui aplicamos escala → espelhamento → cisalhamento → rotação → translação. Trocar a ordem produz resultados visualmente diferentes, porque cada matriz é aplicada no referencial deixado pela anterior — é por isso que engines gráficas sempre documentam explicitamente a ordem de composição das suas transformações.

Filtros como funções por pixel

Brilho e contraste são funções lineares aplicadas a cada canal de cor (R, G, B) independentemente; saturação e matiz (hue) primeiro convertem a cor para o espaço HSL, ajustam o componente relevante, e convertem de volta para RGB; já o desfoque (blur) é, por trás dos panos, uma convolução gaussiana — o mesmo princípio da Seção 14, só que com um kernel muito maior e gerado automaticamente a partir do raio escolhido.

Exportando o resultado

O botão de download chama canvas.toDataURL('image/png'), que serializa todo o conteúdo atual do canvas — já com transformações e filtros aplicados — em uma string Base64 no formato PNG, usada para gerar um link de download temporário. Nada disso passa por um servidor: a imagem carregada, editada e exportada nunca sai do seu navegador.