From Classical Radiosity to ...

Started by
114 comments, last by HellRaiZer 20 years, 11 months ago
Hello again...

You can say that i''m crazy or something, but i got bored reading all that stuff, and i quitted for a while!!! So, i rewritten my radiosity calculator, to have something to work with. Also i made some changes, from the knowledge i got so far.

So, here is how it works so far. I don''t know if this is a full implementation of an already suggested algorithm, but i think that it is a mix from some of them. The steps for calculating radiosity for the Cornel Box (a scene i mean) is :

1) Calculate lightmap UVs for every polygon in the scene and pack them(!!!).
2) Calculate lumel/patches properties given a constant density factor for U and V axis. I mean, a square which is 1x1, with a density in U equal to 2.0f and density V equal 2.0f will have total 4 lumels (that is, its lightmap will be 2x2). Density is variable before starting calculations.
3) Start radiosity loop, by finding the brightest patch/lumel in the scene. (Source)
4) Calculate potential receivers
5) For every receiver (dest), calculate a form factor from source to dest.
6) Calculate the amount of radiance arrives at dest depending on patches'' areas, dest reflectivity form factor etc.
7) Store this ff in a table for later usage (when dest is the source, and source is the dest, you dont have to recalculate this ff!!)
8) When finished with all receivers for this source, update lightmaps and render the scene (to see the progress)
9) Repeat steps 3-8 until the maximum radiosity leaving from the source is less than a given value.

here is the source for that (i hope i pasted it all!!!)

