Kenar Yumuşatma Işın İzlemede Nasıl Uygulanır?


13

Çevrimiçi birkaç makaleyi okuduktan sonra, Ray Tracing'i kullanırken Kenar Yumuşatma'nın nasıl çalıştığından emin olmadığımı söyleyebilirim .

Tek anladığım kadarıyla, Tek Piksel / Işın 1 yerine 4 alt piksele ve 4 ışına ayrılmıştır .

Birisi bunun nasıl yapıldığını açıklayabilir mi (tercihen kodla)?


2
Sadece "süper örnekleme" bakmak önerebilir en.wikipedia.org/wiki/Supersampling ve belki de en.wikipedia.org/wiki/Distributed_ray_tracing ?
Simon F

2
Ayrıca PBRT pbrt.org/chapters/pbrt_chapter7.pdf'in bu bölümünü okumanızı ve bu makaleyi okumanızı tavsiye edebilirim . Lgdv.cs.fau.de/get/785
Tom van Bussel

1
foreach pixel : p{acc = 0; foreach subsample : s { acc+=sample_scene(s);} store(p, acc);}
cırcır ucube

Yanıtlar:


12

Raytracing'de AA yapmanın iki farklı yolu olduğunu söylemek güvenli olduğunu düşünüyorum:

1: Son görüntüye ve derinlik görüntüsüne sahipseniz, oyunlarda kullanılan hemen hemen tüm teknikleri uygulamak mümkündür (FXAA, vb.) Doğrudan son görüntü üzerinde çalışır ve ışın izlemeyle ilgili değildir

2: ikinci yöntem, her piksel için çoklu ışınları hesaba katmak ve ardından sonucun ortalamasını almaktır. Çok basit bir sürüm için şöyle düşünün:

  • önce 1024x1024 boyutunda bir resim, her piksel için bir ışın oluşturursunuz (örneğin)
  • oluşturma işleminden sonra, görüntüyü 512x512 boyutunda ölçeklendirirsiniz (her 4 piksel birer birer önlenir) ve kenarların daha pürüzsüz olduğunu fark edebilirsiniz. Bu şekilde, 512x512 boyutunun son görüntüsünde her piksel için 4 ışın etkili bir şekilde kullandınız.

Bu yöntemde başka varyasyonlar da vardır. Örneğin, geometrinin hemen sağındaki pikseller için örnek sayısını uyarlayabilirsiniz; bu, bazı pikseller için yalnızca 4 örneğiniz ve diğerleri için 16 olacağınız anlamına gelir.

Yukarıdaki yorumlardaki bağlantıları kontrol edin.


Yani temelde bir görüntüyü büyük boyuta dönüştürüyorum ve bir görüntüye kaydederken daha düşük bir boyuta küçültebilir miyim? Bu oldukça basit görünüyor :)! Bu süper örnekleme yöntemi mi?
Arjan Singh

2
@Arjan Singh evet bu en.wikipedia.org/wiki/Supersampling , ama bu en yavaş olanı, raytracing kolayca çok daha iyi performans gösterebilen uyarlanabilir
süper örnekleme

14

Raxvan, kenar yumuşatma yapmak için derinlik gibi bilgileri kullananlar da dahil olmak üzere, "geleneksel" kenar yumuşatma tekniklerinin çalışacağı konusunda tamamen haklıdır. Örneğin ışın izlemede geçici kenar yumuşatma bile yapabilirsiniz.

Julien, süper örneklemenin bir açıklaması olan Raxvan'ın 2. maddesini genişletti ve bunu nasıl yapacağınızı gösterdi, ayrıca örneklerin piksel içindeki yerini rastgele ayarlayabileceğinizi ancak daha sonra çok fazla sinyal işleme ülkesine girdiğinizi belirtti. daha derin ve kesinlikle öyle!

N-N-

Bunu yaparsanız yine de takma ad alabilirsiniz. Bunu yapmak DEĞİLDİR daha iyidir, çünkü örnekleme oranınızı artırıyorsunuz, bu nedenle daha yüksek frekanslı verileri (daha küçük detaylar gibi) işleyebileceksiniz, ancak yine de diğer adlara neden olabilir.

N-

Rand () veya std :: uniform_int_distribution gibi sadece "normal" rasgele sayılar kullandığınızda buna "beyaz gürültü" denir, çünkü beyaz ışığın diğer tüm renklerden nasıl oluştuğu gibi (frekanslar) ) ışığın.

