Sign in to follow this  

Lightmapping questions

This topic is 4581 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

Hi, I am trying different ways to lightmapping but not really coming to solution. This is the code I have right now for lightmapping.
void CModel::GenerateLightMaps(LightInfo l)
{
	// this will generate the texture coords
	vector3 *pVerts = &this->m_Vertices[0];
	vector3 pos(l.m_position.x, l.m_position.y, l.m_position.z);

	for(int i = 0; i < this->m_Vertices.size(); i++)
	{
		
		vector3 v = (pVerts[i] - pos)/l.m_radius;
		this->m_lightmapCoords.push_back(v);
	}

	// this will generate the lightmaps
	const int width = 256;
	const int height = 256;
	
	GLubyte *lightmap = new GLubyte[256*256*3];
	float radius_sq = l.m_radius * l.m_radius;
	GLfloat red = 0, blue = 0, green = 0;

	for(int i = 0; i < this->m_Vertices.size(); i++)
	{
		vector4 normal(this->m_NormalVBO[i]);
		vector4 vertex(this->m_Vertices[i]);
		vector4 lightVec = vertex - l.m_position;
		lightVec.normalize();

		float diff = DotProduct(lightVec, normal);
		vector4 final = l.m_diffuse * abs(diff) * l.m_falloff ;

		red += final.x * 255;
		green += final.y * 255;
		blue += final.z * 255;

		if(red > 255) red = 255;
		if(blue > 255) blue = 255;
		if(green > 255) green = 255;
		for(int iX = 0; iX < width; iX++)
		{
			for(int iY = 0; iY < height; iY++)
			{
				if(diff < 0)
				{
					lightmap[iX * width + iY + 0] = red;
					lightmap[iX * width + iY + 1] = green;
					lightmap[iX * width + iY + 2] = blue;
				}
				else
				{
					lightmap[iX * width + iY + 0] = 0;
					lightmap[iX * width + iY + 1] = 0;
					lightmap[iX * width + iY + 2] = 0;
				}	
			}
		}
	}


	unsigned int texId = CTextureManager::GetInstance().GetTextureID("SceneLight");
	if(glIsTexture(texId))
	{
		glBindTexture(GL_TEXTURE_2D, texId);
		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, lightmap);
	}
	else
	{
		/*ILuint img;
		ilGenImages(1, &img);
		ilBindImage(img);
		ilSetPixels(0, 0, 0, width, height, 0, IL_UNSIGNED_BYTE, IL_JPG, lightmap);
		ilSaveImage("gfx/SceneLight.jpg");
		ilDeleteImages(1, &img);*/
		WriteBmp("gfx/SceneLight.bmp", width, height, lightmap);


		glGenTextures(1, &texId);
		glBindTexture(GL_TEXTURE_2D, texId);
		glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, lightmap);
		CTextureManager::GetInstance().InsertTexture(texId, "SceneLight");
	}

}


Now when I write to a file I always seem to get the same color and when I multitexture it, it doesn't look like there is any lightmapping. Probably I am doing it all the wrong way but I have tried to look at a lot of online tutorials and tried various different approaches but I am not sure if I understand it correctly. I am still unsure as to how exactly do you generate the lightmaps for a whole level. Thanks

Share this post


Link to post
Share on other sites
There are a bunch of bugs in this code.

One is you are allocating an array of bytes, and then adding floats.

Another is you are doing iX * Width + iY. I think you want to allocate an array of width * height * 3 floats, and access it with [ iY * Width + iX ) * 3 ].

Lastly, you are taking the abs of the diffuse light term, you want to do min( 1.0f, max( 0.0f, diffuse ) ).

Share this post


Link to post
Share on other sites
Quote:
Original post by SimmerD
There are a bunch of bugs in this code.

One is you are allocating an array of bytes, and then adding floats.

Another is you are doing iX * Width + iY. I think you want to allocate an array of width * height * 3 floats, and access it with [ iY * Width + iX ) * 3 ].

Lastly, you are taking the abs of the diffuse light term, you want to do min( 1.0f, max( 0.0f, diffuse ) ).


Hi,

Thanks for your reply. The reason I tried doing an abs was because I was getting diff to be less than 0.

Barring apart the the bugs, is this the correct mathematical way of going about creating lightmaps or is there another way. My main confusion is how do I change the colors into rgb triplets and save it into a file or a texture. How does the mapping for this go into a 256x256x3 image works.

Thanks

Share this post


Link to post
Share on other sites
Well, another problem is that you are calculating the whole lightmap for each vertex.

The idea is that each triangle in your mesh maps to some area in your lightmap texure. You need to keep track of where each triangle is, so it doesn't overlap its neighbors. An easy but inefficient way is to treat each triangle as a rectangle, and pack the rectangles into the lightmap.

Here is a relevant link :

http://www.blackpawn.com/texts/lightmaps/default.html

A more advanced method would put nearby triangles that are touching and facing roughly the same direction into their own rectangle together. This is called a chart. The entire lightmap is then an atlas. You can google these terms for more advanced methods, like least squares conformal mapping, etc.

Then you need to use the rectangle's packed location to create the lightmap texture coordinates, and store these in your vertex.

Share this post


Link to post
Share on other sites

This topic is 4581 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this