GELumel* FindBrightestPatch(void){	GELumel* tmp = NULL;	float fEnergy;	// initial energy must me a non negative small value,	// so we set it to 0.0f!!!	fEnergy = 0.0f;	// for every lumel in the scene...	for(int i=0;i<PatchList.size();i++)	{		// calculate the energy it has to give...		float tempEnergy = PatchList[i]->DeltaRad[0] + PatchList[i]->DeltaRad[1] + PatchList[i]->DeltaRad[2];				// if it is greater the the minimum energy so far, and if it 		// belongs to some polygon, set its energy to be the minimum, and brightest patch to		// itself!!!		// IMPORTANT : Only lumels inside a polygon can become sources.		// Lumels outside polygons, are only for receiving!!!!		if(tempEnergy > fEnergy && PatchList[i]->InsidePolygon)		{			tmp  = PatchList[i];			fEnergy = tempEnergy;		}	}	// if the final minimum energy if less than a given limit, then 	// no source found!!!	if(fEnergy < MinRad)		return NULL;		// else, return the source...	return tmp;}int ClassifyPolygon(GEPlane *plane, GEPolygon *poly){	int numPos = 0;	int numNeg = 0;	int i;	for(i=0;i<poly->NumVertices;i++)	{		float side = plane->ClassifyPointf(&poly->Vertex[i].GetVector());		if(side > 0.0f)			numPos++;		else if(side < 0.0f)			numNeg++;	}	if(numPos > 0 && numNeg == 0)		return GE_IN_FRONT_OF;	else if(numPos == 0 && numNeg > 0)		return GE_IN_BACK_OF;	else if(numPos == 0 && numNeg == 0)	{		if(plane->Normal * poly->Plane.Normal > 0.0f)			return GE_IN_FRONT_OF;		else			return GE_IN_BACK_OF;	}	return GE_SPLIT;}void SetupReceivers(GELumel* src){	// Clear receiver list, for a new calculation...	Receiver.clear();	if(!src)		return;	// Count number of lightmaps...	int i, numMaps = LightmapList.size();	int a, numTris;	bool triFound;	GELightmap* lm;	GEPolygon* dstPoly;	int j, k;	for(i=0;i<numMaps;i++)	{		lm = LightmapList[i];		// if the source lumel if behind first triangle''s plane (= lightmap''s plane		// then this lightmap is not a receiver.		if(lm->PolyList[0]->Plane.ClassifyPointf(&src->Pos) < 0.0f)			continue;		// Count number of triangles in current lightmap		numTris = lm->PolyList.size();		triFound = false;		for(a=0;a<numTris;a++)		{			dstPoly = lm->PolyList[a];			// if current triangle is behind source''s plane, 			// then we can''t say if this lightmap is a receiver.			if(ClassifyPolygon(&src->Parent->Plane,dstPoly) == GE_IN_BACK_OF)				continue;			// else this lightmap has some lumels visible from source.			// so set triFound to true, and break...			triFound = true;			break;		}		// If we actually found a triangle that has visible lumels 		// from source then...		if(triFound)		{			// push every lightmap''s lumel to Receiver list...			for(j=0;j<lm->Tex.Width;j++)			{				for(k=0;k<lm->Tex.Height;k++)					if(lm->Lumel[j][k].Parent)						Receiver.push_back(&lm->Lumel[j][k]);			}		}	}}int CastRay(GEPolygon* tri,GEVector3D *cStart, GEVector3D *cEnd, GEVector3D *cOut){	float t, t0, t1;	float dist;	GEVector3D normal = tri->Plane.Normal;	dist = tri->Plane.D;	t0 = - (normal.x * cStart->x + normal.y * cStart->y + normal.z * cStart->z + dist );    t1 = normal * (*cEnd);		if (!t1) 		return 0;		t = t0 / t1;		if(t <= (GE_FLOAT_PRECISION)) 		return 0;	if(t >= (1.0f - GE_FLOAT_PRECISION)) 		return 0;		cOut->x = cStart->x + cEnd->x * t;	cOut->y = cStart->y + cEnd->y * t;	cOut->z = cStart->z + cEnd->z * t;		return 1;}/*int TriangleIntersect(GEVector3D *origin, GEVector3D *dir, GEVector3D *a, GEVector3D *b, GEVector3D *c){	GEVector3D edge1, edge2, tvec, pvec, qvec;	float det,inv_det;	float t, u, v;		edge1 = *b - *a;	edge2 = *c - *a;    	pvec = (*dir) | edge2;	det = edge1 * pvec;	if (det > -EPSILON && det < EPSILON)		return 0;	inv_det = 1.0 / det;		tvec = *origin - *a;	u = (tvec * pvec) * inv_det;	if (u < 0.0 || u > 1.0)		return 0;	qvec = tvec | edge1;		v = ((*dir) * qvec) * inv_det;	if (v < 0.0 || u + v > 1.0)		return 0;	t = (edge2 * qvec) * inv_det;	return 1;}*/int Visible(GEPolygon* tri,GEVector3D *cStart, GEVector3D *cEnd){	GEVector3D c;	if(CastRay(tri, cStart, cEnd, &c))	{		if(tri->IsPointInside(&c,GE_FLOAT_PRECISION))// IntersectLineSegment(&line[0])) 			return 0;	}	return 1;}float CanSeePatch(GELumel* cSrc,GELumel *cDest){	// if src is behind dst plane, or if dst is behind src''s plane	// then there is no chance to see each other!!!!	if( cSrc->Parent->Plane.ClassifyPointf(&cDest->Pos) < 0.0f || 		cDest->Parent->Plane.ClassifyPointf(&cSrc->Pos) < 0.0f)		return 0.0f;	int i;	GEVector3D vect, tmp;	vect = cDest->Pos - cSrc->Pos;	// see if a triangle is in the way between the source and the destination lumel...	for(i = 0; i < PolygonList.size(); i++)	{	  			if(!Visible(PolygonList[i],&cSrc->Pos, &vect) )			return 0.0;	}		return 1.0;}float FormFactor(GELumel *cDest, GELumel *cSrc ) {	float R, cos0i, cos0j, FF, H;	if(!cDest->Parent || !cSrc->Parent)		return 0.0f;	FF = 0.0f;	H  = CanSeePatch(cSrc, cDest); 	if(H == 0.0f)		return 0.0f;	if(cDest->Pos == cSrc->Pos)		return 0.0f;		GEVector3D vect;	vect = cDest->Pos - cSrc->Pos;	R = vect.Normalize();	cos0i = vect * cSrc->Parent->Plane.Normal;	cos0j = - (vect * cDest->Parent->Plane.Normal);	FF = (cos0j * cos0i * cDest->Area * H) / (PI * R * R);		return FF;}void DoPass(void){	GELumel *pSrc, *pDest;	float ff, deltaRad[3];	// search for the brightest of the patches...	pSrc = FindBrightestPatch();		// if no patch has delta rad greater than the given limit	// then we are done we calculations... until we lower the limit!!! 	if(pSrc == NULL)	{		DoRadiosity = false;		AutoStep = false;//		CheckMenuItem(RadMenu,ID_RAD_AUTOSTEP,MF_UNCHECKED);		// we re-save all lightmaps, because the exposure can be changed!!!		UpdateAllLightmaps();			return;	}	// setup the receiver list, for the brightest patch...	SetupReceivers(pSrc);	// count number of receivers...	int numPatches = Receiver.size();		// if there is no lumel to receive radiance, then reset the source	// and return...	if(numPatches <= 0)	{			pSrc->DeltaRad[0] = 0.0f;		pSrc->DeltaRad[1] = 0.0f;		pSrc->DeltaRad[2] = 0.0f;		return;	}	PassesDone++;		CurrentDeltaRad = pSrc->DeltaRad[0] + pSrc->DeltaRad[1] + pSrc->DeltaRad[2];	CurrentSrc = pSrc->Parent;	// For every receiver...	for(int i=0;i<numPatches;i++)	{		pDest = Receiver[i];		// calculate a form factor between the source and the receiver...		if(FFTable[pSrc->Index][pDest->Index] == -1.0f)		{			ff = FormFactor(pSrc, pDest);			FFTable[pSrc->Index][pDest->Index] = ff;			FFTable[pDest->Index][pSrc->Index] = ff;		}		// if the form factor equals zero, then there is nothing to give 		// to that lumel, so continue with the next...		if(ff <= 0.0f)			continue;		// we precalculate this because it is needed a few times...		float mult = pDest->Reflect * ff * pSrc->Area / pDest->Area;		deltaRad[0] = pSrc->DeltaRad[0] * mult;		deltaRad[1] = pSrc->DeltaRad[1] * mult;		deltaRad[2] = pSrc->DeltaRad[2] * mult;		pDest->DeltaRad[0] += deltaRad[0];		pDest->DeltaRad[1] += deltaRad[1];		pDest->DeltaRad[2] += deltaRad[2];		pDest->Rad[0] += deltaRad[0];		pDest->Rad[1] += deltaRad[1];		pDest->Rad[2] += deltaRad[2];	}	// Pass completed!!!	// Reset the brightest patch, to be the darkest...	pSrc->DeltaRad[0] = 0.0f;	pSrc->DeltaRad[1] = 0.0f;	pSrc->DeltaRad[2] = 0.0f;	// save all lightmaps, so we can see the difference!!!	UpdateAllLightmaps();}


There are many problems with it. First of all, color bleeding doesn''t seam to work. I''ve modeled the Cornel Box in Lightwave, and i used the colors described in its specifications (link at Yann''s post). I put colors as described, and i used textures colored in the same way (in case to use multitexturing).

Problems so far.
1) Color bleeding doesn''t seam to work!
2) Form Factors are veeeeery small. With this i want to say that, when i start calculations, light''s radiosity are very big (Luminosity = 100% * Color.RGB = (255, 255, 0)), but when light give all its power, the remaining radiosity in the scene is very small. From 600 (a randome value) when light is still alive, to 50 or less when the light is done!
3) What must lumel/patch density be to make my Cornell Box look like the real thing??? I think a value of 100 lumels/world unit would be great.

