我正在使用www.scratchapixel.com和其他资源来帮助我学习如何实现渲染器。我正在从此页面查看以下代码,其中正在考虑一包光子穿过材料的移动。对于每个光子包,权重$ w $初始化为$ 1 $。 $ dw $是吸收的概率。

让我感到困惑的部分是,从$ w $中减去$ dw $。我看到当数据包的总权重为$ 1 $时,这是有道理的,因为$ 1-dw $是光子未吸收的部分。例如。如果吸收的概率为$ 33 \%$,则$ w​​ = 1-0.33 = 0.67 $,剩下$ 67 \%$的光子。我看不到这在后续迭代中如何有意义。例如,在第二次迭代中,$ w = 0.67-0.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 
        } 
    } 
} 

#1 楼

我认为您是对的,减法是一个错误。该代码应该将未吸收的光子的分数乘以重量。像这样的东西:

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


这使得absorption到目前为止吸收的光子总数,而w是剩余的光子分数。

评论


$ \ begingroup $
作为补充:这个另一个问题的答案有一些俄罗斯轮盘赌的示例代码。 computergraphics.stackexchange.com/questions/2316/…
$ \ endgroup $
–RichieSams
16 Sep 14 '19:23