Funções de Distância Assinada (SDFs)

Visão geral

Uma função de distância assinada (SDF, signed distance function) é uma representação implícita de uma forma ou cena 3D. Em vez de armazenar a geometria como vértices e faces (uma malha) ou como voxels ocupados, uma SDF armazena um campo escalar:

[ f:\mathbb{R}^3 \rightarrow \mathbb{R} ]

com a interpretação principal:

  • Superfície (conjunto de nível zero): o contorno da forma é o conjunto de pontos onde
    [ f(\mathbf{x}) = 0 ]
  • Sinal (interior vs. exterior): o sinal de (f(\mathbf{x})) indica se (\mathbf{x}) está dentro ou fora da forma (a convenção pode variar; comumente (f<0) dentro, (f>0) fora).
  • Magnitude (distância): (|f(\mathbf{x})|) é igual à distância Euclidiana de (\mathbf{x}) ao ponto mais próximo na superfície — quando (f) é uma função de distância verdadeira.

SDFs são amplamente usadas em visão 3D e computação gráfica porque fornecem:

  • Uma representação contínua (consulta em qualquer ponto 3D).
  • Extração fácil de superfície (encontrar onde (f=0)).
  • Derivadas úteis (normais de superfície via gradientes).
  • Interseção eficiente raio–superfície por meio de sphere tracing.
  • Um encaixe natural para representações neurais implícitas (implicit neural representations) e renderização diferenciável/neural (differentiable/neural rendering).

Isso faz das SDFs uma ponte entre pipelines clássicos de geometria e métodos modernos de reconstrução 3D baseados em aprendizado.

SDFs como superfícies implícitas

Uma SDF pertence a uma categoria mais ampla de funções implícitas, em que uma superfície é definida por um conjunto de nível:

[ \mathcal{S} = {\mathbf{x} \in \mathbb{R}^3 \mid f(\mathbf{x}) = 0} ]

Nem toda função implícita é uma SDF. A parte “distância” implica estrutura adicional (notavelmente uma restrição na magnitude do gradiente descrita abaixo). Na prática, você verá vários campos relacionados:

  • SDF (função de distância assinada): (|f(\mathbf{x})|) é a distância verdadeira até a superfície.
  • Campo de distância assinada (signed distance field): uma amostragem discretizada de uma SDF em uma grade (voxels).
  • TSDF (função de distância assinada truncada, truncated signed distance function): as distâncias são limitadas a ([-\tau, \tau]) por eficiência/robustez (comum em sistemas de fusão de profundidade).
  • Campo de ocupação (occupancy field): prevê a probabilidade de estar dentro/fora em vez da distância.

Propriedades matemáticas-chave

1) Interpretação de distância ao ponto mais próximo e continuidade de Lipschitz

Se (f) é uma SDF verdadeira, então (fora de pontos ambíguos) ela satisfaz:

  • Propriedade 1-Lipschitz
    [ |f(\mathbf{x}) - f(\mathbf{y})| \le |\mathbf{x} - \mathbf{y}| ] Intuitivamente: a função não pode mudar mais rápido do que a distância no espaço.

Essa propriedade é importante para ray marching seguro (sphere tracing): ela garante que você pode avançar em (f(\mathbf{x})) sem cruzar a superfície.

2) A equação de Eikonal \(\|\nabla f\| = 1\)

Uma SDF perfeita satisfaz a equação de Eikonal (Eikonal equation) quase em toda parte:

[ |\nabla f(\mathbf{x})| = 1 ]

Exceções ocorrem em pontos onde o ponto de superfície mais próximo não é único (por exemplo, ao longo do eixo medial, arestas/cantos vivos), onde (f) pode não ser diferenciável.

Em SDFs baseadas em aprendizado, impor (|\nabla f|\approx 1) (a “perda de Eikonal”) é um regularizador padrão para manter o campo com comportamento “tipo distância”.

3) Normais de superfície a partir de gradientes

Para uma superfície implícita (f(\mathbf{x})=0), o gradiente aponta na direção de maior aumento de (f) e é ortogonal ao conjunto de nível. Assim, a normal de superfície é:

[ \mathbf{n}(\mathbf{x}) = \frac{\nabla f(\mathbf{x})}{|\nabla f(\mathbf{x})|} \quad \text{(avaliada em } f(\mathbf{x})=0\text{)} ]

Essa é uma das maiores vantagens práticas das SDFs: as normais vêm “de graça” se você consegue calcular gradientes (analiticamente, via diferenciação automática em SDFs neurais, ou via diferenças finitas em grades).