Any suggestions for making it better acceptable.
I''m shutting down now. I have reading in front of me.

Thanks for the attention!!!

HellRaiZer
HellRaiZer
Advertisement
quote:
So, here is how it works so far. I don''t know if this is a full implementation of an already suggested algorithm, but i think that it is a mix from some of them. The steps for calculating radiosity for the Cornel Box (a scene i mean) is :

[...]

That lookes like PR radiosity, until you get at step 7. It''s the whole point of PR radiosity to not store the FFs, you could use simple matrix radiosity otherwise. Storing them all on a large scene will take a huge amount of memory. You''ll have to compute some FFs twice (or more) with PR, that''s perfectly normal. In the end, it''s still going to be faster than matrix radiosity.

quote:
Problems so far.
1) Color bleeding doesn''t seam to work!
2) Form Factors are veeeeery small. With this i want to say that, when i start calculations, light''s radiosity are very big (Luminosity = 100% * Color.RGB = (255, 255, 0)), but when light give all its power, the remaining radiosity in the scene is very small. From 600 (a randome value) when light is still alive, to 50 or less when the light is done!
3) What must lumel/patch density be to make my Cornell Box look like the real thing??? I think a value of 100 lumels/world unit would be great.

1) see below
2) Perfectly normal. The shot radiosity is going to drop exponentially. Your 600->50 drop is not very much at all, and drops in that range occur long before colour bleeding starts to get visible. In the end, when the solution gradually converges, you''ll get initial light to shooting ratios of 1:1000 or less. The colour bleeding is created by very subtle energy transfer, you need a certain number of iterations to see it. Actually the colour bleeding part shows you, that your radiosity engine really starts working

