I'm working on a (toy-level) path/ray-tracer, currently trying to implement (and understand) improved sampling strategies.
The obvious next choice after uniform random sampling would be stratified/jittered sampling. The idea itself is clear: You divide the domain to sample (let's say the unit square) into NxN sub regions/cells, place a sample into each of those and add noise to it. Afterwards you shuffle the sample array so the consumption order does not matter - at least that is my understanding for the shuffle step.
This procedure is explained over and over in lots of sources and literature, but what most barely touch is how you would consume those in practise. While it is clear for a single use case, like sampling a primary ray/camera pixel or sampling the surface of an area light, my understanding (which might be wrong) is that those stratified [0,1]^N samples act as a general source of well distributed random numbers.
An example, say you want to render 1024 samples for some scene with area lights with a path tracer.
- just generating 32 x 32 (camera ray) samples is not working out, as you will need more good 2D samples for the area lights. Generating 32x32 arrays for each occasion where you might need good 2D samples is probably not a good idea, or is it? Though, given that you know the max ray bounce number one could make a good upper limit guess for the necessary total amount of 2D samples per pixel.
- you will also need good 1D numbers for things like rolling the russian roulette dice or picking the BRDF to sample, the amount needed is probably unknown in advance, but again, guessing a reasonable upper limit would probably work out
My immediate (and probably flawed) idea would be to create stratified sample arrays per pixel (or even for the full rendering) for dimensions 1+2 which do not necessarily match the requested total sample per pixel count, e.g. 64x64 each time, no matter the samples per pixel count. You would consume those in order, after shuffling, and if used up generate them fresh.
Other alternatives i could think of:
given number of pixel samples N, always generate N stratified samples on demand whenever needed
generate enough samples ahead of time per pixel, when running out fall back to uniform random numbers or generate new stratified samples (so eventually the same as above)
So long story short, the actual question is probably how do i properly consume those stratified samples? Are you even supposed to use such samples outside of primary pixel or area light samples? (Re)Use unused numbers per pixel sample, per full rendering? Or am i generally on the wrong path, in that those stratified samples are not meant as a replacement for well distributed random numbers?