Bir piksel içindeki örnekleri rastgele ayarlamak için beyaz gürültü kullanmak bazen örneklerinizin bir araya gelmesi sorununu yaşar. Örneğin, bir pikselde ortalama 100 örnek alırsanız, ancak TÜMÜ pikselin sol üst köşesinde kalırsa, pikselin diğer bölümleri hakkında HERHANGİ bir bilgi alamazsınız, bu nedenle sonuçta ortaya çıkan piksel renginiz ne renk olması gerektiği hakkında bilgi eksik olacaktır.

Daha iyi bir yaklaşım, sadece yüksek frekanslı bileşenler (mavi ışığın yüksek frekanslı ışık gibi) içeren mavi gürültü adı verilen bir şey kullanmaktır.

Mavi gürültünün yararı, düzgün bir örnekleme ızgarasında olduğu gibi piksel üzerinde bile kapsama alanı almanızdır, ancak yine de bazı rastgele özellikler elde edersiniz, bu da takma gürültüye dönüşür ve size daha iyi görünen bir görüntü verir.

Ne yazık ki, mavi gürültü hesaplamak çok maliyetli olabilir ve en iyi yöntemlerin hepsi patentli gibi görünüyor (ne halt ?!), ancak bunu yapmanın bir yolu, pixar tarafından icat edildi (ve patentli de düşünüyorum ama% 100 emin değilim) eşit bir numune noktaları ızgarası oluşturmak, daha sonra her numune noktasını rastgele bir şekilde dengelemek - örnekleme ızgarasının genişliği ve yüksekliğinin yarısı veya eksi yarısı arasındaki rastgele bir miktar gibi. Bu şekilde oldukça ucuz bir tür mavi gürültü örneklemesi elde edersiniz.

Bunun tabakalı örnekleme biçimi olduğunu ve poisson disk örneklemenin de mavi gürültü üretmenin bir yolu olduğunu unutmayın: https://www.jasondavies.com/poisson-disc/

Daha derine inmek istiyorsanız, muhtemelen bu soruyu kontrol etmek ve cevaplamak isteyeceksiniz!

Bir piksel içinde birden fazla rasgele örnek kullanarak kenar yumuşatmanın temel nedeni nedir?

Son olarak, bu şeyler fotogerçekçi ışın izlemenin yaygın bir yöntemi olan monte carlo yol izleme alanına girmeye başlıyor. bunun hakkında daha fazla bilgi edinmek istiyorsanız, bunu okuyun!

http://blog.demofox.org/2016/09/21/path-tracing-getting-started-with-diffuse-and-emissive/


Adını görür görmez mavi gürültüye bir şeyler ekleyeceğini biliyordum :)
Hubble

Bu tekrar aktif olduğu için: Bunun neden olduğunu açıklamak için - mavi gürültü örnekleme modelleri, düşük frekanslarda yoğunlaşan enerjinin çoğuyla fonksiyonları entegre etmede mükemmeldir. Bu nedenle, mavi bir gürültü modeli kullanarak, sinyalin düşük frekanslarla daha yumuşak / baskın olduğunu etkili bir şekilde varsayıyorsunuz. Yüksek frekanslı sinyaller için bu aslında ters etki yaratabilir. Neyse ki, doğal görüntüler enerjilerini düşük frekanslarda yoğunlaştırır. Daha fazla ayrıntı için bkz. Sampling.mpi-inf.mpg.de/2019-singh-fourier.html
lightxbulb

7

Diyelim ki oldukça tipik bir ışın izleme ana döngüsü:

struct Ray
{
    vec3 origin;
    vec3 direction;
};

RGBColor* image = CreateImageBuffer(width, height);

for (int j=0; j < height; ++i)
{
    for (int i=0; i < width; ++i)
    {
        float x = 2.0 * (float)i / (float)max(width, height) - 1.0;
        float y = 2.0 * (float)j / (float)max(width, height) - 1.0;

        vec3 dir = normalize(vec3(x, y, -tanHalfFov));
        Ray r = { cameraPosition, dir };

        image[width * j + i] = ComputeColor(r);
    }
}

4 SSAA numunesi yapmak için olası bir modifikasyonu:

float jitterMatrix[4 * 2] = {
    -1.0/4.0,  3.0/4.0,
     3.0/4.0,  1.0/3.0,
    -3.0/4.0, -1.0/4.0,
     1.0/4.0, -3.0/4.0,
};

