Page 10 of 13

Re: Adaptive sampling improvements

Posted: Wed Apr 17, 2019 12:34 am
by alpistinho
It has to do with the scrambling pass.

When I hardcode these values, the distribution returns to look like Sobol.

Code: Select all

sobolSequence.rng0 = 0.2;//rngGenerator.
sobolSequence.rng1 = 0.7;//rngGenerator.floatValue();
sobolSequence.rngPass = 0.55;//rngGenerator.uintValue();
Using the same seed for every pixel, even though each one is in a different pass may not be the right thing to do

Re: Adaptive sampling improvements

Posted: Wed Apr 17, 2019 1:28 am
by alpistinho
I have absolutely no idea how mathematically sound this is but using the pixelIndex as the seed for the RNG seems to work...

Code: Select all

		// Initialize rng0, rng1 and rngPass
		rngGenerator.init(pixelIndex % (0xFFFFFFFFu - 1u) + 1u);
		sobolSequence.rng0 = rngGenerator.floatValue();
		sobolSequence.rng1 = rngGenerator.floatValue();
		sobolSequence.rngPass = rngGenerator.uintValue();
Uniform Sobol (25 Spp)
RGB_IMAGEPIPELINE_uniform_sobol.png
Adaptive Sobol (25 Spp avg.)
RGB_IMAGEPIPELINE_adaptive_sobol_using_pixelPass_as_seed.png
Samplecount
Screenshot from 2019-04-16 22-27-08.png

Re: Adaptive sampling improvements

Posted: Wed Apr 17, 2019 9:34 am
by Dade
Your code will produce duplicate samples on multiple GPUs and when using CPU+GPU (so there is a lot of wasted work). You need to use "seedBase + pixelIndex".

You can't also call rngGenerator.init() for every samples, the overhead is too high (check the code), your slowing the rendering too much.

Fixing the above two problems leads back to the original code :?:

Re: Adaptive sampling improvements

Posted: Wed Apr 17, 2019 9:41 am
by alpistinho
Sure, I was not proposing leaving the code like that. I am still investigating the cause and hope to find a better solution.

I am not 100% sure about what is causing the issue, but as you can see on the samples distributions I've posted, the current solution is making Sobol more like Random.

Re: Adaptive sampling improvements

Posted: Wed Apr 17, 2019 10:39 am
by Dade
alpistinho wrote:
Wed Apr 17, 2019 9:41 am
I am not 100% sure about what is causing the issue, but as you can see on the samples distributions I've posted, the current solution is making Sobol more like Random.
In theory, a sequence of (pseudo)random numbers is the same of a sequence of random numbers but I would be very suprised if the problem is really in the correlation of the sequence (pseudo)random.

The other option is that there is something going wrong with the value "seedBase", have you tried to use this code ?

Code: Select all

		// Initialize rng0, rng1 and rngPass
		rngGenerator.init(seedBase + pixelIndex % (0xFFFFFFFFu - 1u) + 1u);
		sobolSequence.rng0 = rngGenerator.floatValue();
		sobolSequence.rng1 = rngGenerator.floatValue();
		sobolSequence.rngPass = rngGenerator.uintValue();
The only difference with your code is the "seedBase +".

Re: Adaptive sampling improvements

Posted: Thu Apr 18, 2019 1:42 am
by alpistinho
Dade wrote:
Wed Apr 17, 2019 10:39 am
The other option is that there is something going wrong with the value "seedBase", have you tried to use this code ?

Code: Select all

		// Initialize rng0, rng1 and rngPass
		rngGenerator.init(seedBase + pixelIndex % (0xFFFFFFFFu - 1u) + 1u);
		sobolSequence.rng0 = rngGenerator.floatValue();
		sobolSequence.rng1 = rngGenerator.floatValue();
		sobolSequence.rngPass = rngGenerator.uintValue();
The only difference with your code is the "seedBase +".
It makes the rendering noisier again and the distribution for an arbitrary pixel I chose looks random and not Sobol.
I've had little time today and will not have much until Friday to dedicate to this issue

Re: Adaptive sampling improvements

