Home Technical Talk

Lightmapper for Unity

polycounter lvl 18
Offline / Send Message
commander_keen polycounter lvl 18
I have been making a lightmap generating system for Unity for the last few days and I figured I should release something before I get bored of it and forget about it like so many other things. Heres the basic fetures:

-Render only the objects you want to by selecting multiple objects or groups of objects and do a batch render.
-Generate lightmaps on imported meshes with 2 uv channels.
-Lightmaps are generated from all lights in the scene.
-Ghetto material management, for keeping lightmapped materials updated with their source materials.
-4X modualted lightmaps for over exposure.

Download current Lightmapper for Unity
Extract contents into your Project/Assets folder.

Download Sample Project


now for the media:

If you have the Unity web player installed you can walk around in the example project here:
http://keenleveldesign.com/pimp/unitylightmaps/lightmapper_web_1.0.html
and windows standalone if you dont have the web player it also has a better camera :)
http://keenleveldesign.com/pimp/unitylightmaps/lightmapperexample01standalone.zip

unitylightmaps03.jpg

unitylightmaps04.jpg

unitylightmaps05.jpg

How to use:
-Extract lightmapperX.X.zip into your Project/Assets folder.
-Export an object from your 3d package, and make sure it has 2 uv channels. The second uv channel is what the lightmap uses. Make sure you leave a bit of bleed room around the uv islands for the lightmap.
-Add the object into the scene.
Make a material with a shader type Lightmapper>DiffuseModulate4. This is important. The standard Unity lightmap shaders wont work correctly.
-Assign the materials(s) to your model
-Add a 'Lightmapper' component to your object (Scripts/Lightmapper). This will automatically add a MeshCollider component to the object. This is nessessary for the object to cast shadows on other objects.
-Add some point lights in the scene.
-In the menu bar at the top of Unity click "Lightmapper>Bake Selection And Children". If you dont see this menu then you didnt extract it correctly.
-You should see a progress window, this could take a while with lots of lights. When its done your object should show up with a lightmap.
-Adjust the settings in the Lightmapper component on the object if the lightmap looks low res or "spotty".

Things still todo:
-Make more materials.
-Fix the problem of unwanted objects casting shadows. (you can put them in the "Ignore Raycast" layer, or add them to layer 29)
-Add support for spot and directional lights.
-Probably more

Tips:
-Keep lightmap texel density even throughout the scene to avoid artifacts on smaller objects.
-Try to use smaller lights around smaller objects. Large area lights dont work too well on small objects. Using smaller lights will also help calculation time.