4) Geometria Sólida Construtiva (CSG) com min/max

SDFs suportam composição simples de formas:

  • União: (f_{\cup}(\mathbf{x}) = \min(f_1(\mathbf{x}), f_2(\mathbf{x})))
  • Interseção: (f_{\cap}(\mathbf{x}) = \max(f_1(\mathbf{x}), f_2(\mathbf{x})))
  • Diferença: (f_{\setminus}(\mathbf{x}) = \max(f_1(\mathbf{x}), -f_2(\mathbf{x})))

Essas operações preservam o conjunto de nível zero (embora o resultado possa perder a propriedade estrita de “distância verdadeira” a menos que seja reinicializado).

Exemplos práticos de SDFs

SDFs analíticas para primitivas

Muitas formas básicas têm SDFs em forma fechada. Por exemplo, uma esfera centrada em (\mathbf{c}) com raio (r):

[ f(\mathbf{x}) = |\mathbf{x}-\mathbf{c}| - r ]

Um plano com normal unitária (\mathbf{n}) e offset (d) (equação do plano (\mathbf{n}\cdot\mathbf{x} + d = 0)):

[ f(\mathbf{x}) = \mathbf{n}\cdot\mathbf{x} + d ]

Essas SDFs analíticas são comuns em modelagem procedural e como blocos de construção para cenas mais complexas (via CSG).

Um exemplo mínimo de sphere tracing (interseção raio–SDF)

Sphere tracing (uma forma de ray marching) usa o valor da SDF como um tamanho de passo conservador em direção à superfície.

import numpy as np

def sphere_trace(ray_o, ray_d, sdf, t_max=100.0, eps=1e-4, max_steps=256):
    """
    ray_o: (3,) origin
    ray_d: (3,) direction (assumed normalized)
    sdf: callable f(x)->signed distance
    Returns: (hit, t, x)
    """
    t = 0.0
    for _ in range(max_steps):
        x = ray_o + t * ray_d
        d = sdf(x)
        if abs(d) < eps:
            return True, t, x
        t += d  # safe if sdf is a true SDF (or conservative underestimate)
        if t > t_max:
            break
    return False, t, ray_o + t * ray_d

Para sombrear o ponto de acerto, estime a normal por um gradiente. Em uma SDF não neural, você pode usar diferenças finitas:

def estimate_normal(x, sdf, h=1e-3):
    dx = np.array([h, 0, 0])
    dy = np.array([0, h, 0])
    dz = np.array([0, 0, h])
    g = np.array([
        sdf(x + dx) - sdf(x - dx),
        sdf(x + dy) - sdf(x - dy),
        sdf(x + dz) - sdf(x - dz),
    ]) / (2*h)
    return g / (np.linalg.norm(g) + 1e-12)

Importante: o sphere tracing assume que a SDF não superestima o quão longe você está da superfície. Se o seu campo não for uma SDF verdadeira (comum em campos aprendidos), você pode precisar de passos menores, line search, ou busca de raiz (root-finding) assim que uma mudança de sinal estiver delimitada.

Conversões: SDFs, malhas e voxels

SDFs não substituem malhas e voxels; elas fazem parte de um conjunto de ferramentas. Sistemas reais frequentemente convertem entre elas.

SDF → malha (extração de superfície)

Para obter uma malha poligonal, amostre (f) em uma grade 3D e extraia a isosuperfície de nível zero:

  • Marching Cubes: o método clássico; robusto e amplamente usado.
  • Dual Contouring: pode preservar melhor características agudas ao usar dados de Hermite (valores + gradientes).

Fluxo de trabalho:

  1. Escolha uma bounding box e a resolução da grade.
  2. Avalie (f) nos vértices da grade.
  3. Execute Marching Cubes no campo escalar.
  4. Opcionalmente refine (por exemplo, projetar vértices em direção a (f=0), calcular normais a partir de (\nabla f)).

Isso é comum em pipelines de SDF neural: o modelo é contínuo, mas você exporta uma malha para uso posterior.

Malha → SDF (cálculo de distância + dentro/fora)

Converter uma malha para uma SDF tipicamente envolve:

  1. Calcular a distância não assinada (unsigned distance) até a malha (distância ao triângulo mais próximo; acelerado com BVH/k-d tree).
  2. Determinar o sinal (dentro/fora), usando métodos como:
    • Número de enrolamento (winding number) (robusto para malhas não estanques em muitos casos),
    • Paridade por lançamento de raios (ray casting parity) (interseções ímpar/par; pode ser frágil),
    • Preenchimento por inundação (flood fill) em uma grade de voxels se se assume um contorno estanque.

