レイトレーシングでアンチエイリアシングはどのように実装されていますか?


12

オンラインでいくつかの記事を読んだ後、レイトレーシングでアンチエイリアシングがどのように機能するかについて私は自信がないと自信を持って言えます。

私が理解しているのは、単一のピクセル/光線が1ではなく4つのサブピクセルと4つの光線に分割されていることです。

誰かがこれがどのように行われるのかを説明できますか?


2
「スーパーサンプリング」en.wikipedia.org/wiki/Supersamplingおよびおそらくen.wikipedia.org/wiki/Distributed_ray_tracingご覧になることをお勧めしますか?
サイモンF

2
また、PBRT pbrt.org/chapters/pbrt_chapter7.pdfのこの章を読んで、このペーパーlgdv.cs.fau.de/get/785(pbrtで実装されたものとは異なる手法を説明しています)を読むこともお勧めします。
トムヴァンバッセル

1
foreach pixel : p{acc = 0; foreach subsample : s { acc+=sample_scene(s);} store(p, acc);}
ラチェットフリーク

回答:


11

レイトレーシングでAAを実行するには、2つの異なる方法があると言っても安全だと思います。

1:最終画像と深度画像がある場合、ゲームで使用されているほとんどすべての既存の技術(FXAAなど)を適用できます。これらは最終画像に直接作用し、レイトレーシングとは関係ありません

2:2番目の方法は、ピクセルごとに複数の光線を考慮して、結果を平均化することです。非常に単純なバージョンの場合、次のように考えてください。

  • 最初にサイズ1024x1024の画像をレンダリングします。たとえば、各ピクセルに1つのレイがあります
  • レンダリング後、イメージを512x512にスケーリングし(各4ピクセルが1つに平均化されます)、エッジがより滑らかになっていることがわかります。このようにして、512x512サイズの最終画像の各ピクセルに4つの光線を効果的に使用しました。

この方法には他にもバリエーションがあります。たとえば、ジオメトリの端にあるピクセルのサンプル数を調整できます。つまり、一部のピクセルでは4つのサンプルしか使用できず、他のピクセルでは16になります。

上記のコメント内のリンクを確認してください。


だから基本的に私は画像を大きなサイズにレンダリングし、画像に保存するときにそれをより小さなサイズにダウンスケールしますか?それは非常に簡単なようです:)!これはスーパーサンプリング方式ですか?
アルジャンシン

1
それはだそうシン@Arjan en.wikipedia.org/wiki/Supersamplingが、これはそれらすべての最も遅いが、レイトレーシングはあなたが簡単に、より良い多くのことを行うことができ、適応型スーパーサンプリング、行うことができますされて
Raxvan

12

Raxvanは、深度などの情報を使用してアンチエイリアシングを行うものを含め、「従来の」アンチエイリアシング手法がレイトレーシングで機能することを完全に正しいと考えています。たとえば、レイトレーシングで一時的なアンチエイリアシングを行うこともできます。

ジュリアンは、スーパーサンプリングの説明であるRaxvanの2番目の項目を拡張し、実際にそれを行う方法を示しました。また、ピクセル内のサンプルの位置をランダム化できるが、その後、多くの信号処理国に入ることに言及しましたより深く、そして間違いなくそうです!

NN

そうした場合でも、エイリアスを取得できます。サンプリングレートを上げているので、それをしないよりはましです。したがって、より高い周波数のデータ(詳細は小さい)を処理できますが、エイリアシングを引き起こす可能性があります。

N

rand()またはstd :: uniform_int_distributionから取得するような「通常の」乱数を使用する場合、白色光が他のすべての色(周波数)で構成される方法など、すべての周波数が含まれるため「ホワイトノイズ」と呼ばれます) 光の。

ホワイトノイズを使用してピクセル内のサンプルをランダム化すると、サンプルがまとまってしまうという問題が発生します。たとえば、ピクセルで100個のサンプルを平均しても、それらがすべてピクセルの左上隅にある場合、ピクセルの他の部分に関する情報は取得されないため、最終的なピクセルの色はどの色にする必要があるかに関する情報が欠落しています。

より良いアプローチは、高周波成分のみを含むブルーノイズと呼ばれるものを使用することです(青色光が高周波光である方法など)。

ブルーノイズの利点は、均一なサンプリンググリッドで得られるように、ピクセル全体を均一にカバーできることですが、それでもある程度のランダム性が得られるため、エイリアシングがノイズに変わり、見栄えが良くなります。

残念ながら、ブルーノイズは計算に非常にコストがかかる可能性があり、最良の方法はすべて特許を取得しているようです(一体何でしょう!)、しかしこれを行う1つの方法はpixarによって発明されていますサンプルポイントの偶数グリッドを作成し、各サンプルポイントをランダムにオフセットします(サンプリンググリッドの幅と高さのプラスまたはマイナス間のランダムな量など)。このようにして、かなり安価にブルーノイズのサンプリングを行うことができます。

これは層化サンプリングの形式であり、ポアソンディスクサンプリングもその形式であり、ブルーノイズを生成する方法でもあることに注意してください。https//www.jasondavies.com/poisson-disc/

もっと深く知りたい場合は、おそらくこの質問と回答も確認してください。

ピクセル内で複数のランダムサンプルを使用するアンチエイリアシングの基本的な理由は何ですか?

最後に、このようなものは、フォトリアリスティックなレイトレーシングを行う一般的な方法であるモンテカルロパストレーシングの領域に迷い込み始めています。それについてもっと知りたいなら、これを読んでください!

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


7

かなり典型的なレイトレーシングのメインループを考えてみましょう。

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つのサンプルMSAAを実行するための1つの可能な変更は次のとおりです。

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;
    }
}

もう1つの可能性は、(上記のマトリックスベースの代わりに)ランダムジッタを行うことですが、すぐに信号処理の領域に入り、適切なノイズ関数を選択する方法を知るには多くの読み取りが必要になります。

アイデアは同じままです:ピクセルを小さな正方形の領域を表すと考え、ピクセルの中心を通過する光線を1つだけ照射する代わりに、ピクセル領域全体をカバーする多くの光線を照射します。光線の分布が密であればあるほど、より良い信号が得られます。

PS:上記のコードをその場で書いたので、いくつかのエラーが発生することを期待しています。基本的な考え方を示すことのみを目的としています。


素晴らしい答えです!@Raxvanが使用する方法とは対照的に、この方法を使用する利点は何ですか?大きなサイズにレンダリングした後、小さなサイズにダウンスケーリングしても同じ結果が得られますか?
アルジャンシン

基本的に、レイトレーシングを使用すると、大きな画像をレンダリングしてから縮小する必要がありません。つまり、柔軟性がはるかに高くなります。つまり、多数のサンプルを使用でき、リージョンに応じてサンプルの数を変更でき、単純に、再スケールステップを追加する必要がありません。
ジュリアンゲルトー16年

2
ジッタリングのトピックでは、これはかなり複雑なトピックであることがわかりました。ここに数年前の最新技術を分析した素晴らしい論文がありますgraphics.pixar.com/library/MultiJitteredSampling/paper.pdf
Mikkel Gjoel

上記のコードサンプルでは4サンプルMSAAを使用していますが、8x MSAAを実行したい場合、マトリックスはどのようになりますか?上記のジッターマトリックスで何を変更する必要がありますか?
アルジャンシン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.