Sign in to follow this  
JorenJoestar

Lightmapping what a passion!

Recommended Posts

Hello guys! Here again to finally work on the lightmapper...it taked me some time to begin, I changed city, company and life! :P I've began with a standard planar mapping...I think it is good, but I have a really simple question: how can I determine WHERE to write inside the lightmap? I mean...every triangle does not affect the whole lightmap, so I have to know where to write! It is only a matter of "point in a triangle" test? Following the code...now it is wrong because it writes on all the lightmap everytime, so it overwrite the previous results:
        int iTQuantity = (triangle quantity)
	float minU = 9999999999.0f, minV  = 9999999999.0f;
	float maxU = -9999999999.0f, maxV = -9999999999.0f;

	for(int i = 0; i < iTQuantity; i++)
	{
                int flag;
		Vector triNormal;  // face normal

		if (triNormal.X >= triNormal.Y && 
			triNormal.X >= triNormal.Z)
		{
			flag = 1;
			tCoordV0.u = pos0.y * density;
			tCoordV0.v = pos0.z * density;
			
			tCoordV1.u = pos1.y * density;
			tCoordV1.v = pos1.z * density;

            tCoordV2.u = pos2.y * density;
			tCoordV2.v = pos2.z * density;

		}
		else if (triNormal.Y() >= triNormal.X() && 
				triNormal.Y() >= triNormal.Z())
		{
			flag = 2;
			tCoordV0.u = pos0.x * density;
			tCoordV0.v = pos0.z * density;
			
			tCoordV1.u = pos1.x * density;
			tCoordV1.v = pos1.z * density;

            tCoordV2.u = pos2.x * density;
			tCoordV2.v = pos2.z * density;
		}
		else
		{
			flag = 3;
			
			tCoordV0.u = pos0.x * density;
			tCoordV0.v = pos0.y * density;
			
			tCoordV1.u = pos1.x * density;
			tCoordV1.v = pos1.y * density;

            tCoordV2.u = pos2.x * density;
			tCoordV2.v = pos2.y * density;
		}


		// Find minimum coords
		if (tCoordV0.u < minU)
			minU = tCoordV0.u;
		
		...
		
		// Find maximum coords
		
		...

		minU = floor(minU);
		minV = floor(minV);

		float deltaU, deltaV;
		deltaU = maxU - minU;
		deltaV = maxV - minV;

		tCoordV0.X() -= minU;
		tCoordV0.Y() -= minV;
		tCoordV0.X() /= deltaU;
		tCoordV0.Y() /= deltaV;

		... do also to v1 and v2

		float fDistance = - (triNormal.X * n0.X + triNormal.Y * n0.Y + triNormal.Z * n0.Z);
		Vector3f UVVector, vect1, vect2;

		switch (flag)
		{
		case 1:	// YZ Plane
			{
				UVVector.X  = - (triNormal.Y  * minU + triNormal.Z  * minV + fDistance) / triNormal.X ;
				UVVector.Y  = minU;
				UVVector.Z  = minV;
				vect1.X  = - (triNormal.Y  * maxU + triNormal.Z  * minV + fDistance) / triNormal.X ;
				vect1.Y  = maxU;
				vect1.Z  = minV;
				vect2.X  = - (triNormal.Y  * minU + triNormal.Z  * maxV + fDistance) / triNormal.X ;
				vect2.Y  = minU;
				vect2.Z  = maxV;
				break;
			}

		case 2:	// XZ Plane
			{
				UVVector.X  = minU;
				UVVector.Y  = - (triNormal.X  * minU + triNormal.Z  * minV + fDistance) / triNormal.Y ;
				UVVector.Z  = minV;
				vect1.X  = maxU;
				vect1.Y  = - (triNormal.X  * maxU + triNormal.Z  * minV + fDistance) / triNormal.Y ;
				vect1.Z  = minV;
				vect2.X  = minU;
				vect2.Y  = - (triNormal.X  * minU + triNormal.Z  * maxV + fDistance) / triNormal.Y ;
				vect2.Z  = maxV;
				break;
			}

		case 3: // XY Plane
			{
				UVVector.X  = minU;
				UVVector.Y  = minV;
				UVVector.Z  = - (triNormal.X  * minU + triNormal.Y  * minV + fDistance) / triNormal.Z ;
				vect1.X  = maxU;
				vect1.Y  = minV;
				vect1.Z  = - (triNormal.X  * maxU + triNormal.Y  * minV + fDistance) / triNormal.Z ;
				vect2.X  = minU;
				vect2.Y  = maxV;
				vect2.Z  = - (triNormal.X  * minU + triNormal.Y  * maxV + fDistance) / triNormal.Z ;
				break;
			}
		}

		Vector3f edge1, edge2;
		edge1.X  = vect1.X  - UVVector.X ;
		edge1.Y  = vect1.Y  - UVVector.Y ;
		edge1.Z  = vect1.Z  - UVVector.Z ;
		edge2.X  = vect2.X  - UVVector.X ;
		edge2.Y  = vect2.Y  - UVVector.Y ;
		edge2.Z  = vect2.Z  - UVVector.Z ;

		for (int x = 0; x < lMapWidth; x++)
		{
			for (int y = 0; y < lMapHeight; y++)
			{
				float uFactor = x * 1.0f / lMapWidth;
				float vFactor = y * 1.0f / lMapHeight;

				Vector3f newedge1, newedge2;
				newedge1.X  = edge1.X  * uFactor;
				newedge1.Y  = edge1.Y  * uFactor;
				newedge1.Z  = edge1.Z  * uFactor;
				newedge2.X  = edge2.X  * vFactor;
				newedge2.Y  = edge2.Y  * vFactor;
				newedge2.Z  = edge2.Z  * vFactor;

				lumelsPos[x][y].X  = UVVector.X  + newedge2.X  + newedge1.X ;
				lumelsPos[x][y].Y  = UVVector.Y  + newedge2.Y  + newedge1.Y ;
				lumelsPos[x][y].Z  = UVVector.Z  + newedge2.Z  + newedge1.Z ;

				float r = 0.0f, g = 0.0f, b = 0.0f;

				for (int k = 0; k < max_light; k++)
				{
					Vector3f lightVector;
					float cosAngle;

					lightVector.X  = lightpos[k].X  - lumelsPos[x][y].X;
					lightVector.Y  = lightpos[k].Y  - lumelsPos[x][y].Y;
					lightVector.Z  = lightpos[k].Z  - lumelsPos[x][y].Z;
					lightVector.Normalize ;

					cosAngle = absVector.Dot(lightVector);

					if (cosAngle < 0.0f)
						cosAngle = 0.0f;

					r += lightCol[k].R  * cosAngle;
					g += lightCol[k].G  * cosAngle;
					b += lightCol[k].B  * cosAngle;
				}

				if (r > 255.0f)
					r = 255.0f;

				if (g > 255.0f)
					g = 255.0f;

				if (b > 255.0f)
					b = 255.0f;


				lumelCol[x][y].R  = r;
				lumelCol[x][y].G  = g;
				lumelCol[x][y].B  = b;
			}
		}
	}