Another thing: Keep in mind, that you are not working with colours, but with energy. Luminosity start values will rarely begin at 255 clamped. More something like 1000+, but that depends on your scale. The exact energy of the Cornell light is specified somewhere on their page, try to use it as given.

Also, don''t forget that you''ll not see anything meaningful without using a HDR exposure system before copying the patches to the lightmap. What equation are you using here ?

3) Depends on the quality you want. For starters, try a 64*64 grid for each of the 5 walls. That will already give you a nice quality, close to the Cornell reference image.
About the Form Factor table. You are absolutly right! I don't need it. I tried it with lightmap density (5.0, 5.0), and the number of patches reached 16000. So this makes a 16000x16000 matrix which needs around 1GB of memory. And as a result, my demo didn't started at all. So i erased the FFTable, and i recalculate form factors as needed.

How i calculate initial radiosity. Because i model all my models with Lightwave i'll reference to it. I don't know if you know this prog, so i'll try to say what happens. Lightwave let you specify a luminosity value for a surface in range [0, 100]%. So for light source i set it to 100%, and for all the other polygons to 0%. Also you can specify a color for the surface, and a texture (Lightwave's optional, but not in my engine; that's why i have to load one-color textures for the walls!!!). The output values for all of these are in range (float)[0.0, 1.0].

So the equation for calculating initial radiosity for a lumel/patch is :

float RadiosityMultiplier = 255.0f;curLumel->Rad[GE_COLOR_RED] = parentPoly->Material->Color[0] * parentPoly->Material->Luminosity * RadiosityMultiplier;curLumel->Rad[GE_COLOR_GREEN] = parentPoly->Material->Color[1] * parentPoly->Material->Luminosity * RadiosityMultiplier;curLumel->Rad[GE_COLOR_BLUE] = parentPoly->Material->Color[2] * parentPoly->Material->Luminosity * RadiosityMultiplier;


I thought that a value of 255.0f for the multiplier can be fine for not exceeding the color value range. But that's can be overriden (???) with exposure. I can change it to anything, but i let it that way for now.

quote:
Another thing: Keep in mind, that you are not working with colours, but with energy. Luminosity start values will rarely begin at 255 clamped. More something like 1000+, but that depends on your scale


Do you mean that i have to make RadiosityMultiplier bigger???

Exposure. I took this from Elias's tut on exposure. It is that simple.

inline float geExpose(float light, float exposure){	return ((1.0f - exp(-light * exposure)) * 255.0f);};


where light is the radiosity value (in RGB form; three calls to this), and exposure a value in range [0.0, 1.0]. I use exposure=0.15 or something. Big values of this, make the image veeeeery bright.

Finally, lightmap's dimensions. What you think is the most proper input to the calculator? Do i have to pass to it, lets say the biggest acceptable lightmap dimensions, and let it calculate densities, or pass it UV densities and calculate lightmap dimensions??? I must say that i have problems with that. First, my lightmap dimensions aren't power of 2. OpenGL doesn't complain not DevIL do. But, is it bad for my app? Do i have to stick with power-of-2 lightmaps? Also, do i have to generate my lumels on an indexed/fixed grid? Because i tried it in the past, i must say that there are some problems with raycasting during rad calcs. Shadows appear in the middle of nowhere. To solve all that by...

1) Passing densities and let it calculate lightmap's dimensions.
2) Don't care about OpenGL memory (this is bad)!!!
3) Don't distribute lumels on a ficed grid, but calculate their positions using planar mapping!

Thanks again.

HellRaiZer

PS. I think the exposure function has something to do with the fact that my lightmaps seams to have cirles of light(???) on them! Do you now what i mean? But, that's because the main texture is a one-color texture. If it was a game-like texture it wouldn't be noticable!!!
PS2. Any thoughts on adaptive subdivision? I have no idea how to do it, so if you can help, please say it. I understand the basics of it, but the implementation (subdividing a patch, and reconstructing lightmaps from patches) seams very difficult!!