Posted: Thu Apr 18, 2019 2:11 am
by alpistinho
Dade wrote:
Wed Apr 17, 2019 10:39 am
In theory, a sequence of (pseudo)random numbers is the same of a sequence of random numbers but I would be very suprised if the problem is really in the correlation of the sequence (pseudo)random.
I am not saying it is this necessarily, but somehow initializing rngGenerator using different values causes the distribution to degrade into a simple Random sampling.

Am I correct to assume that this seed is used to drive the RNG that draws the values used in the Cranley-Patterson rotation and the offset put into the SobolDimension function under SobolSequence::GetSample?

If I am correct, I understand why using the pixelIndex as seed will really cause the sample repetition between multiple devices, since there would be nothing to differentiate them as the pass and rngPass would be the same.

I could create a vector to hold an TauswortheRandomGenerator for each pixel, but I guess that would create an overhead of height * width * 12 bytes. That would be 96 MB for a 4K image, which is guess it's a bit too much when summed to the height * width * 4 bytes from the passPerPixel variable

Re: Adaptive sampling improvements

Posted: Thu Apr 18, 2019 9:50 am
by Dade
alpistinho wrote:
Thu Apr 18, 2019 1:42 am
It makes the rendering noisier again and the distribution for an arbitrary pixel I chose looks random and not Sobol.
But this is very strange is like saying that the this sequence of a0-aN:

Code: Select all

rngGenerator.init(1);
a0 = rngGenerator.floatValue();
a1 = rngGenerator.floatValue();
a2 = rngGenerator.floatValue();
a3 = rngGenerator.floatValue();
...
have different randomness than this sequence of a0-aN:

Code: Select all

rngGenerator.init(1);
a0 = rngGenerator.floatValue();
rngGenerator.init(2);
a1 = rngGenerator.floatValue();
rngGenerator.init(3);
a2 = rngGenerator.floatValue();
rngGenerator.init(4);
a3 = rngGenerator.floatValue();
...

Re: Adaptive sampling improvements

Posted: Thu Apr 18, 2019 11:51 am
by FarbigeWelt
But this is very strange is like saying that the this sequence of a0-aN:

have different randomness than this sequence of a0-aN:

[/quote]

Actually these are two different series of random numbers. Each init leads to slightly different randomness, if statistically evaluated. If the random generator was perfect then the randomness would be equal in both cases if evaluated over a very large number of values. Generators are biased, some more some less, enough unbiased though for a lot of applications. Very random number can be generated if init(clock) whereas clock is at least in milliseconds and two following clocks are never the same number or at least for millions of inits..

Re: Adaptive sampling improvements

Posted: Fri Apr 19, 2019 4:08 pm
by alpistinho
Hello,

I think I've found the issue.

Currently, the seed for the RNG is based on the seedBase, that is a fixed value, and on the pixelIndex inside SobolSharedSampler. The pixelIndex is incremented by SOBOL_THREAD_WORK_SIZE every time the GetNewPixelIndex is called.

This means that several seeds are used per pass, but they are always the same across passes. When uniform sampling is used, the pixels are sampled sequentially, so a given pixel always uses the same sobolSequence.rng0, sobolSequence.rng1 and sobolSequence.rngPass values across different passes.
I don't know if this is by design or not.

The adaptive sampling is used, the stochastic nature breaks this and the values uses vary across passes and somehow this leads to a worse sampling distribution.
alpistinho wrote:
Wed Apr 17, 2019 1:28 am
I have absolutely no idea how mathematically sound this is but using the pixelIndex as the seed for the RNG seems to work...

Code: Select all

		// Initialize rng0, rng1 and rngPass
		rngGenerator.init(pixelIndex % (0xFFFFFFFFu - 1u) + 1u);
		sobolSequence.rng0 = rngGenerator.floatValue();
		sobolSequence.rng1 = rngGenerator.floatValue();
		sobolSequence.rngPass = rngGenerator.uintValue();
When I used the code above, the distribution started being fixed per pixel again, restoring the original behavior.

I have to see now how to implement this without resorting to initializing the RNG all the time