Composição de SDF 2D
Montar uma forma com distâncias com sinal combinadas por min, max e min suave e desenhar preenchimento, contorno e sombra a partir do resultado.
Cards
Um exemplo ao vivo para ajustar, aprender e copiar.
Como funciona
Um campo de distância com sinalUma função que devolve a distância de um ponto até a borda de uma forma, negativa dentro e positiva fora. O zero é o próprio contorno. Campo de distância com sinal (SDF) Uma função que devolve a distância de um ponto até a borda de uma forma, negativa dentro e positiva fora. O zero é o próprio contorno. Mínimo suave Uma versão do min que arredonda o canto onde dois valores se cruzam. Aplicado a dois campos de distância, funde as formas numa só, com a largura da fusão definida por k.circle(p) = |p| − r descreve uma forma com um número por ponto: a distância até a
borda, negativa por dentro. O que interessa é que distâncias se combinam. O min de dois campos é as duas formas ao
mesmo tempo (uma união), o max é só onde elas se sobrepõem (uma interseção) e max(a, -b) é a primeira forma com a
segunda recortada dela (uma subtração). Um mínimo suaveUma versão do min que arredonda o canto onde dois valores se cruzam. Aplicado a dois campos de distância, funde as formas numa só, com a largura da fusão definida por k.h = clamp(0.5 + 0.5 (b − a) / k, 0, 1); smin = mix(b, a, h) − k h (1 − h)
Assim, uma forma complexa não precisa de fórmula própria. Um retângulo arredondado é uma caixa cuja distância foi encolhida e depois crescida de volta; uma seta é a união de dois segmentos de reta; um anel é um disco menos um disco menor. O resultado continua sendo um campo de distância, então o passo seguinte pode usá-lo do mesmo jeito.
É por isso que vale aprender a compor. Uma distância dá vários visuais de graça: o preenchimento (abaixo de zero), um
contorno (perto de zero dos dois lados), um brilho ou uma sombra projetada suave (um smoothstep largo do lado de fora),
cada um uma borda recortada do mesmo número. E, como a borda sai de uma distância, ela pode ser suavizada com precisão,
com um pixel de largura em qualquer tamanho, usando a derivada em espaço de tela fwidth. Elementos de interface,
ícones, marcadores de mapa e glifos de fonte são desenhados assim quando precisam continuar nítidos em qualquer zoom.
Leitura complementar
- dFdx, dFdy (abre em uma nova aba)Referência
- fwidth (abre em uma nova aba)Referência
- Filterable procedurals (abre em uma nova aba)Artigo
- 2D distance functions (abre em uma nova aba)Artigo
- Signed distance function (abre em uma nova aba)Referência
- Shapes (abre em uma nova aba)Livro
- Smooth minimum (abre em uma nova aba)Artigo
- Distance functions (abre em uma nova aba)Artigo
- Distance functions (abre em uma nova aba)Artigo
- Improved alpha-tested magnification for vector textures and special effects (abre em uma nova aba)Paper
- CanvasItem shaders (abre em uma nova aba)Documentação