Essa conversão é usada para:

  • Criar dados de treinamento para SDFs neurais,
  • Habilitar campos de colisão em simulação/robótica,
  • Executar operações volumétricas (morfologia, suavização) em uma forma.

TSDFs e fusão de profundidade (voxels + distâncias truncadas)

Uma TSDF armazena distâncias assinadas, mas as limita a uma banda de truncamento ([-\tau, \tau]). TSDFs são populares em pipelines de reconstrução RGB-D (por exemplo, sistemas no estilo KinectFusion):

  • Cada imagem de profundidade define um conjunto de pontos de superfície observados ao longo de raios da câmera.
  • Para cada voxel perto da superfície observada, integre uma estimativa de distância assinada.
  • Faça a média das estimativas ao longo do tempo com pesos.

A fusão de TSDF é eficaz porque:

  • Suaviza o ruído do sensor,
  • É incremental e previsível em memória,
  • Produz uma superfície coerente que pode ser extraída com Marching Cubes.

Sistemas modernos baseados em aprendizado ainda podem usar TSDFs como entradas, priors ou inicialização para otimização.

SDFs em renderização diferenciável e neural

SDFs desempenham um papel central em renderização diferenciável (differentiable rendering) e reconstrução neural, especialmente quando você quer gradientes de perdas de imagem de volta para parâmetros de geometria. Isso se relaciona de perto com Renderização Diferenciável, Representações Neurais Implícitas e Renderização Neural.

SDFs neurais (representações neurais implícitas de geometria)

Uma SDF neural (neural SDF) representa (f(\mathbf{x})) com uma rede neural (geralmente uma MLP), muitas vezes com codificação posicional:

[ f_\theta(\mathbf{x}) \approx \text{SDF}(\mathbf{x}) ]

Os sinais de treinamento variam conforme a tarefa/dados:

  • A partir de nuvens de pontos: impor (f_\theta(\mathbf{x}_i)=0) em amostras na superfície, além de regularização.
  • A partir de pontos orientados (normais): alinhar (\nabla f_\theta(\mathbf{x}_i)) com normais conhecidas.
  • A partir de rótulos de ocupação: incentivar consistência de sinal (dentro/fora).
  • A partir de imagens: renderizar e corresponder pixels (silhuetas, profundidade, cor), retropropagando através do processo de renderização.

Um regularizador comum é a perda de Eikonal (Eikonal loss): [ \mathcal{L}{eik} = \mathbb{E}{\mathbf{x}}\left(|\nabla f_\theta(\mathbf{x})| - 1\right)^2 ] que incentiva comportamento tipo distância e estabiliza o sphere tracing e o cálculo de normais.

Famílias bem conhecidas de SDFs neurais incluem métodos no espírito de DeepSDF/SAL e renderizadores mais recentes que combinam geometria por SDF com aparência volumétrica.

Renderização diferenciável com geometria por SDF

Há duas estratégias comuns para renderizar uma SDF de forma diferenciável:

1) Interseção de superfície diferenciável + sombreamento

Você pode definir o pixel renderizado por:

  1. Interseção raio–superfície: encontrar (t^) tal que (f(\mathbf{o}+t^\mathbf{d})=0)
  2. Calcular a normal (\nabla f) no ponto de interseção
  3. Sombrear (Lambertiano/Phong/BRDF aprendida)

Tornar isso diferenciável é complicado porque a interseção envolve procedimentos iterativos (sphere tracing/busca de raiz). Abordagens práticas:

  • Diferenciar através das iterações (possível, mas pode ser instável),
  • Usar diferenciação implícita ao redor da raiz,
  • Usar aproximações “suaves” para a interseção.

Essa abordagem é conceitualmente limpa e produz superfícies nítidas, mas pode ser sensível à inicialização e à qualidade da SDF.

2) Converter SDF em uma densidade volumétrica para renderização volumétrica diferenciável

Muitos métodos modernos “suavizam” a superfície convertendo valores da SDF em uma densidade (density) (\sigma(\mathbf{x})) adequada para renderização volumétrica (semelhante em espírito ao NeRF). Uma ideia comum:

  • Pontos perto da superfície (onde (f\approx 0)) recebem alta densidade,
  • Pontos longe recebem baixa densidade.

