Anti-aliasing / Filtrado en trazado de rayos

20

En el trazado de rayos / trazado de ruta, una de las formas más sencillas de suavizar la imagen es supermuestrear los valores de píxeles y promediar los resultados. ES DECIR. en lugar de tomar cada muestra a través del centro del píxel, compensa las muestras en cierta cantidad.

Al buscar en Internet, he encontrado dos métodos algo diferentes para hacer esto:

  1. Genere muestras como desee y pese el resultado con un filtro
    • Un ejemplo es PBRT
  2. Genere las muestras con una distribución igual a la forma de un filtro.


Generar y pesar

El proceso básico es:

  1. Cree muestras como desee (secuencias aleatorias, estratificadas, de baja discrepancia, etc.)
  2. Compense el rayo de la cámara con dos muestras (x e y)
  3. Renderiza la escena con el rayo
  4. Calcule un peso utilizando una función de filtro y la distancia de la muestra en referencia al centro de píxeles. Por ejemplo, filtro de caja, filtro de tienda, filtro gaussiano, etc.) Formas de filtro
  5. Aplica el peso al color del render


Generar en forma de filtro

La premisa básica es utilizar el muestreo de transformación inversa para crear muestras que se distribuyen de acuerdo con la forma de un filtro. Por ejemplo, un histograma de muestras distribuidas en forma de gaussiano sería:
Histograma Gaussiano

Esto puede hacerse exactamente, o agrupando la función en un discreto pdf / cdf. smallpt usa el cdf inverso exacto de un filtro de tienda. Aquí se pueden encontrar ejemplos de métodos de agrupamiento


Preguntas

¿Cuáles son los pros y los contras de cada método? ¿Y por qué usarías uno sobre el otro? Se me ocurren algunas cosas:

Generar y pesar parece ser el más robusto, permitiendo cualquier combinación de cualquier método de muestreo con cualquier filtro. Sin embargo, requiere que rastree los pesos en ImageBuffer y luego haga una resolución final.

Generar en forma de filtro solo puede admitir formas de filtro positivas (es decir, sin Mitchell, Catmull Rom o Lanczos), ya que no puede tener un pdf negativo. Pero, como se mencionó anteriormente, es más fácil de implementar, ya que no necesita rastrear ningún peso.

Aunque, al final, supongo que puede pensar en el método 2 como una simplificación del método 1, ya que esencialmente está usando un peso de filtro de caja implícito.

RichieSams
fuente
Solo pensando en voz alta ... ¿Podría modelar la parte negativa de un filtro por separado para generar dos conjuntos de muestras, una para ser tratada como positiva y la otra como negativa? ¿Esto permitiría filtros arbitrarios para su segundo enfoque (generar en forma de filtro)?
trichoplax
¿Tal vez?
Déjame jugar
1
Ok, si rastreas los ceros de la función, puedes abs () la salida en el pdf. Luego, al tomar muestras, puede verificar si es negativo. Código de muestra aquí: gist.github.com/RichieSams/aa7e71a0fb4720c8cb41
RichieSams

Respuestas:

9

Hay un gran artículo de 2006 sobre este tema, Filter Importance Sampling . Proponen su método 2, estudian las propiedades y generalmente se muestran a favor de él. Afirman que este método proporciona resultados de representación más suaves porque pondera todas las muestras que contribuyen a un píxel por igual, reduciendo así la variación en los valores finales de píxel. Esto tiene sentido, ya que es una máxima general en Monte Carlo que hace que el muestreo de importancia dé una varianza menor que las muestras ponderadas.

El método 2 también tiene la ventaja de ser un poco más fácil de paralelizar porque los cálculos de cada píxel son independientes de todos los demás píxeles, mientras que en el método 1, los resultados de la muestra se comparten entre los píxeles vecinos (y, por lo tanto, deben sincronizarse / comunicarse de alguna manera cuando los píxeles están paralelos) múltiples procesadores). Por la misma razón, es más fácil hacer un muestreo adaptativo (más muestras en áreas de alta varianza de la imagen) con el método 2 que con el método 1.

En el documento, también experimentaron con un filtro Mitchell, tomando muestras de abs () del filtro y luego ponderando cada muestra con +1 o −1, como sugirió @trichoplax. Pero esto terminó aumentando la varianza y siendo peor que el método 1, por lo que concluyen que el método 2 solo se puede usar para filtros positivos.

Dicho esto, los resultados de este documento pueden no ser de aplicación universal, y puede ser algo dependiente de la escena qué método de muestreo es mejor. Escribí una publicación de blog investigando esta preguntaindependientemente en 2014, utilizando una "función de imagen" sintética en lugar de un renderizado completo, y descubrió que el método 1 brinda resultados visualmente más agradables debido a que suaviza los bordes de alto contraste de manera más agradable. Benedikt Bitterli también comentó sobre esa publicación que informa un problema similar con su renderizador (exceso de ruido de alta frecuencia alrededor de las fuentes de luz cuando se usa el método 2). Más allá de eso, descubrí que la principal diferencia entre los métodos era la frecuencia del ruido resultante: el método 2 produce un ruido de "tamaño de píxel" de mayor frecuencia, mientras que el método 1 proporciona "granos" de ruido de 2-3 píxeles de ancho, pero la amplitud del ruido fue similar para ambos, por lo que el tipo de ruido que se ve menos mal es probablemente una cuestión de preferencia personal.

Nathan Reed
fuente
¡Gracias! Estos son grandes recursos. Entonces, al final, ¿hay 3 métodos? 1. Generar y pesar con salpicaduras 2. Generar y pesar sin salpicaduras 3. Generar en forma de filtro
RichieSams
¿Conoces algún periódico, blog, etc. que explore cómo paralelizar Generate y Weight con splatting? En la parte superior de mi cabeza, podría tener un mutex por mosaico, o hacer que cada píxel sea atómico.
RichieSams
2
@RichieSams No sé por qué usarías "generar y pesar sin salpicar", en realidad, eso parece ser peor en cualquier caso que el muestreo de importancia de filtro. Estaba asumiendo que "generar y pesar" implica salpicar. En cuanto a la paralelización de las salpicaduras, desde la parte superior de mi cabeza, una forma sería dividir la imagen en mosaicos, pero dar a cada mosaico un borde de 2‒3 píxeles para atrapar los símbolos que cruzan el borde del mosaico. Luego, en una pasada final, combine aditivamente los mosaicos confinados en la imagen final.
Nathan Reed