<p>I think you're right and the subtraction is a mistake. The code should rather be multiplying the fraction of photons not absorbed into the weight. Something like:</p>

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

<p>This makes <code>absorption</code> the total fraction of photons absorbed so far, and <code>w</code> the fraction of photons remaining.</p>

CC BY-SA 3.0
2016-09-14T19:23:27.573Z
As an addendum: The answer to this other question has some sample code for russian roulette. http://computergraphics.stackexchange.com/questions/2316/is-russian-roulette-really-the-answer/2325#2325
RichieSams
CC BY-SA 3.0
2016-09-14T15:46:57.783Z
2016-09-14T15:46:57.783Z
Nathan Reed
<p>I'm using www.scratchapixel.com among other resources to help me learn how to implement a renderer. I am looking at the following code from <a href="http://www.scratchapixel.com/lessons/mathematics-physics-for-computer-graphics/monte-carlo-methods-in-practice/monte-carlo-simulation">this page</a> where a packet of photons moving through a material is being considered. For each photon packet, the weight $w$ is initialised to $1$. $dw$ is the probability of absorption.</p>

<p>The confusing part to me is when $dw$ is subtracted from $w$. I can see this would make sense when the packet has full-weight of $1$ because $1 - dw$ is the unabsorbed proportion of photons. E.g. if probability of absorption is $33\%$ then $w = 1 - 0.33 = 0.67$ and $67\%$ of the photons remain. I can't see how this makes sense on subsequent iterations. For example, on iteration two, $w = 0.67 - 0.33 = 0.34$ so half the photons are absorbed on this iteration, not a third.</p>

<pre><code>int photons = 10000; 
... 
int m = 5; // there's 1 over 6 chances for the packet to be absorbed 
for (int i = 0; i &lt; 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 &lt; 0.001) { // perform russian roulette if weight is small 
            if (drand48() &lt; 1.0 / m) { 
                break; // we kill the packet 
            } 
            else 
                w *= m; // adjust weight 
        } 
    } 
} 
</code></pre>

<pathtracing><monte-carlo>
Is this Russian roulette code correct?
PeteUK
# Is this Russian roulette code correct?

(Asked by: username_0 on 2016-09-12)

I'm using www.scratchapixel.com among other resources to help me learn how to implement a renderer. I am looking at the following code from [this page](http://www.scratchapixel.com/lessons/mathematics-physics-for-computer-graphics/monte-carlo-methods-in-practice/monte-carlo-simulation) where a packet of photons moving through a material is being considered. For each photon packet, the weight $w$ is initialised to $1$. $dw$ is the probability of absorption.

The confusing part to me is when $dw$ is subtracted from $w$. I can see this would make sense when the packet has full-weight of $1$ because $1 - dw$ is the unabsorbed proportion of photons. E.g. if probability of absorption is $33\%$ then $w = 1 - 0.33 = 0.67$ and $67\%$ of the photons remain. I can't see how this makes sense on subsequent iterations. For example, on iteration two, $w = 0.67 - 0.33 = 0.34$ so half the photons are absorbed on this iteration, not a third.

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

```

**Tags:** pathtracing, monte-carlo


---

## 1 answers

### Answer by username_1 on 2016-09-14. Score: 4 | Accepted answer

I think you're right and the subtraction is a mistake. The code should rather be multiplying the fraction of photons not absorbed into the weight. Something like:

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

```

This makes `absorption` the total fraction of photons absorbed so far, and `w` the fraction of photons remaining.

> **Comments:**
> **username_2**: As an addendum: The answer to this other question has some sample code for russian roulette. http://computergraphics.stackexchange.com/questions/2316/is-russian-roulette-really-the-answer/2325#2325  

---