HellRaiZer

[edited by - HellRaiZer on June 14, 2003 1:04:52 PM]
HellRaiZer
Some thoughts and changes...

1) I made my exposure function a little different. Instead of having an exp(x), i changed it to pow(base, x). This way i can check the effect of base on my lightmaps'' colors. From my experience, nothing much. The shading remains the same, and the "circles of light", i said earlier, are still there!

#define E 2.7182818finline float geExpose(float light, float exposure, float base = E){	return ((1.0f - pow(base, -light * exposure)) * 255.0f);};


2) Lumel densities have nothing to do with those circles of light. I set densities so the output lightmaps have dimensions 64x64 for the walls, as you suggested, but it still seams not good. I mean, in comparison with the real Cornell Box!!!! For testing this, i made my lightmaps huge (about 256x256) and no actual change to the final image.

3) If i remember right, Cornell''s specifications describe light in terms of wave lengths and luminosity. I don''t remember reading something on light''s color. From the result, i thought it must be a dark yellow. Because, if the back wall has white as initial color, and in the final image it is yellow, light must be yellow. But how can i make it yellow, and render it in white?????

And something on HDRImaging. I searched the forum''s FAQ for this. I searched the links it has, and i reached a paper on HDRI. From its description i thought it will be fine for start. When i clicked the link to download it, a thunder hitted me on the head. 15 MB. Oh no, i can''t dl this stuff from here. Our connections are still ancient. So, if you have something smaller, and as good as this, please say it.

I think i need some kind of filtering for my lightmaps. Like Blurring or something. Because, no matter what my lightmaps'' dimensions are, i see their pixels, where boxes touches the floor. Cornell Box is a fine scene for testing radiosity, btw!!!!! What can i do for it??? Because i tried blurring them, using DevIL''s internal functions, but there are problems when blurring the border or the lightmaps. It messes it up!!!

Thanks one more time for the attention, and i hope you are still with me!

HellRaiZer
HellRaiZer
quote:
I thought that a value of 255.0f for the multiplier can be fine for not exceeding the color value range. But that's can be overriden (???) with exposure. I can change it to anything, but i let it that way for now.

When talking about radiosity, you have to keep a very important thing in mind: we are not talking about colours, but energies. The radiosity values do not have a limit, theoretically, they could reach infinity. They are only really limited to positive numbers. In practice, using floats will be fine for most cases. Hugo Elias' tutorial unfortunately treats the radiosity values as colours, which is conceptually wrong (another reason why I consider his paper as "fake radiosity"). We are not dealing with colours, we are dealing with power units per area. This becomes even more important with multi-spectral radiosity (see below). The actual conversion of the light power values to light intensity is done through the exposure function: just as light photons expose a piece of photographic film.

quote:
Do you mean that i have to make RadiosityMultiplier bigger???

That depends on your general scale. A real radiosity renderer will operate on the real units. In the real world, radiosity is power per area, and measured in Watt per square meter (W/m²). A power unit, the Watt, is energy per time: Joule per second (J/s). If you base your scale around those units, then you can take realworld light power into the system. For example, design your scale such that one 3D unit is one centimeter. Build your Cornell box at the original size. Have one radiosity unit be exactly 1 W/m². Standarize your units.

quote:
Finally, lightmap's dimensions. What you think is the most proper input to the calculator? Do i have to pass to it, lets say the biggest acceptable lightmap dimensions, and let it calculate densities, or pass it UV densities and calculate lightmap dimensions??? I must say that i have problems with that. First, my lightmap dimensions aren't power of 2. OpenGL doesn't complain not DevIL do. But, is it bad for my app? Do i have to stick with power-of-2 lightmaps?

No, you don't need to. Just pack a set of smaller lightmaps into a large OpenGL texture for final rendering. About the resolution: you can either use a fixed number of texels per distance unit, which is very easy with standarized units as mentioned above: Say you want a precision of 5mm for a lightmap lumel. In that case, that would be 2 texels per 1 3D unit (as one unit is one cm). The use of realworld units is really convenient.