thanks guys!

Share this post


Link to post
Share on other sites
Since you will want to write some value to every texel of the lightmap, it is more appropriate to loop through all the texels and find the triangle given the texel position within the texture, instead of finding the texel given a triangle and a position within it.

After you've found the triangle that a given point of the lightmap lies in, you need to solve the barycentric coordinates of the point on the said triangle.

The barycentric coordinate is in the parameter space for the triangle; the coordinate is defined as uvw where each component is the distance of a given point from the opposite edge of v0 (u), v1 (v) or v2 (w) where v0, v1 and v2 are the vertices of the triangle. All components must satisfy the 0<n<1 equation in order for the point to be inside the triangle.

Once you've found the barycentric coordinates, you can interpolate between the positions of the vertices by using the barycentric coordinate components u, v and w as weights for the contribution of the positions of v0, v1 and v2. The new position would then be given by v0 * baryc.u + v1 * baryc.v + v2 * baryc.w .

If you approach this the other way - that is, given triangle and a point in it - you could interpolate the vertex texture coordinates and find the texture-space position of the point on the triangle.

---

In order to solve the barycentric coordinates given a point and a triangle (assuming point and triangle are on the same plane):

Let distU be the cartesian real distance of the tested point from edge v2-v1
Let maxDistU be the cartesian real distance of v0 from edge v2-v1
The barycentric u component is distU / maxDistU.
Repeat for v and w by defining the vertex and the opposing edge variables appropriately.

The tested point is inside the triangle if all components of the barycentric coordinate are within 0...1.

If the point is not in the triangle plane, project the point into said plane before doing the above calculations.

[Edited by - Nik02 on July 24, 2009 1:21:37 PM]

Share this post


Link to post
Share on other sites

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