Anti-aliasing / Filtering dalam Ray Tracing

20

Dalam ray tracing / path tracing, salah satu cara paling sederhana untuk anti-alias gambar adalah dengan mengganti nilai piksel dan rata-rata hasilnya. YAITU. alih-alih memotret setiap sampel melalui bagian tengah piksel, Anda mengimbangi sampel dengan jumlah tertentu.

Dalam mencari di internet, saya menemukan dua metode yang agak berbeda untuk melakukan ini:

  1. Buat sampel sesuai keinginan Anda dan timbang hasilnya dengan filter
    • Salah satu contohnya adalah PBRT
  2. Hasilkan sampel dengan distribusi yang sama dengan bentuk filter


Hasilkan dan Timbang

Proses dasarnya adalah:

  1. Buat sampel sesuai keinginan Anda (secara acak, bertingkat, urutan perbedaan rendah, dll.)
  2. Offset sinar kamera menggunakan dua sampel (x dan y)
  3. Jadikan adegan dengan sinar
  4. Hitung bobot menggunakan fungsi filter dan jarak sampel mengacu pada pusat piksel. Misalnya, Filter Kotak, Filter Tenda, Filter Gaussian, dll.) Bentuk Filter
  5. Berikan bobot pada warna dari render


Buat dalam bentuk filter

Premis dasarnya adalah menggunakan Inverse Transform Sampling untuk membuat sampel yang didistribusikan sesuai dengan bentuk filter. Misalnya histogram dari sampel yang didistribusikan dalam bentuk Gaussian adalah:
Histogram Gaussian

Ini bisa dilakukan dengan tepat, atau dengan menggeser fungsi menjadi pdf / cdf diskrit. smallpt menggunakan cdf terbalik yang tepat dari filter tenda. Contoh metode binning dapat ditemukan di sini


Pertanyaan

Apa pro dan kontra dari setiap metode? Dan mengapa Anda menggunakan salah satunya? Saya dapat memikirkan beberapa hal:

Menghasilkan dan Menimbang tampaknya menjadi yang paling kuat, memungkinkan kombinasi metode pengambilan sampel apa pun dengan filter apa pun. Namun, itu mengharuskan Anda untuk melacak bobot di ImageBuffer dan kemudian melakukan penyelesaian akhir.

Menghasilkan dalam Bentuk Filter hanya dapat mendukung bentuk filter positif (mis. Tidak ada Mitchell, Catmull Rom, atau Lanczos), karena Anda tidak dapat memiliki pdf negatif. Tapi, seperti yang disebutkan di atas, lebih mudah diterapkan, karena Anda tidak perlu melacak bobot apa pun.

Meskipun, pada akhirnya, saya kira Anda bisa menganggap metode 2 sebagai penyederhanaan metode 1, karena pada dasarnya menggunakan berat Box Filter implisit.

RichieSams
sumber
Hanya berpikir keras ... Bisakah Anda memodelkan bagian negatif dari filter secara terpisah untuk menghasilkan dua set sampel, satu diperlakukan sebagai positif dan yang lainnya sebagai negatif? Apakah ini memungkinkan filter sewenang-wenang untuk pendekatan kedua Anda (menghasilkan dalam bentuk filter)?
trichoplax
Mungkin? Biarkan aku bermain-main sebentar
RichieSams
1
Ok, jika Anda melacak nol fungsi, Anda bisa abs () output ke pdf. Kemudian saat pengambilan sampel, Anda dapat memeriksa apakah Anda negatif. Contoh kode di sini: gist.github.com/RichieSams/aa7e71a0fb4720c8cb41
RichieSams

Jawaban:

9