The second approach is adaptive subdivision, where the grid resolution will automatically adapt. But that approach is already pretty advanced, and you should implement a working traditional system first.

quote:
1) I made my exposure function a little different. Instead of having an exp(x), i changed it to pow(base, x). This way i can check the effect of base on my lightmaps' colors. From my experience, nothing much. The shading remains the same, and the "circles of light", i said earlier, are still there!

Well, you have a lot of freedom to play with various exposure functions. They are not part of the radiosity solution, but part of the camera/eye that views the solution. There are a wide variety of different approaches possible, feel free to use the one that suits you best. I'm not sure what you mean with "circles of light". It sounds like a precision issue. Can you post a screenshot ?

quote:
3) If i remember right, Cornell's specifications describe light in terms of wave lengths and luminosity. I don't remember reading something on light's color.

The wavelength of a light defines its colour !

quote:
From the result, i thought it must be a dark yellow. Because, if the back wall has white as initial color, and in the final image it is yellow, light must be yellow. But how can i make it yellow, and render it in white?????

Heh, that's because we are talking of energies, not of colours OK, if you consider your radiosity solution, forget about colours. They don't exist. You only have power and energy. This energy is distributed over the entire spectrum, ie. it has multiple wavelengths. If you trace only one wavelength, you'll get monochrome lighting. Really professional radiosity packages trace over 20+ different wavelength bands simultaneously (an SPD = spectral power distribution). A commonly used tradeoff between simplicity and quality is to trace over 3 wavelength bands: the red, the green, and the blue band. That's what you already do. The colour spectrum of the Cornell light, and the Cornell box materials, are all give in a multi-wavelength SPD, I think with 15 bands. If you want to trace in 3 bands (ie. RGB), then you need to convert the 15 band SPD to a 3 band SPD. Google for "Spectral power distributions" and "CIE curves".

The reason why to backwall appears yellow, is because of the colour bleeding between the red and green walls (red light + green light = yellow light !). If you render the Cornell box without colour bleeding, your box will be white !

A suggestion: comment out parts of your formfactor computations, the shadows to be precise. First, try to solve the radiosity equation using fully analytic methods. That is, the full FF equation, but without testing for occlusion. Once that works, you can go shadows.

Here is an example of the Cornell box without shadows (the lightmap reslution is very low, though, so you sometimes get problems at the borders). Note that your colours will probably be a bit different, because of the different exposure function.


Oh, in case you wonder, the packed lightmap for this box look like this (packed into a 256*128 texture):


quote:
And something on HDRImaging. I searched the forum's FAQ for this. I searched the links it has, and i reached a paper on HDRI. From its description i thought it will be fine for start. When i clicked the link to download it, a thunder hitted me on the head. 15 MB. Oh no, i can't dl this stuff from here. Our connections are still ancient. So, if you have something smaller, and as good as this, please say it.

Hmm, HDRI is not the same as HDR remapping. While being used for radiosity enhancements (esp. outdoors), HDRI is not a part of the radiosity equation. HDR remapping, however, simply refers to the exposure part. You should forget about HDRI right now, it'll only make it unnecessarily complex.


[edited by - Yann L on June 15, 2003 7:23:43 PM]
For my models i try to keep them in real world units. I mean, a common bedroom can be 5m x 4m. This is 5x4 world units in my engine. I have a little problem with depth testing (running on 16-bit for better performance) so i keep 1 world unit = 1 m. So when i say about lightmap densities, 5 lumels per world unit = 5 lumels per meter or 1 lumel per 20 cm.

I haven''t thought that i must do the same thing with radiosity and energy. Because the result was some colored image (lightmaps) i couldn''t think it as energy values. I cleared it now. Thanks

Sorry about the screenshot but i have no space to upload it. With "circles of light" i mean, that lightmap''s gradient from black to white is very obvious in some cases. If you take a look at your screenshot, the way it is uploaded in this post, examine the tall block. It seams like lightmap''s gradient isn''t continues. I know this isn''t obvious on your image (the image you have on your pc), but you can see it in the uploaded one. This is what i mean.

quote:
The wavelength of a light defines its colour !


I think i learned that sometime at school, but i wasn''t able to think of it this way. Because, i couldn''t think of a way to convert a single value (wavelenght) to an RGB format!!! I''ll search for it, in Google.

