Urho3D Lightmap generator

Early Merry Christmas, repo: https://github.com/Lumak/Urho3D-Lightmap

12 Likes

Update the roomScene.xml to make the baked texture seamless.

Looks great ! is there a way to bake some indirect lighting too ? Like AO and GI ? If yes or there’s EVEN a plan to implement it i will switch to this right away !

Direct lighting only:

press F5 to start the light process and once complete, technique is changed to xxLightMap and the results should look like this with indirect lighting… unless I forgot to check something in.

1 Like

Nice work, thanks for sharing :wink:

I managed to write bake indirect lighting code and capture, but what’s captured is not what I expect. It looks like just a larger version of the lightmap instead of direct+indirect+shadows. Is that what you expect?

It might help you understand if I posted some images.

edit: nvm, indirect baked texture = diffuse texture + indirect lighting. The lightmap is just indirect lighting, no texture. Anyway, indirect process is in the repo.

direct bake

lightmap

indirect bake

1 Like

Updated repo w/ bake indirect and misc. cleanup.

I wrote some test code to process solidangle color averaging in the background thread to reduce the overall build time for larger indirect lighting textures sizes, 128x128 and 256x256, and these are the kind of numbers that I’m getting in the lightmap.log file.

-------------128x128---------
[Mon Dec  4 09:13:25 2017] INFO: node7: indirect completion = 20.78 sec.
[Mon Dec  4 09:13:25 2017] INFO: node9: indirect completion = 20.79 sec.
[Mon Dec  4 09:13:25 2017] INFO: node10: indirect completion = 20.81 sec.
[Mon Dec  4 09:13:37 2017] INFO: node5: indirect completion = 33.39 sec.
[Mon Dec  4 09:14:04 2017] INFO: node8: indirect completion = 60.55 sec.
[Mon Dec  4 09:14:24 2017] INFO: node6: indirect completion = 80.01 sec.

-------------256x256---------
[Mon Dec  4 09:17:26 2017] INFO: node7: indirect completion = 81.61 sec.
[Mon Dec  4 09:17:26 2017] INFO: node9: indirect completion = 81.65 sec.
[Mon Dec  4 09:17:26 2017] INFO: node10: indirect completion = 81.69 sec.
[Mon Dec  4 09:18:13 2017] INFO: node5: indirect completion = 128.24 sec.
[Mon Dec  4 09:20:08 2017] INFO: node8: indirect completion = 243.74 sec.
[Mon Dec  4 09:21:21 2017] INFO: node6: indirect completion = 316.35 sec.

You can specify the size at line 258 in LightmapCreator.cpp:

lightmap->BeginIndirectLighting(outputPath_, 256);

Detail images:
lightmap

baked indirect

And you have to ask, is it worth creating a higher res image for indirect bake. And the answer is no.
There are obvious detail difference in the lightmap images from 64x64 to 256x256, but the diff of baked indirect images aren’t all that different.
diff image online w/ fuzz 1%

2 Likes

Really no difference when comparing the default size at 64x64.

-------------64x64---------
[Mon Dec  4 11:28:45 2017] INFO: node7: indirect completion = 5.37 sec.
[Mon Dec  4 11:28:45 2017] INFO: node9: indirect completion = 5.37 sec.
[Mon Dec  4 11:28:45 2017] INFO: node10: indirect completion = 5.38 sec.
[Mon Dec  4 11:28:49 2017] INFO: node5: indirect completion = 9.14 sec.
[Mon Dec  4 11:28:54 2017] INFO: node8: indirect completion = 14.90 sec.
[Mon Dec  4 11:29:00 2017] INFO: node6: indirect completion = 20.73 sec.
total time = 20.73 sec.
--- threaded
[Mon Dec  4 11:30:11 2017] INFO: node7: indirect completion = 5.38 sec.
[Mon Dec  4 11:30:11 2017] INFO: node9: indirect completion = 5.39 sec.
[Mon Dec  4 11:30:11 2017] INFO: node10: indirect completion = 5.40 sec.
[Mon Dec  4 11:30:14 2017] INFO: node5: indirect completion = 9.07 sec.
[Mon Dec  4 11:30:20 2017] INFO: node8: indirect completion = 14.76 sec.
[Mon Dec  4 11:30:26 2017] INFO: node6: indirect completion = 20.49 sec.
total time = 20.49 sec.

You can save about a minute when creating 256x256 image threaded, but as mentioned previously, it’s not worth it. And for this reason, I won’t be checking in my threaded test code to the repo.

I was very skeptical about the diff’d images, and looking through my code, I realized I was calling lightmap->SetSavefile(false); early on to skip updating my baked files.

True diff images:

64v128

128v256

2 Likes

Repo updated w/ solid angle color computation threaded option, and more importantly the indirect render texture is now fixed to 64x64.

Repo updated: runs 4x faster. The default scene setup now completes in ~5 secs.

Thanks 4 share… nice christmas gift :grinning:

You’re welcome :slight_smile:

Repo updated: refactored lightmap.cpp and created texturebake.cpp. This is the last update I’ll make this year.

1 Like

I’m curious: any chance this can be used with external tools such as Mitsuba or Eevee?

Doing lighting correctly is something extremely difficult and this project could benefit from being a modular way of integrating renderers, instead of trying to render things itself. That’s just my two cents, of course! Amazing effort. Learning a lot from your code, Lumak. You rock.

I’m not aware of Eevee but have studies Mitsuba about a couple of years ago. Mitsuba does generate perfect lighting images but it does this by screen space raycasts, and there are variations of raycast options, does it on the CPU, and is really slow.

My implementation is based on Hugo Elias’s Radiosity. Except, I haven’t implemented the skipping of pixels, evaluate, and interpolate part, but brute force pixel processing. And I also use hemisphere instead of hemicube that everyone who’s ever implemented Hugo’s method that I’ve seen are so keen to believe that is the best option.

Using Urho3D’s tech., indirect light processing is blazing fast. And the accuracy only depends on the lightmap/indirect light resolution that you choose.

Here’s an example of the lightmap image created at 512x512 resolution:

I never realized how accurate Hugo’s method was until I observed the cascading light and shadow at the top/left of the image and color bleeding.

3 Likes

That description above, I will have to use it on my github repo page.

I see. But isn’t speed that much of a concern when you’re baking lights? Or are you planning of generating lightmaps in realtime, similar to what Sauerbraten does?

Generating lightmaps at runtime to achieve static GI is exactly what’s happening in my demo - just skip baking textures because you really don’t need them, unless you’re wanting to remove lights from the scene and render baked images as unlit.

Speed is a concern to me. I don’t know about you but, I can remember a number of times when I’ve tried generating lightmaps in other engine/program and having to wait 40 mins. to see resulting lightmap textures with undesirable blemishes even for scenes strictly with box only type geometries.

What makes Mitsuba not work in this case is, it only does screen space processing. If you’re wanting to only do screen space, there are plenty of shaders out there that can do SSGI, of course, w/o BRDF that Mitsuba applies in its process.

edit: had to rephrase.
edit2: sry, I don’t know what a Sauerbraten is.

1 Like

Let me also mention that there is a baked scene sample in Lightmap/bakedScene.xml which demonstrates rendering bakedIndirect as Unlit w/o any lights in the scene.