Radiosity: Cornell Box Incorrect Coloring - Emission SPD?

Started by
4 comments, last by bakery2k1 19 years, 10 months ago
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]
Advertisement
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]
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.
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.
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.
Just an idea, but can''t it have to do with the exposure value you are using?

This topic is closed to new replies.

Advertisement