Spectral path tracing - image color/brightness incorrect I implemented a spectral path tracing using physically base BRDF models such as Oren-Nayar,Specular Reflection and Transmission, Lambertian. All calculation in the path tracer uses standard illuminant and macbeth color checker SPD, spectral power distribution. The result of the path tracer for each pixel is the SPD obtained as a sum of SPD obtained from each sample calculated by the pat tracer. This SPD is then converted to CIE XYZ color and to RGB. The result scene obtained is the following one (in this example taking 500 samples per pixel):



As you can see, everything seems fine, except for the brightness/luminance of the scene. Every object in the scene is darker than it have to be. The floor and the front wall of the cornell box in the scene must be white and neutral8 (from macbeth color checker), but they are dark gray.
The following method is the one that trace the samples for a pixel of the path tracer:

Vector3D PathTracer::getPixelColor(const Ray&amp; ray, int bounce) {

    Spectrum&lt;constant::spectrumSamples&gt; L(0.0f);
    int numberOfSamples = 500;
    float sampleWeight = 1.0f/(float)numberOfSamples;

    for (int i = 0; i &lt; numberOfSamples; i++) {

        Spectrum&lt;constant::spectrumSamples&gt; spectrumSample = trace(ray, bounce);
        L = L + spectrumSample * sampleWeight;
    }

    Spectrum&lt;constant::spectrumSamples&gt; Li = scene-&gt;light-&gt;spectrum;

    ColorMatchingFunction* colorMatchingFunction = new Standard2ObserverColorMatchingFunction();

    //Get tristimulus values.
    Vector3D tristimulus = CIE1931XYZ::tristimulusValues(L, Li, colorMatchingFunction);

    //Convert tristimulus to sRGB.
    Vector3D color = CIE1931XYZ::tristimulusTosRGB(tristimulus);

    //Apply sRGB gamma correction.
    sRGB::sRGBGammaCorrection(color, GammaCompanding);

    //Convert to standard 0 - 255 RGB value.
    sRGB::sRGBStandardRange(color);

    delete colorMatchingFunction;

    return color;
}


As you can seen, I already apply a gamma correction to the color obtained. 
Do you have any idea why my image rendered is so dark? My concerns are in the part where I convert the SPD sum, obtained from the samples, into RGB color. Do you see any error? Am I missing something? Do I need other operation to execute a correct conversion from the SPD obtained from the sampling to an RGB color?



To avoid to write a too long question, I will link the main classes used by the path tracer for the calculation:


Lighting/shading class used to recursive calculate the rendering equation https://github.com/chicio/Spectrum-Clara-Lux-Tracer/blob/luminance/SCLT/Shading/PathBRDF.cpp 
CIE XYZ conversion https://github.com/chicio/Spectrum-Clara-Lux-Tracer/blob/luminance/SCLT/Color/CIEColorSpaces/CIEXYZ.cpp
sRGB utils https://github.com/chicio/Spectrum-Clara-Lux-Tracer/blob/luminance/SCLT/Color/sRGB.hpp


The other files/classes used are all on this repository (branch luminance)

https://github.com/chicio/Spectrum-Clara-Lux-Tracer/tree/luminance



Thanks you all guys, I hope someone could help me.
The problem lies mainly in CIE1931XYZ::tristimulusValues() function, where you normalize the resulting color to the luminance of your illuminant which causes that directly observed light source has luminance 1, but everything else is much darker. That is a nice thing to do if you just want to visualize colours of various reflectance spectra under a given illumination, but is probably not the best thing to do in a global illumination renderer.

To be more specific, you cannot expect a reflectance profile to be rendered always completely white just because it reflects all incident energy (constant spectral reflectance equal to 1 everywhere). Neglecting the material directional properties (BSDF, etc.), the properties of the light reflected from a point depend both on reflectance spectral profile of the material, and on the spectral and angular properties of the incident light. The incident light therefore depends not only on the SPD of the illuminant used for your light source, but also on its size and distance from the shaded point. The points closer to the light source will be brighter, while distant points will be darker.

I would suggest removing the luminance normalization in your Spectrum-to-XYZ conversion completely and then adjusting the overall brightness of your scene by multiplying the normalized SPD of the used illuminant (D65 in your case) with some brightness parameter. Whether you multiply it before rendering, during rendering or during the XYZ conversion step is completely up to you. The choice shouldn't affect the result.