Então renderize integrando ao longo do raio com renderização volumétrica diferenciável padrão, permitindo gradientes robustos mesmo quando a geometria ainda está grosseira.

Essa abordagem híbrida é popular porque combina:

  • Viés geométrico da SDF (superfície bem definida, normais),
  • Paisagem de otimização suave da renderização volumétrica.

Pipelines de reconstrução (imagens multi-view → SDF)

Em reconstrução multi-view, você tipicamente:

  1. Conhece ou estima parâmetros de câmera (ver Calibração de Câmera e Estimativa de Pose).
  2. Possivelmente refina poses conjuntamente com a geometria via otimização no estilo Bundle Adjustment.
  3. Otimiza parâmetros da SDF (\theta) (e frequentemente parâmetros de aparência) para minimizar perdas fotométricas/de silhueta/de profundidade através das vistas.

A reconstrução baseada em SDF é especialmente atraente quando você quer:

  • Superfícies estanques,
  • Boas normais,
  • Geometria compacta e contínua.

Pontos fortes e limitações

Pontos fortes

  • Consultas contínuas, sem dependência de resolução (diferente de grades de voxels fixas).
  • Cálculo fácil de normais via gradientes.
  • Interseção eficiente com sphere tracing (quando “tipo SDF”).
  • Forte prior geométrico no aprendizado (incentiva superfícies coerentes).
  • Modelagem composicional via operações CSG.

Limitações e armadilhas comuns

  • Nem sempre é um campo de distância verdadeiro: SDFs aprendidas podem violar (|\nabla f|=1), quebrando garantias do sphere tracing e produzindo normais enviesadas.
  • Ambiguidade de sinal: “dentro/fora” é fácil para objetos fechados, mais difícil para superfícies abertas ou cenas sem estanqueidade.
  • Estruturas finas: vãos estreitos ou superfícies muito finas podem ser difíceis de representar ou amostrar sem alta resolução.
  • Artefatos de extração: a qualidade do marching cubes depende da resolução de amostragem; detalhes finos podem se perder.
  • Cenas grandes: SDFs globais podem ser caras; sistemas práticos usam aceleração (octrees, hash grids, particionamento espacial).

Orientações práticas

  • Use uma estrutura de aceleração (grade, octree, BVH, hash grid) se você precisa de consultas rápidas ou cálculos de distância até malhas.
  • Se você depende de sphere tracing, garanta que seu campo seja uma SDF verdadeira ou uma subestimativa conservadora; caso contrário use passos menores e busca de raiz com delimitação.
  • Para SDFs neurais, inclua regularização de Eikonal e amostre pontos tanto perto quanto longe da superfície.
  • Para gerar malha, escolha a resolução da grade com base no menor tamanho de característica e considere pós-processamento (projeção para (f=0), suavização, dizimação).
  • Para fusão de sensores, o truncamento da TSDF melhora a robustez; escolha o truncamento (\tau) com base no ruído de profundidade e no tamanho do voxel.

Relação com outras representações 3D

Dentro da visão 3D moderna, SDFs são uma de várias representações principais:

  • Malhas: explícitas, eficientes para renderização, mas mais difíceis de otimizar diretamente e podem mudar topologia.
  • Voxels/TSDFs: diretos e robustos, mas exigem muita memória em alta resolução.
  • Campos de radiância (por exemplo, no estilo NeRF): modelam aparência e densidade; fortes para síntese de novas vistas, mas a geometria pode ser menos explícita a menos que seja restringida.
  • Gaussianas 3D: representação explícita baseada em pontos otimizada para renderização rápida (ver Splatting de Gaussianas 3D).

SDFs são frequentemente escolhidas quando qualidade de superfície e entendimento geométrico importam (normais, malhas estanques, campos de colisão), e são cada vez mais combinadas com técnicas de renderização neural para reconstrução fotorrealista.

Resumo

Funções de distância assinada representam geometria 3D de forma implícita com um campo escalar cujo conjunto de nível zero define a superfície e cujo sinal indica dentro/fora. SDFs verdadeiras satisfazem propriedades geométricas úteis — especialmente (|\nabla f|=1) — permitindo normais a partir de gradientes e interseção eficiente raio–superfície via sphere tracing. SDFs convertem naturalmente de/para malhas e campos de voxels (incluindo TSDFs) e se tornaram fundamentais em reconstrução implícita neural (neural implicit reconstruction) e renderização diferenciável/neural, onde a geometria por SDF é otimizada a partir de imagens, profundidade ou nuvens de pontos com aprendizado baseado em gradientes.