Ada makalah yang bagus dari 2006 tentang topik ini, Filter Importance Sampling . Mereka mengusulkan metode 2 Anda, mempelajari sifat-sifatnya, dan secara umum mendukungnya. Mereka mengklaim bahwa metode ini memberikan hasil rendering yang lebih halus karena bobot semua sampel yang berkontribusi pada piksel sama, sehingga mengurangi varians dalam nilai piksel akhir. Ini masuk akal, karena ini merupakan pepatah umum dalam Monte Carlo yang menyatakan bahwa sampel-kepentingan akan memberikan varians yang lebih rendah daripada sampel tertimbang.

Metode 2 juga memiliki keuntungan menjadi sedikit lebih mudah untuk diparalelkan karena perhitungan masing-masing piksel tidak tergantung pada semua piksel lainnya, sedangkan dalam metode 1, hasil sampel dibagi di seluruh piksel tetangga (dan karena itu harus disinkronkan / dikomunikasikan entah bagaimana ketika piksel diparalelkan melintasi beberapa prosesor). Untuk alasan yang sama, lebih mudah untuk melakukan pengambilan sampel adaptif (lebih banyak sampel di area varians tinggi pada gambar) dengan metode 2 daripada metode 1.

Dalam makalah, mereka juga bereksperimen dengan filter Mitchell, mengambil sampel dari abs () filter dan kemudian menimbang setiap sampel dengan +1 atau -1, seperti yang disarankan @trichoplax. Tapi ini akhirnya benar-benar meningkatkan varians dan menjadi lebih buruk daripada metode 1, sehingga mereka menyimpulkan bahwa metode 2 hanya dapat digunakan untuk filter positif.

Yang sedang berkata, hasil dari makalah ini mungkin tidak berlaku secara universal, dan mungkin agak tergantung adegan metode pengambilan sampel yang lebih baik. Saya menulis posting blog yang menyelidiki pertanyaan inisecara independen pada tahun 2014, menggunakan "fungsi gambar" sintetik daripada rendering penuh, dan menemukan metode 1 untuk memberikan hasil yang lebih menyenangkan secara visual karena menghaluskan tepi kontras tinggi dengan lebih baik. Benedikt Bitterli juga mengomentari pos yang melaporkan masalah yang sama dengan pemberi rendernya (kelebihan frekuensi tinggi kebisingan di sekitar sumber cahaya saat menggunakan metode 2). Di luar itu, saya menemukan perbedaan utama antara metode adalah frekuensi noise yang dihasilkan: metode 2 memberikan frekuensi tinggi, "berukuran pixel" noise, sedangkan metode 1 memberikan noise "grain" yang berukuran 2-3 pixel, tetapi amplitudo kebisingan serupa untuk keduanya, sehingga jenis kebisingan yang terlihat kurang buruk mungkin adalah masalah preferensi pribadi.

Nathan Reed
sumber
Terima kasih! Ini adalah sumber yang bagus. Jadi, pada akhirnya, ada 3 metode? 1. Hasilkan dan Timbang dengan splatting 2. Hasilkan dan Timbang tanpa splatting 3. Hasilkan dalam Bentuk Filter
RichieSams
Apakah Anda tahu ada makalah, blog, dll. Yang mengeksplorasi cara memparalelkan Generate dan Weight dengan splatting? Dari atas kepala saya, Anda bisa memiliki mutex per ubin, atau membuat atomik setiap pixel.
RichieSams
2
@RichieSams Saya tidak tahu mengapa Anda akan menggunakan "menghasilkan dan menimbang tanpa menepuk", sebenarnya — sepertinya itu akan lebih buruk dalam hal apapun daripada menyaring sampel penting. Saya berasumsi bahwa "menghasilkan dan menimbang" menyiratkan percikan. Sedangkan untuk paralelisasi percikan, dari atas kepala saya, salah satu caranya adalah dengan membagi gambar menjadi ubin, tetapi memberikan setiap ubin batas 2‒3 piksel untuk menangkap percikan yang melintasi tepi ubin. Kemudian dalam pass terakhir, tambahkan komposit ubin berbatasan bersama-sama ke dalam gambar akhir.
Nathan Reed