Closed JustinTimeCuber closed 6 months ago
With the latest changes:
Before:
Definitely an improvement in terms of speckles. Not exactly sure why they aren't completely eliminated, but I'll think about it more.
More analysis that should hopefully be pretty convincing that this is unbiased:
10 million samples, with SS=DIFFUSE
SS=OFF
:
Difference (zero difference mapped to 127 RGB value)
Looks good to me so far and the results are amazing! This PR needs a rebase now.
Some more thoughts:
I have fixed the merge conflict and changed the name to IMPORTANCE
as you suggested.
Great work! :clap: Especially all the renders and the description of the algorithm! :tada:
The problem
Chunky currently has two sun sampling methods:
![image](https://github.com/chunky-dev/chunky/assets/46458276/4cceec37-8eaf-44b0-aa3e-90946314b0b9)
FAST
, which converges quickly but does not provide accurate visuals in all scenarios, andHIGH_QUALITY
, which from my testing just seems to be a middleground betweenFAST
andOFF
- depending on the ratio betweenSun luminosity
andSunlight intensity
,HIGH_QUALITY
sun sampling can be made "wrong but fast" or "noisy but accurate" or somewhere in-between:Besides the fact that having two separate controls for sun brightness is confusing (and probably should be looked into in the future), this doesn't really solve the issue of
FAST
sun sampling being inaccurate, because in order to get accurate results, you're not really getting reduced noise anyway.Overview of the new algorithm
The idea here is to do the sun sampling as a direct part of calculating diffuse reflections, rather than as an additional ray that has to be combined with the actual diffuse ray to give a result. Without sun sampling, diffuse scattering looks something like this. Depending on the exact settings (sun size, altitude) as well as relative angle of the surface, and ignoring any obstructions, there is a roughly 1 in 1000 chance of a direct sun hit per diffuse reflection:
However, what if we biased the sample, and then corrected for it? That is, we alter the distribution to be something like this:
Then, if the ray is in the 10%, we divide its contribution by 100 (and if it is in the 90%, we multiply it by 1.11). This corrects for the bias introduced by changing the distribution. Another way to think of it is that instead of getting 1 ray of very bright sunlight per 1000 diffuse reflections, we will get 100 relatively dim ones. And notably, although we are technically getting fewer samples from the rest of the scene (and slightly amplifying those samples accordingly), the difference is rather small, in this case about 10%. And this value is configurable, so even a chance of 1% for sun sampling can improve sunlight convergence by a factor of 10 while having a negligible (0.9%) loss in quality for other light sources. This approach is a form of importance sampling.
Noise reduction examples
Generally, noise is reduced in direct and diffusely-reflected sunlight, but not in other less common effects such as specularly-reflected sunlight and caustics. Here is a scene with only diffuse surfaces, rendered with SS off (baseline), SS
A few things to note here, besides the general reduction in noise:
FAST
, and my algorithm at 1%, 10%, and 50% sample chances:FAST
sampling works pretty well and gives similar results (albeit with less yellow sunlight). However, the next example shows where this method really excels.Here is a scene that includes both diffuse and specular reflections:
![image](https://github.com/chunky-dev/chunky/assets/46458276/4bb5feab-8059-4575-bd23-38107c1d9811)
FAST
, although not quite as much) while still preserving certain effects such as reflected sunlight.Correctness
To ensure that this algorithm works as expected, I have tested it in a few complex scenes at high SPP, in comparison to sun sampling off:
I was hoping to see caustics in this render, since I had sunlight passing through water. It's possible that they are there but extremely subtle. However, just to ensure that caustics are working as expected, I ran this render:
![image](https://github.com/chunky-dev/chunky/assets/46458276/90e9f3f5-83fd-4abd-8ffb-0785600a2b13)
Things to consider before merging
HIGH_QUALITY
stay as-is, be renamed, or removed?DIFFUSE
make sense?Sun
class, should those be moved elsewhere?