for (int j=0; j < height; ++i)
{
    for (int i=0; i < width; ++i)
    {
        // Init the pixel to 100% black (no light).
        image[width * j + i] = RGBColor(0.0);

        // Accumulate light for N samples.
        for (int sample = 0; sample < 4; ++sample)
        {
            float x = 2.0 * (i + jitterMatrix[2*sample]) / (float)max(width, height) - 1.0;
            float y = 2.0 * (i + jitterMatrix[2*sample+1]) / (float)max(width, height) - 1.0;

            vec3 dir = normalize(vec3(x, y, -tanHalfFov) + jitter);
            Ray r = { cameraPosition, dir };

            image[width * j + i] += ComputeColor(r);
        }

        // Get the average.
        image[width * j + i] /= 4.0;
    }
}

Başka bir olasılık, rastgele bir titreşim yapmaktır (yukarıdaki matris tabanlı olanın yerine), ancak daha sonra sinyal işleme alanına girersiniz ve iyi bir gürültü işlevinin nasıl seçileceğini bilmek çok fazla okuma gerektirir.

Fikir yine de aynı kalıyor: Pikselin küçük bir kare alanı temsil ettiğini düşünün ve pikselin merkezinden geçen tek bir ışını çekmek yerine, tüm piksel alanını kaplayan birçok ışın çekin. Işın dağılımı ne kadar yoğun olursa, o kadar iyi sinyal alırsınız.

PS: Yukarıdaki kodu anında yazdım, bu yüzden birkaç hata beklerdim. Sadece temel fikri göstermek içindir.


Mükemmel cevap! @Raxvan'ın kullandığı yönteme karşı bu yöntemi kullanmanın faydaları nelerdir? Aynı sonuçları daha büyük bir boyuta dönüştürüp daha sonra daha küçük bir boyuta küçülterek elde edecek miyim?
Arjan Singh

Temel olarak, ışın izleme ile daha büyük bir görüntü oluşturmanıza ve ölçeklendirmenize gerek yoktur. Bu, çok daha fazla esnekliğiniz olduğu anlamına gelir: çok sayıda örneğiniz olabilir, bölgeye bağlı olarak örnek sayısını değiştirebilirsiniz ve basitçe, yeniden satış adımını eklemeniz gerekmez.
Julien Guertault

2
Titreşim konusunda, bu oldukça karmaşık bir konu olarak ortaya çıkıyor. İşte birkaç yıl önce en son teknolojiyi analiz eden harika bir makale graphics.pixar.com/library/MultiJitteredSampling/paper.pdf
Mikkel Gjoel

Yukarıdaki kod örneği 4 Örnek MSAA kullanır, 8x MSAA yapmak isteseydim matris o zaman neye benzeyecekti? Yukarıda gösterilen titreşim matrisinde neyi değiştirmem gerekir?
Arjan Singh

1
@SimonF Gösterdiğiniz için teşekkür ederiz. Sabit.
Julien Guertault

1

Yukarıdaki cevaplara eklemek için:

Dağıtılmış Işın İzleme (Cook, Porter ve Carpenter). Aynı anda uzamsal AA, geçici AA (yani hareket bulanıklığı) ve odak / alan derinliği yapmanıza olanak sağlar. Kağıdı okumak en iyisidir, ancak temel olarak piksel başına ateşlediğiniz N-ışınlarına da sahte rasgele zamanlar (hareket bulanıklığı için) ve lens üzerindeki konumlar (odak efektleri elde etmek için) atanabilir.

Uyarlanabilir Süper Örnekleme: Başlangıçta piksel başına belirli sayıda ışın gönderirsiniz. Bununla birlikte, yerel bir mahalledeki ışınlar önemli ölçüde farklı sonuçlar verirse, sonuçları iyileştirmek için yerel olarak örnekleme oranını (2x diyelim) artırabilirsiniz. İşlemi tekrarlamayı seçebilirsiniz. Nesneler hala 'numuneler arasında düşebileceği' için mükemmel değildir, ancak muhtemelen daha yüksek oranda eşit örneklemeden daha ucuzdur.

Konilerle ışın izlemesi (Amanatides): Sonsuz ince bir ışın kullanmak yerine, her ışın bunun yerine bir koni ile yakınlaştırılır, mesela kısmi kapsama alanını değerlendirmenize izin veren tüm pikseli (ve komşularının bir kısmını) kaplayan bir çapla . Ayrıca doku örnekleme / kenar yumuşatma, yumuşak gölgeler ve potansiyel olarak LOD modelleri için faydaları vardır. Ben bir uygulama yaptım birçok yıllar önce - bunu yapmak kesinlikle daha zordur, ancak ek ışınlarının bir sürü önlemek gelmez. IIRC'de kalem izleme adı verilen bir plan da vardı (ancak ilk aramam gazeteye bir bağlantı bulamadı)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.