Archived

This topic is now archived and is closed to further replies.

Radiosity: Cornell Box Incorrect Coloring - Emission SPD?

This topic is 4940 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am using the Cornell Box data to test my radiosity processor. I am currently using 16 wavelength bands, from 400 to 700 nm in 20nm steps. The reflectance spectra for the walls are given in small enough steps, but the emission spectrum for the light is given only at 400, 500, 600 and 700nm. How do I calculate the value to use for emission at 420nm, for example? I have tried simply linearly interpolating the given values, but the resulting image is too yellow. Thanks [edited by - bakery2k1 on May 29, 2004 7:33:19 AM] [edited by - bakery2k1 on June 2, 2004 7:49:07 AM]

Share this post


Link to post
Share on other sites
As an example, here is Cornell's reference rendering of the box:



and here is the rendering produced by my implementation, using what should be exactly the same data:



[edited by - bakery2k1 on May 29, 2004 7:36:34 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by bakery2k1
I am currently using 16 wavelength bands, from 400 to 700 nm in 20nm steps. The reflectance spectra for the walls are given in small enough steps, but the emission spectrum for the light is given only at 400, 500, 600 and 700nm. How do I calculate the value to use for emission at 420nm, for example?
I have tried simply linearly interpolating the given values, but the resulting image is too yellow.


Linear interpolation isn''t very well suited for task like this one. Emission spectra rarely included spikes or sudden linear changes in emission power, as linear interpolation will introduce (unless you are simulating the spectrum of monochromatic sources, of course, but in this case no interpolation is needed anway).

I''d suggest using a smooth interpolation method. Cosine interpolation is easy, but will deform your spectrum quite a bit. Bicubic is probably the best tradeoff between performance and quality. If you don''t care about performance (discretizing the emission spectrum of lightsources is hardly a performance critical operation, as it is done only once), then I''d suggest spline interpolation. That will get you excellent quality.

Share this post


Link to post
Share on other sites
I tried using a cubic interpolation instead, but the resulting image was not very different at all. I guess it may not be the SPD which is causing the problem. Any other ideas what it might be? Here is my code which converts the radiosity values to RGB triples:



//CIE 1964

static float Xs[16]={ 0.0191f, 0.2045f, 0.3837f, 0.3023f, 0.0805f,
0.0038f, 0.1177f, 0.3768f, 0.7052f, 1.0142f,
1.1240f, 0.8563f, 0.4316f, 0.1526f, 0.0409f,
0.0096f};

static float Ys[16]={ 0.0020f, 0.0214f, 0.0621f, 0.1282f, 0.2536f,
0.4608f, 0.7618f, 0.9620f, 0.9973f, 0.8689f,
0.6583f, 0.3981f, 0.1798f, 0.0603f, 0.0159f,
0.0037f};

static float Zs[16]={ 0.0860f, 0.9725f, 1.9673f, 1.7454f, 0.7721f,
0.2185f, 0.0607f, 0.0137f, 0.0000f, 0.0000f,
0.0000f, 0.0000f, 0.0000f, 0.0000f, 0.0000f,
0.0000f};

//Loop through faces

for(vector<SceneFace>::iterator face=faces.begin(); face!=faces.end(); ++face)
{
//Convert radiosity values to CIE XYZ color

float X=0.0f, Y=0.0f, Z=0.0f;

for(int i=0; i<16; ++i)
{
X+=face->radiosities[i]*Xs[i];
Y+=face->radiosities[i]*Ys[i];
Z+=face->radiosities[i]*Zs[i];
}

//Convert XYZ to RGB

face->color.r = 3.240479*X - 1.537150*Y - 0.498535*Z;
face->color.g = -0.969256*X + 1.875992*Y + 0.041556*Z;
face->color.b = 0.055648*X - 0.204043*Y + 1.057311*Z;

//Apply exposure calculation

float exposure=0.2f;

face->color.r = 1.0f - exp(-exposure*face->color.r);
face->color.g = 1.0f - exp(-exposure*face->color.g);
face->color.b = 1.0f - exp(-exposure*face->color.b);

}



After this, the resulting face colors are averaged to give vertex colors for Gouraud shading.

Share this post


Link to post
Share on other sites
OK, you''re using the CIE 1964 spectral tristimulus matching curves, and the standard 709/D65 matrix. Your code looks perfectly fine from here.

Hmm. I don''t see too many possibilities. From the top of my head:

* I don''t remember if the Cornell box used the CIE-1964 or CIE-1931 matching curves. Both give a different colour response. Although it would be logical to use CIE-1964, you could still try the other curves, just in case (if you don''t have the curves, let me know, I can post them).

* From your image, It doesn''t really look like a spectral shift specific to the lightsource. It''s more like a general contrast problem with the entire image. But that''s very hard to judge from an image alone. Have you tried playing around with the exposure amount ? Did you apply any gamma correction or CMS conversion for your screen ?

* Just in case some mathematical inaccuracy creeps up in your solver: supply flat spectral emission and reflectance bands for all surfaces and the light (but keep the relative emission energy). The resulting image should be 100% greyscale. If anything is even slightly coloured, you have a math problem somewhere.

* Just to be sure, try to trace over the set with a spectral spacing of 4 nm, matching the reflectance data of the Cornell box surfaces. I don''t think that you will see much difference, but it''s worth a try.

That''s all I can figure out right now. Post your results from the tests, if it still doesn''t work, we can try to dig a little deeper.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Just an idea, but can''t it have to do with the exposure value you are using?

Share this post


Link to post
Share on other sites