このロシアのルーレットのコードは正しいですか?


8

レンダラーの実装方法を学ぶために、他のリソースの中でwww.scratchapixel.comを使用しています。このページから次のコードを見ています。マテリアルを通過するフォトンのパケットが検討されています。フォトンパケットごとに、重みが初期化されます。は吸収の確率です。w1dw

私にとって混乱するのは、からを引くときです。は光子の吸収されていない割合であるため、パケットのフルウェイトが場合、これが理にかなっていることがわかります。例えば、吸収の確率がある場合次いでと光子のが残っています。これが後続の反復でどのように意味をなすかわかりません。たとえば、反復2では、なので、この反復では3番目ではなく半分の光子が吸収されます。dww11dw33%w=10.33=0.6767%w=0.670.33=0.34

int photons = 10000; 
... 
int m = 5; // there's 1 over 6 chances for the packet to be absorbed 
for (int i = 0; i < nphotons; ++i) { 
    float w = 1; // set the weight to 1 
    Vec3f P(0, 0, 0); 
    Vec3f V(0, 0, 1); 
    while (1) { 
        ... 
        float dw = sigma_a / sigma_t; 
        absorption += dw; 
        w -= dw; 
        if (w < 0.001) { // perform russian roulette if weight is small 
            if (drand48() < 1.0 / m) { 
                break; // we kill the packet 
            } 
            else 
                w *= m; // adjust weight 
        } 
    } 
} 

回答:


4

私はあなたが正しいと思いますし、引き算は間違いです。コードは、ウェイトに吸収されないフォトンの割合を乗算する必要があります。何かのようなもの:

float fraction_absorbed = sigma_a / sigma_t;
absorption += w * fraction_absorbed;
w *= (1.0f - fraction_absorbed);

これによりabsorption、これまでに吸収されたフォトンの合計の割合とw、残っているフォトンの割合が決まります。


2
補遺として:この他の質問への答えは、ロシアのルーレットのためのいくつかのサンプルコードがあります。computergraphics.stackexchange.com/questions/2316/...
RichieSams
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.