Lightmap calculation problems

Hi
I’m implementing lightmaps, and i’m using the tecnique described for the apparition engine, to get the light impact on a surface.

Well, briefly, what i do is the following:

First, i seek in the polygon, wich ones have the same axis coordinate, if all the X’s are equals then i work in Z/Y, if all the Y’s are equal i work in XZ, and if all the Z’s are equal i work in XY.

lets’s imagine i’m working in XY
My next step, is to find out the biggest X and the lowest X, the biggest Y, and the lowest Y.

X = BIG_X - MIN_X;
Y = BIG_Y - MIN_Y;

As i’m using 16x16 lightmaps, i’m going to get the u,v steps to scan the polygon

u_steps = X /16;
v_steps = Y /16;

for(float xx=MIN_X; xx<= BIG_X; xx=xx + u_steps)
{
for(float yy=MIN_Y; yy<=BIG_Y; yy = yy + v_steps)
{

			float position[3];

			position[0] = xx;
			position[1] = yy;
			position[2] = next_dados-&gt;z[0]; // this is from the structure where my poly is stored

// Get the distance from the light
float distancia=Distance(position,light_source);

			attenuation = (distancia*distancia) / (RADIUS*RADIUS);

			intensity = 1 - attenuation;


			Value[p] = intensity;
			p++;
		}
	}
	p=0;

To render the lightmap, i doing this:
Using normal polygon coordinates, but divided by the lightmap height/lenght.

glTexCoord2f(next_dados->u[i]/16,next_dados->v[i]/16);

Now, my lightmaps don’t look correct, they appear dark/bright where they shouldn’t.

Also, the variable Value, that is where i’m storing the values of the lightmaps, i see that for 0 i get total darkeness, 1 total darkeness, but 0.50 it’s bright!! how come ?
shouldn’t be 0, total dark, 1 total brightness?
I’m using GL_LUMINANCE!

thanks for any help

Bruno

>Now, my lightmaps don’t look correct, they appear dark/bright where they
>shouldn’t.
Give me more details. This could be because of the Value variable you describe below?

>Also, the variable Value, that is where i’m storing the values of the lightmaps, i
>see that for 0 i get total darkeness, 1 total darkeness, but 0.50 it’s bright!! how
>come ? shouldn’t be 0, total dark, 1 total brightness? I’m using GL_LUMINANCE!
Well, maybe you’re using some kind of mapping to signed bytes in GL_LUMINANCE? From the spec in msdn:
"Each element is a single luminance value. It is converted to floating point, and then assembled into an RGBA element by replicating the luminance value three times for red, green, and blue, and attaching 1.0 for alpha. "
If it’s internally converted to rgb, then why dont you build a rgb texture instead of letting the driver do a conversion?
The correct call should be something like:
glTexImage2D(GL_TEXTURE_2D.0,1,width,height,0,GL_LUMINACE,GL_FLOAT,Value);
I would rather use unsigned bytes (you need 1/4 of the main memory to store lightmaps in your engine):
glTexImage2D(GL_TEXTURE_2D.0,1,width,height,0,GL_LUMINACE,GL_UNSIGNED_BYTE,ByteValue);

Well, my Value variable is defined this way:

#define LIGHTMAP_ATTS 16
float Value[LIGHTMAP_ATTS * LIGHTMAP_ATTS];

glGenTextures(1,&Lightmaps[num_lightmap]);
next_dados->id = num_lightmap;
//Use that ID for a texture object. Set the stuff up for what we want.
glBindTexture(GL_TEXTURE_2D, Lightmaps[num_lightmap]);
glTexImage2D(GL_TEXTURE_2D, 0, 3, LIGHTMAP_ATTS, LIGHTMAP_ATTS, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, Value);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

Any problems here ?

thanks

Bruno

Well, my Value variable is defined this way:

#define LIGHTMAP_ATTS 16
float Value[LIGHTMAP_ATTS * LIGHTMAP_ATTS];

glGenTextures(1,&Lightmaps[num_lightmap]);
next_dados->id = num_lightmap;
//Use that ID for a texture object. Set the stuff up for what we want.
glBindTexture(GL_TEXTURE_2D, Lightmaps[num_lightmap]);
glTexImage2D(GL_TEXTURE_2D, 0, 3, LIGHTMAP_ATTS, LIGHTMAP_ATTS, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, Value);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

Any problems here ?

thanks

Bruno

In the line:

glTexImage2D(GL_TEXTURE_2D, 0, 3, LIGHTMAP_ATTS, LIGHTMAP_ATTS, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, Value);

Change the 3 to GL_LUMINANCE since this values use as number of channels has been deprecated and is now known as the internal format, and either change the external data type GL_UNSIGNED_BYTE to GL_FLOAT or change Value to a unsigned byte array. The data type of the array needs to match the pixel data type.

[This message has been edited by DFrey (edited 01-09-2001).]

If i change the 3 to GL_LUMINANCE, is it like this it should be?

glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, LIGHTMAP_ATTS, LIGHTMAP_ATTS, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, Value);

About changing the type of variable…, if i change from float to GLuint, i will loose the float accuracy, all the values between 0 and 1 will be rounded wither up or down to 1 or 0, and the screen will be all dark, mostly because all the values are being rounded to 0., however if i change in glTexImage2D from GL_UNSIGNED_BYTE to float, everything is dark again…, why ? what am i doing wrong ?
please help

thanks

Bruno

Correct about GL_LUMINANCE.
Also if you want to keep the array as type float, then you will have to change GL_UNSIGNED_BYTE to GL_FLOAT. If you use GL_FLOAT and it appears too dark, then your problem is either in implementing the lightmaps or in making them. I personally would change the array to unsigned byte and store the lightmap pixels in the unsigned byte [0…255] range rather than float [0…1]. Then you could load a lightmap into an external image editor too see if the resulting lightmap was really made correctly, and to make fine adjustments.

[This message has been edited by DFrey (edited 01-09-2001).]

I also notice in your algorithm, that if RADIUS is smaller than distancia, then the intensity will be negative (not really a big problem there), but oddly enough, any light, regardless of how bright it is, will reach maximum intensity if the distance is small enough. The intensity should get no brighter than the maximum intensity of the light. But that’s not your immediate problem if you are telling OpenGL that your float array is a unsigned byte array. A float is composed of four bytes, but since you are telling OpenGL the array elements are unsigned bytes, it treats every byte as a single pixel. That means it is creating 4 distinct pixels for every float in the array (up to the limits you impose). And those will all be wrong, for the most part.