Page 1 of 1

Lightmap calculation, bleeding issue

Posted: Wed Mar 18, 2009 6:30 pm
by nickle
Dear all,

I implemented the lightmap calculation algorithm. It kinda works.

1. I create a individual mesh.

2. for each face of the original mesh,

2a. I create a meshbuffer and add to the new mesh
using 'S3DVertex2TCoords' for each vertice.

2b. I calculate the light map UV coordinates and all the
lumels positions.

2c. I calculate the light rgb value for each lumel using
the simple N.L lighting model for each static light
and assign each lumel with that value.

2d. Blur the current face's calculated lightmap.

The problem is for invalid lumels handling. I will illustrate using some pictures.

The result is like following if I set all the invalid lumels to red color in step 2c.

Image

Then I tried to set the invalid lumels to the closest valid lumel color, the result is

Image

It doesn't solve the bleeding problem.

What if I also sample the invalid lumels? The result is

Image

It reduced the diagonal edges' bleeding greatly, but still the horizontal and vertical bleeding problems never get away.

Can anyone suggest me a way to solve this problem? Thanks..

the above results[/img]

Posted: Thu Mar 19, 2009 8:34 am
by BlindSide
Are you using per face normals?

Posted: Thu Mar 19, 2009 10:45 am
by nickle
Hi BlindSide,

Thank you for the reply... Yes, I am using per face normals.. and for the above cases. The mesh is just a simple hillplanemesh with 3x3 resolution. I think the normals are all vector3df(0,1,0) for both vertices and faces. The light is positioned at vector3df(0,4000,0). Each light map is 16x16.

Posted: Fri Mar 20, 2009 4:32 am
by BlindSide
I'm afraid I don't quite get the "Invalid Lumels" problem. I've got a software raytracer and all I have to do is a basic nDotL operation for each pixel and I get accurate lighting. The fact that the invalid lumels are appearing at the edges between the triangles made me think it had to do with per vertex normals but I guess that's not the case. Does blurring have anything to do with it?

Btw this is all very interesting I've been thinking about writing a lightmapper myself for some time.

Posted: Fri Mar 20, 2009 5:09 am
by nickle
I sent a email to your gmail box - "monstrobishi@gmail.com" :wink:

Posted: Fri Mar 20, 2009 7:50 am
by Steel Style
Hey I think that bluring is the real problem like it's per face bluring the horizontal and vertical edges are blured and so you are getting strange value with offset. Exemple for a 256² texture, the texcoord(0,0) is blured with the (0,1) and the (0,255) if you didn't clamp blur.

So I actullay recommend you to not blur edges or bluring the whole mesh at same time.

Posted: Sat Mar 21, 2009 9:48 pm
by omaremad
Looks like a bilinear issue, can you show us your light map texture? The lightmap may need "padding".

Posted: Mon Mar 23, 2009 10:24 am
by BlindSide
If the triangle UVs on the lightmap are not side by side, the black part could be bleeding into the triangle's area because of bilinear filtering like omaremad suggested, and the blurring would make this even more obvious. I ran the example on my end and printed the result, and it seemed there was some bleeding around the borders of the image. This was not caused by bilinear or the blurring though, so it may have something to do with the accuracy of the UV calculations. I only used a cube mesh scene node, I've yet to try it on something that doesn't have identical UVs on each face. Can I have a look at the mesh you used?

Also to save a few instructions you can do:

Code: Select all

float lightDist = staticlights[j]->getPosition().getDistanceFrom(lumels[iX][iY]);
lightvector /= lightDist;
Instead of:

Code: Select all

float lightDist = staticlights[j]->getPosition().getDistanceFrom(lumels[iX][iY]);
lightvector.normalize();
What are your final plans for this? Are you going to extend it to a full featured global illumination lightmapper?

Cheers

Posted: Mon Mar 23, 2009 4:06 pm
by nickle
Yes, accuracy of UV calculations are causing the problem. I have been thinking of ways to adjust the UVs like

if(UV < 0.1) UV += epsilon;
if(UV > 0.9) UV -= epsilon;

Although it will eliminate the black border, the result is not realistic and still can clearly see the border difference.

The mesh I am using is a Hillplane mesh.

IMesh * mesh = smgr->addHillPlaneMesh("planeH", dimension2d<f32>(15000,15000), dimension2d<u32>(4,4))->getMesh(0);

The reason why I decide to employ the lightmapper is my mesh is created on the fly, so cannot use external lightmapper solutions. Although a per-pixel lighting shader can also do it in real-time, however I have already used XEffect to shadow mapping, for real-time soft shadow, if + per-pixel lighting for each lights (lamp) since there will be many lights in the scene, it will be unpractical.

So I am now doing experiments to implement the algorithm. If the result is decent, yes, I am willing to extend it to a full featured GI lightmapper.

Posted: Mon Mar 23, 2009 7:32 pm
by BlindSide
It's nicer to do:

Code: Select all

UV = core::clamp<f32>(UV, 0.01, 0.99);
:wink:

Posted: Thu Mar 26, 2009 7:23 am
by puh
nickle: could you post your code for lightmap calculation for public use? Im very interested in this for example...