I'll add some guidelines to help readers understand Benedikt Bitterli's statement "Make sure to gamma correct your images".
Gamma correcting images does not mean applying a power filter at the end.
It means working in linear space during all calculations, and finally encoding the output into gamma space.
Gamma space is the color space into which all display machines of this age expect RGB values to be presented to them.
Linear space in opposition, is the fact of working with values which are proportional to physical emissions.
Therefore, when the artist edit the values of the albedos colors of the world surfaces, and the colors of the lights of the scene, he does it in gamma space because no edition software dare to modify what the user has input and just saves as-is. So the artist was looking at something that looked good for him, while stored in gamma space.
So the first step of all rendering engine, should be to convert all human edited input to linear space first. In your case that means all sphere colors and emissions values.
Then, you do your usual raytracing, brdf evaluation, monte carlo sampling, whatever process, in HDR if possible using
float32 components if possible. (usually works nice with 128 bits SIMD as
Finally you tone filter the HDR image according to the exposure value you choose, heuristically or manually. This operation could be very simple like a
clamp. And then and only then, you encode the final image to gamma space.
The base is: a monitor will take an input value x and apply the formula x^2.2 to create the physical radiance on the output pixel.
Thus, the conversion formulas goes as follow:
linear to gamma: x^(1/2.2)
gamma to linear: x^2.2
Please note as trivia that sRGB space has a complex formula, a
if, and some offset. But viewed from afar the curve is very very close to simple gamma.
Second thing to take into account, are you sure your sampling is fair ?
You could be sampling too much in the directions that privileges more rays to reach the sky. check the uniformity of your sampling. You said you use a gaussian that seems to me like you are going to ask for bias. Just use the classic Lambert distribution sampling: https://pathtracing.wordpress.com/
this way you reduce the number of samples necessary to get a variance equivalent with a purely uniform sphere. and you also save the cosine evaluation because its embedded in the distribution.
Lastly, if your spheres are really mirrors and your GI is supposedly actually working, it will accumulate reflected energy on the ground, therefore compensating your shadows from occlusion. I even expect to see more energy than darkening in such cases.