Replies

  • gamedev
    Offline / Send Message
    gamedev polycounter lvl 12
    Really cool Keen. Gonna check this out this weekend. You post this over at Unity3d as well? You could probably slick it up a bit and sell this. So many people want a built in lightmapper.
  • renderhjs
    Offline / Send Message
    renderhjs sublime tool
    you scare me o_O
  • Microneezia
    Offline / Send Message
    Microneezia polycounter lvl 10
    Wow, thanks so much for releasing this! I just noticed your work in waywo and was thankful someone was making this; i didnt expect to see it so fast for public tho, I think he is right in thinking you could sell it.
  • CrazyButcher
    Offline / Send Message
    CrazyButcher polycounter lvl 20
    not that I am into unity, but it's nice that you release your lightmapper!

    I've looked into your code. And having written a similar tool for luxinia once, here is some hints towards better efficiency and higher quality results:

    raycast vs raytrace
    Don't trace from lightsource to object, but do the opposite. That is shoot a ray from every lightmap texel thru the world. You either have to rasterize the uvmesh of every node yourself, and generate worldpositions for it. Or you use a "raytrace hack". Ie you create a dummy mesh for the pyhsics engine, passing the texcoord2 as positions. Then you raytrace within the 0,1 region on that uvmesh (parallel rays perpendicular to xy plane), and you get back triangle and barycentric coordinates of the hitpoint. Using those you get the object position of that texel. Transform it with the node's matrix and you have the world position.

    That way you get a much better ratio of rays that are meaningful and contribute well (with your current approach you might have many rays hitting the same uv spots on the lightmap texture). Yes this setup takes more time to do, but once you have it, it's a huge benefit and allows to do much more cool stuff, as you gained efficiency.

    soft shadows / area lights
    instead of directly shooting from worldpos to lightpos, you can offset positions. Using the direction vector between the two, and another non parallel vector. You use the crossproduct to create a perpendicular vector to light direction. That vector you add to worldpos or lightpos. (be sure you also have random ones every time). Do an average over the result and you have soft shadows.

    ambient occlusion
    you can shoot random rays from worldpos. Ideally you take the triangles normal into account and just shoot on one hemisphere. But if you dont have the normal at hand, just brute force fire in all directions. Depending on the range of your hit (or no hit) you would give each sample a weight, at the end sum them all and you have a nice AO term.

    for approximating many random vectors in a circle, look into poison disc distribtion. It gives good results using less samples.

    do normal based lighting
    at the moment you purely light on radial falloff. That is cool as one can fake GI easily with many small lights. And if remember right, this was also the way things were done in q2 and maybe even q3. But for higher quality (depending on the style you want to achieve) using classic diffuse and ambient lighting terms might further boost quality. Then you need to have per-texel normals. Which can be derived similar to the per-texel world positions.


    All these are just suggestions and hints if you want to further enhance it, but don't put in tons of time if the current results are cool with you and serve their purpose.
  • cman2k
    Offline / Send Message
    cman2k polycounter lvl 17
    The new hotness. This is badass! You are a mad genius my friend.
  • James Edwards
    Offline / Send Message
    James Edwards polycounter lvl 18
    Sweet! Need to check this out.
  • Thomas P.
    Offline / Send Message
    Thomas P. polycounter lvl 14
    This looks quite interesting. Will have to check this later on. Not that I need it for my current project but this looks handy nevertheless. Good job!

    Thomas P.
  • Pseudo
    Offline / Send Message
    Pseudo polycounter lvl 18
    That's awesome, thanks for sharing!

    Do your materials work on the iPhone?
  • commander_keen
    Offline / Send Message
    commander_keen polycounter lvl 18
    Pseudo, the current shader doesnt run on the iphone. I may change how the material works which might make it run on the iphone and not look like total crap.

    CrazyButcher, thanks these are all very good suggestions. The original idea was to trace from texel to light, but couldnt find an easy way to do that so I gave up :P. Area lights is something I want to do and is pretty easy. For normal based lighting I think theres actually a few lines in there that attempt to do it but fail more or less. I will try to get this working better.
  • Davision3D
    Offline / Send Message
    Davision3D polycounter
    Thx a lot!
    I will try some things with it as soon as i have time.
    I hope you dont get bored and you will continue working on it! :)
  • SHEPEIRO
    Offline / Send Message
    SHEPEIRO polycounter lvl 17
  • rasmus
  • Tulkamir
    Offline / Send Message
    Tulkamir polycounter lvl 18
    Kick ass, thanks a tonne for sharing this Keen. I'm lookin forward to getting some time aside to check it out in depth. :D
  • Kawe
    Offline / Send Message
    Kawe polycounter lvl 8
    This is really cool :)
  • CrazyButcher
    Offline / Send Message
    CrazyButcher polycounter lvl 20
    keen, I might be able to help you on the texel to worldpos thing. And write a little uv rasterizer that you can make use of.
    edit: working on a luxinia tutorial for this task. lua and javascript are similar, so you shall be able to adjust the important bits for your tool.
  • CrazyButcher
    Offline / Send Message
    CrazyButcher polycounter lvl 20
    lightmapgen.jpg

    Did a rough version of the lightmapper in Lua, only collision is handled in C by ODE. Api of unity and luxinia shouldnt be too different, so in theory you should be able to follow this. The "interpolator" code is a bit rough, as I made it generic (any vectors of any length can be passed). So if you need help about it, ask, or wait until the full tutorial is done.

    Anyway for the proper tutorial I will do more effects and add plenty more descriptions. Nevertheless the current code can be found here:
    http://crazybutcher.luxinia.de/code/lua/lightmapgen.lua

    The rasterizer is based on an implementation by Diogo Teixeira, who based his implementation on this article series by Chris Hecker. It is a very robust rasterizer, doesnt create "holes" or overlaps.

    http://chrishecker.com/Miscellaneous_Technical_Articles
  • commander_keen
    Offline / Send Message
    commander_keen polycounter lvl 18
    Awesome CrazyButcher, I will have a look at that. Anyway, heres some radiosity :)
    unitylightmaps06.jpg

    And another shot. Its pretty fast if you get the settings right.
    unitylightmaps07.jpg
  • CrazyButcher
    Offline / Send Message
    CrazyButcher polycounter lvl 20
    nice work, if you really want to get down to the details, I can recommend Paul Nettle's radiosity engine (many mods for different users exist, ogre3d, irrlicht, blitz3d...)

    http://www.paulnettle.com/pub/FluidStudios/Radiosity/

    and another link with good sublinks
    http://kevinbeason.com/smallpt/
  • Funky Bunnies
    Offline / Send Message
    Funky Bunnies polycounter lvl 17
    pimp work, commander_keen
  • kr1stov
    hey!

    great work! is there a possibility to save the lightmap as an external file to do some cosmetics in photoshop?

    thx
  • brokenpoly
    Offline / Send Message
    brokenpoly polycounter lvl 9
    Wow! This looks absolutely stunning!
    Been waiting for this for a while now, so it was a pleasant surprise to see this one :)

    Keep up the excellent work!
Sign In or Register to comment.