Anti-alias / Filtering in Ray Tracing


20

Nel ray tracing / path tracing, uno dei modi più semplici per anti-alias l'immagine è quello di sostituire i valori dei pixel e fare una media dei risultati. IE. invece di sparare ad ogni campione attraverso il centro del pixel, compensi i campioni di una certa quantità.

Nella ricerca su Internet, ho trovato due metodi leggermente diversi per farlo:

  1. Generare i campioni come desiderato e pesare il risultato con un filtro
    • Un esempio è PBRT
  2. Genera i campioni con una distribuzione uguale alla forma di un filtro


Genera e pesa

Il processo di base è:

  1. Crea campioni come preferisci (sequenze casuali, stratificate, a bassa discrepanza, ecc.)
  2. Offset il raggio della videocamera usando due campioni (xey)
  3. Rendi la scena con il raggio
  4. Calcola un peso utilizzando una funzione di filtro e la distanza del campione in riferimento al centro del pixel. Ad esempio, Box Filter, Filter Tent, Gaussian Filter, ecc.) Forme di filtro
  5. Applica il peso al colore dal rendering


Genera sotto forma di un filtro

La premessa di base è di utilizzare il campionamento per trasformazioni inverse per creare campioni distribuiti in base alla forma di un filtro. Ad esempio un istogramma di un campione distribuito a forma di gaussiano sarebbe:
Istogramma gaussiano

Questo può essere fatto esattamente, oppure inserendo la funzione in un pdf / cdf discreto. smallpt utilizza l'esatto cdf inverso di un filtro tenda. Esempi di metodo di binning sono disponibili qui


Domande

Quali sono i pro e i contro di ciascun metodo? E perché dovresti usarne uno sopra l'altro? Posso pensare ad alcune cose:

Generate and Weigh sembra essere il più robusto, consentendo qualsiasi combinazione di qualsiasi metodo di campionamento con qualsiasi filtro. Tuttavia, è necessario tenere traccia dei pesi in ImageBuffer e quindi eseguire una risoluzione finale.

Genera nella forma di un filtro può supportare solo forme di filtro positive (es. No Mitchell, Catmull Rom o Lanczos), dal momento che non puoi avere un pdf negativo. Ma, come accennato in precedenza, è più facile da implementare, poiché non è necessario tenere traccia dei pesi.

Tuttavia, alla fine, immagino che tu possa pensare al metodo 2 come a una semplificazione del metodo 1, poiché utilizza essenzialmente un peso implicito del filtro box.


Solo pensando ad alta voce ... Potresti modellare la parte negativa di un filtro separatamente per generare due serie di campioni, uno da trattare come positivo e l'altro come negativo? Ciò consentirebbe filtri arbitrari per il tuo secondo approccio (generare nella forma di un filtro)?
trichoplax,

Può essere? Fammi giocherellare per un po '
RichieSams

1
Ok, se segui gli zeri della funzione, puoi abs () l'output nel pdf. Quindi, durante il campionamento, puoi verificare se sei negativo. Codice di esempio qui: gist.github.com/RichieSams/aa7e71a0fb4720c8cb41
RichieSams

Risposte:


9

C'è un ottimo documento del 2006 su questo argomento, Filter Importance Sampling . Propongono il tuo metodo 2, studiano le proprietà e ne escono generalmente a favore. Sostengono che questo metodo fornisce risultati di rendering più fluidi perché pondera tutti i campioni che contribuiscono allo stesso modo a un pixel, riducendo in tal modo la varianza dei valori finali del pixel. Questo ha un senso, dato che è una massima generale a Monte Carlo, secondo cui il campionamento per importanza darà una varianza inferiore rispetto ai campioni ponderati.

Il metodo 2 ha anche il vantaggio di essere leggermente più semplice da parallelizzare perché i calcoli di ciascun pixel sono indipendenti da tutti gli altri pixel, mentre nel metodo 1, i risultati del campione sono condivisi tra pixel vicini (e quindi devono essere sincronizzati / comunicati in qualche modo quando i pixel sono parallelizzati attraverso processori multipli). Per lo stesso motivo, è più semplice eseguire il campionamento adattivo (più campioni nelle aree ad alta varianza dell'immagine) con il metodo 2 rispetto al metodo 1.

Nel documento, hanno anche sperimentato un filtro Mitchell, campionando da abs () del filtro e quindi ponderando ogni campione con +1 o −1, come suggerito da @trichoplax. Ma questo ha effettivamente aumentato la varianza ed è peggiore del metodo 1, quindi concludono che il metodo 2 è utilizzabile solo per filtri positivi.

Detto questo, i risultati di questo documento potrebbero non essere universalmente applicabili e potrebbe essere in qualche modo dipendente dalla scena quale metodo di campionamento sia migliore. Ho scritto un post sul blog indagando su questa domandaindipendentemente nel 2014, usando una "funzione immagine" sintetica piuttosto che il rendering completo, e ho trovato il metodo 1 per dare risultati visivamente più piacevoli grazie alla levigatura più precisa dei bordi ad alto contrasto. Benedikt Bitterli ha anche commentato quel post riportando un problema simile con il suo renderer (rumore ad alta frequenza in eccesso attorno alle sorgenti luminose quando si utilizza il metodo 2). Oltre a ciò, ho scoperto che la differenza principale tra i metodi era la frequenza del rumore risultante: il metodo 2 produce rumore a "pixel" ad alta frequenza, mentre il metodo 1 dà "grani" di rumore di 2-3 pixel di diametro, ma l'ampiezza del rumore era simile per entrambi, quindi quale tipo di rumore sembra meno cattivo è probabilmente una questione di preferenza personale.


Grazie! Queste sono grandi risorse. Quindi, alla fine, ci sono 3 metodi? 1. Genera e pesa con lo splatting 2. Genera e pesa senza lo splatting 3. Genera nella forma di un filtro
RichieSams

Conoscete documenti, blog, ecc. Che esplorano come parallelizzare Genera e Peso con lo splatting? Dalla parte superiore della mia testa, potresti avere un mutex per piastrella o rendere atomico ogni pixel.
RichieSams,

2
@RichieSams Non so perché dovresti usare "generare e pesare senza splattare", in realtà - sembra che sarebbe comunque peggio del campionamento di importanza del filtro. Supponevo che "generare e pesare" implichi lo splatting. Per quanto riguarda la parallelizzazione dello splatting, dalla parte superiore della mia testa, un modo sarebbe quello di dividere l'immagine in tessere, ma dare a ogni tessera un bordo di 2‒3 pixel per catturare simboli che attraversano il bordo della tessera. Quindi, in un passaggio finale, componi in modo additivo le tessere delimitate insieme nell'immagine finale.
Nathan Reed
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.