Btw, my lightmaps looks exactly like yours, except they aren''t packed this way. I mean i have the same 15 lightmaps, but they are independent from its other. This is not a problem right now (polygon count is very low), but i would like to know how you do it, sometime. I think i saw a tut on this, which uses quad trees, or something, but i didn''t understood well, so i abandoned it. My way works for now!!!!!

HellRaiZer

PS. A great paper i found during my search on radiosity tutorials, is (i don''t remember the link)

"Progressive Radiosity Static Lighting for Game Engines" by FABIO POLICARPO, GILLIARD LOPES and ALAN WATT

http://www.paralelo.com.br/papers/
HellRaiZer
you always have space to upload it. on my page. go to davepermen.net, on free, and upload your pics.

yann, anything yet from your sh testings?

"take a look around" - limp bizkit
www.google.com

[edited by - davepermen on June 16, 2003 8:54:58 AM]
If that's not the help you're after then you're going to have to explain the problem better than what you have. - joanusdmentia

My Page davepermen.net | My Music on Bandcamp and on Soundcloud

quote:
Sorry about the screenshot but i have no space to upload it. With "circles of light" i mean, that lightmap''s gradient from black to white is very obvious in some cases. If you take a look at your screenshot, the way it is uploaded in this post, examine the tall block. It seams like lightmap''s gradient isn''t continues. I know this isn''t obvious on your image (the image you have on your pc), but you can see it in the uploaded one. This is what i mean.

I don''t get it. My Cornell image (the one on this page) looks perfectly continuous to me. There are obviously a few JPEG compression artifacts, but they are almost unnoticeable. I don''t understand where you see a discontinuity in the light gradients ?

quote:
Btw, my lightmaps looks exactly like yours, except they aren''t packed this way. I mean i have the same 15 lightmaps, but they are independent from its other. This is not a problem right now (polygon count is very low), but i would like to know how you do it, sometime. I think i saw a tut on this, which uses quad trees, or something, but i didn''t understood well, so i abandoned it. My way works for now!!!!!

Well, you can either use a quadtree, or a hierachical coverage map, much like a mipmap pyramid. Both will let you accelerate the finding of free space on the texture, and the exact placement position. But you can also simply use brute force (loop through all pixels, and text until no collision between the new and existing maps is found). Although this is pretty slow for larger scenes, it won''t make a difference on 17 lightmaps.

quote:
yann, anything yet from your sh testings?

Yeah. I got the rotation to work, more or less (also thanks to the AP). The results for oudoor lighting are not bad, but not as good as I expected it. But that''s probably because I still use it on per-vertex base. The next step is to replace my outdoor radmaps by SH-maps. That should solve the quality issue. I''m a bit afraid of the performance drop, though. Also, it will probably limit the system to fragment-program capable cards.

I also have a few problems with the exposure issue, when both radiosity light and SH light coincide. I could precalc the exposure, but then I''d lose the realtime HDR information on the specular parts. This is only used by a few shaders, but I''d like to keep it there. I''m currently busy with another thing, so I''ll be able to continue experimenting at the end of this week.
Thanks daveperman, i'll have this in mind.

For the moment, i'll try not to show anything, until i make "color bleeding" work.

I'm trying everything i can think of. Lights initial energy, surface reflectance, everything. But there are two problems. When i make my light's energy too big, the scene become very bright, and there is no space for yellowing. I mean, lightmaps' colors are become nearly white, and then they can't reduce the blue value, so they can't become yellow!!!! I know it sounds very crazy, but my English.....

If i make my light's energy small, and change surface reflectance, it seams that there is not much energy to distribute, and the scene remains dark!!!

Btw, i couldn't find something on Spectrum to RGB conversion! Also do you have an idea, how i can use the info from lightwave(described in a previous post), to set up correct initial radiosities???? It sounds crazy too, but i'm desperate. I must make that room YELLOW!!!!!!!

Thanks

HellRaiZer

[edited by - HellRaiZer on June 16, 2003 10:07:08 AM]
HellRaiZer
Yann, this is what i mean. The JPEG compression artifacts you see in your picture, are present in mine, when i''m running the thing. I mean, there is nothing bad with your picture, but those unnoticable artifacts occurs in my lightmaps. And they aren''t unnoticable!!!

HellRaiZer
HellRaiZer

This topic is closed to new replies.

Advertisement