I think the Random Code is serverly busted.

We start with

1 2 3 | ComputeLightPropagation(lighting_work *Work) ... for(u32 SamplePointIndex = FirstSamplePointIndex; // NOTE(casey): Light point 0 is never used |

Now we are in a loop.

We initalize now EVERY time the seed:

1 | random_series Series = RandomSeed(213897*(2398 + Solution->EntropyCounter)); |

This is a bad idea, we should initialize the Seed once when we start, then update the random state with the old state.

Why? We will get the SAME sequenca as long as EntropyCounter stays the same.

But it gets worse.

What happens in RandomSeed?

1 2 3 4 | inline random_series RandomSeed(uint32 E0 = 78953890, uint32 E1 = 235498, uint32 E2 = 893456, uint32 E3 = 93453080) |

We don't even use EntropyCounter!

So we use the same sequence every Sample Point!

And I tested this, I wrote out the random numbers.

I think we should initialize Random seed once, get rid of entropy and save the state instead.

You already did this for the normal Series:

1 | Solution->Series = RandomSeed(1234); |

Then change RandomSeed:

1 2 3 4 5 6 7 8 | inline random_series RandomSeed(uint32 E0) { random_series Series; Series.State = U32_4x(E0, E0+45646, E0+511345, E0+2131857); return(Series); } |

Get the series

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | lighting_solution *Solution = Work->Solution; u32 FirstSamplePointIndex = Work->FirstSamplePointIndex; u32 OnePastLastSamplePointIndex = Work->OnePastLastSamplePointIndex; u32 RayCount = 16; v3 MoonColor = 0.4f*V3(0.10f, 0.80f, 1.00f); for(u32 SamplePointIndex = FirstSamplePointIndex; // NOTE(casey): Light point 0 is never used SamplePointIndex < OnePastLastSamplePointIndex; ++SamplePointIndex) { lighting_point *SamplePoint = Solution->Points + SamplePointIndex; v3_4x RayOrigin = V3_4x(SamplePoint->P, SamplePoint->P, SamplePoint->P, SamplePoint->P); v3_4x SamplePointN = V3_4x(SamplePoint->N); // TODO(casey): randomize based on point position? random_series Series = Solution->Series; //uint32 two = 2; //uint32 Series2 = RandomSeed2(two); for(u32 RayIndex = 0; RayIndex < RayCount; ++RayIndex) |

Just get pure random noise

1 2 3 4 5 6 | v3_4x Delta; Delta.x = RandomBilateral_4x(&Series); Delta.y = RandomBilateral_4x(&Series); Delta.z = RandomBilateral_4x(&Series); v3_4x Basis2 = ApproxNOZ(Delta); v3_4x SampleD4x = Basis2; |

And write the series back at the end of the for loop

1 | Solution->Series = Series; |