Lightmap-how to make all objects have same uv density?

Started by
10 comments, last by ChenMo 5 years, 9 months ago

I am implementing baking in our engine.I met a problem about how to assignment per object uv in lightmap atlas.

I am using UVAtlas to generate lightmap uv, most unwrapped mesh has a uv range [0, 1), no matter how big they are. I wanna them have same uv density so to packing them well in lightmap atlas.I have tried thekla_atlas to do the same thing too, but it seems that it can not unwrap uv according mesh size.

As far as I can see, unwrapping uv coordinates using its world space can solve this, all meshes share a same scale.But I don't hope to spend a lot of time to write these code and debug them.I am wandering is there exist some methods I don't know that can scale each lightmap uv to a same density.

Thanks in advance. : )

Advertisement

I think this should work:

Call UVAtlasPartition()

Scale the charts 

Call UVAtlasPack() - or implement your own packing.

 

To scale the charts, loop over all triangles to calculate the average scaling factor between UV and world space.

Triangle area is simply fabs((v1-v0).Cross(v2-v0).Length() / 2) if you don't know. From this it's easy to calculate a global scaling, probably like so:

 

for all triangles

{

areaSum3D += triangle.worldSpaceArea;

areaSumUV += triangle.UVArea;

}

float scale3DtoUV = sqrt(areaSumUV / areaSum3D);

float globalFactor = scale3DtoUV /  yourTargetScale; // or vice versa? i'm so dump with divisions...

 

After that multiply all UVs by globalFactor.

 

I am so happy to saw a good and strightforward way to finish this work. And I think I have got it because of your post. Mostly it can work well I think, although how to calculate the area of a triagnle I have never met ever before. I will implement it as you metioned on Monday, and I think there is a little detail to do e.g. the parameter about streching and so on.Thank you @JoeJ very much, and I will maintain this thread until I have got all over the work.

I hope it works as expected. In the worst case it rescales UVs itself while packing to maximize texture space utilization. :( But i don't think so. 

The other thing i missed would be an option to tag edges to become seams. Currently the tool produces bad results for something simple like a cube: 3 sides get merged to one chart resulting in heavy distortion around the shared vertex, no matter what stretching parameter i've used. I assume results are generally bad for something like low poly architecture. To fix it, probably it works to split hard edges and duplicate vertices before processing with UV Atlas. 

As you mentioned about packing, I hope it can pack well according to the uv value after scaled.I will try it out.

I have taken notice of the output vertex count after creating atlas method called,it incrementd than input vertex count, and then I invalidated optimizing when load mesh, as a result, no vertex was merged, and I don't need to reorder triangle index after generating uv atlas.Both the input and the output mesh now have the same vertex count and triangle list.I think doing so may help you resolve the bad partition problem, or merge some edges manualy to control the chart count.My testing mesh has 100629 vertices and there exists about 400 charts in generated uv atlas.

I have also tried out lightmap uv generating in Unreal, it has a better result than UVatlas looks like.The charts's distribution is neat.I think I would not learn how to do it from it's source code unless I can not got a accectable result from UVAtlas.

2 hours ago, ChenMo said:

I have also tried out lightmap uv generating in Unreal, it has a better result than UVatlas looks like.The charts's distribution is neat.I think I would not learn how to do it from it's source code unless I can not got a accectable result from UVAtlas.

I assume Thekla has tighter packing (brute force method) than UV Atlas (Tetris method IIRC). If you need really tight packing it might be worth to try. Personally i have only used UV Atlas to compare it against my own work. I came up with a chart relaxation algorithm that works like soft body simulation (using triangle constraints to make them try keeping their original shape). My algorithm produces almost the same output as UV Atlas. I have a little less distortion in some cases but it's not noticeable, so UV Atlas is high quality to me in this regard.

The hardest problem is the segmentation. But if you already have a UV channel with artist made UV seams, UV Atlas needs to add only a small number of additional seams if at all. If that's what you mean above, be aware there is no guarantee input and output vertex count remain equal: Even if you accept high distortion, it may decide to add seams to make charts topologically equivalent to a disc.

However, if you don't have UV seams available and results are not good enough, we could talk about better segmentation in more detail (but that's some work! - try to avoid it ;) )

I'm so happy to see you have worked so deeply on this work. I have not worked deeply till now.

I will obersve the packing result fomr UVAtlas and Thekla, and take care of the input and output vertex count.

As you mentioned, UV atlas can work well if I have added additional seams info into input mesh.I don't hope to make our artists to do more work than before, so I will spend some time to solve the segmentation probram.

I will do the partition work first tomorrow, and then next, aha, there is some work waiting me to do.I am so happy I can communicate with you further and I will share my experience here next. : ).

Hi there.

Since last post has past 20 days.I have done some work on our lightmap baking project, and now I will share some experience here about this thread.

 I have done as JoeJ said before:

Call UVAtlasPartition()

Scale the charts 

Call UVAtlasPack() - or implement your own packing.

Too sad it generate the same chart size(of the whole mesh) after packing no matter how I scale the charts.So I give UVAtlas up, and try to use thekla_atlas.

Now thekla_atlas works well expect few meshes. I will debug it in the feature.I also processed the first colocal index info to made triangles connected as much as possible.If you want to know more details about this, see this https://github.com/Thekla/thekla_atlas/issues/18, the author answered the question about this.

I am going to solve the problem about seams now. : )

Hi @JoeJ, it has passed some time since we talked about this thread last time.I have been working on our lightmap project these days.

Because you had mentioned the problems about seams, and I found a useful method and implementation post by Sylvan: https://www.sebastiansylvan.com/post/LeastSquaresTextureSeams/, I hope this may help you. : )

I have injected it into our project, and it works well after some necessary changes.Here are two images which with seams and another one after stitched.

before.png.67d7d9319e3cafc9f29c93e35c3ee3fb.png

 

after.png.d7a9821c00cbc585c38dace4baf79079.png

41 minutes ago, ChenMo said:

Because you had mentioned the problems about seams, and I found a useful method and implementation post by Sylvan: https://www.sebastiansylvan.com/post/LeastSquaresTextureSeams/, I hope this may help you. : )

Thanks! That's definitively an alternative in case of failure on the global parameterization i'm working on. I've thought about something like this, but would not have assumed it works so well. I think i can at least utilize this for higher mip levels where my solution will cause artefacts, if not for everything. Thanks again!

 

This topic is closed to new replies.

Advertisement