This tutorial is all about lightmaps, which are the high-quality light baking method in Unreal. The first half of the tutorial describes how to use lightmaps on CSG and existing assets inside Unreal. The second half explains how to create lightmaps for your own meshes in Maya or Max. You can obviously skip that section if you don’t plan on creating your own models.
When you bake lighting on your scene, the lighting data gets stored into one or more images called lightmaps. Create a test scene now (or open an existing scene) that’s a simple CSG room with a light in it. Something like this.
Save your scene (call it DM-LightmapTest.ut3) and bake lighting. Now look in your Generic Browser, and you’ll see a package named DM-LightmapTest. If you select it, you’ll see four texture images in it – these are the lightmaps that got baked for your cube. (I won’t go into why there are four of them – the reasons are technical and they won’t affect your work.) If you create a bigger level, the lightmaps will be bigger because they cover more surface area. Pretty simple.
Now switch back to the main editor window and click the “Lighting Only” button in your perspective viewport. The checkerboard goes away and you’re left with just the lighting. But notice it’s a little blotchy – that’s because there’s not a lot of detail in the lightmap. (After all, those images in the generic browser were pretty small.)
Ok, maybe it’s not that obvious. It’ll be much more clear if we put a static mesh in the world that casts a shadow on the wall. In the HU_Deco3 package there’s a fire hydrant prop (named S_HU_Deco_SM_FireHydrant01.) Place that in the world between your light and the wall. It’s a pretty small prop, so scale it larger, at least 4x size.
If you bake lighting you’ll see a big blurry shadow on the wall. That’s the effect of having a low-detail lightmap.
Let’s look at how to increase this detail.
Go back into lit mode and select the wall that has the blurry shadow on it. Open up the Surface Properties window by going to View->Surface Properties (or by hitting F5.)
We’ve covered most of these settings in an earlier tutorial, but let’s look at the “Lighting” section. Specifically the “Lightmap Resolution” parameter.
A setting of 32 means that there’ll be one lightmap pixel every 32 units. If we want more detail (and we do!) we can make that number smaller. Set it to 4 and bake again. You’ll notice the bake takes much longer, but you’ve got a much more obvious shadow from the fire hydrant. (If you try setting the resolution to 1, it may take over a minute to bake, but the results look even better.)
Go back to the Generic Browser and find your map. You’ll notice some new lightmap textures have been created (and the old ones may still be hanging around too – Unreal will clean those up later.) If you look closely at your lightmap, you can see one big square with a shadow of the fire hydrant on it, and five tiny blurry squares. That adds up to the six sides of your room.
And that’s about it – if you need more detail, set the Lightmap Resolution to a lower value, but keep in mind your bake times will suffer.
Baking lighting on Static Meshes is a little more versatile than on CSG geo. By default, all static meshes use Vertex Lighting – instead of baking into an image, light values get baked into the vertices that make up the geometry, and lighting is blended across the surface.
In my map there’s kind of a weird hard shadow near the top of the fire hydrant.
If I overlay the wireframe on the image (Photoshopped for clarity) you can see that the shadow falls right along one of the mesh’s edges. That’s effectively the result you get from vertex lighting.
But lots of meshes in Unreal are set up so that you can put a lightmap on them too, and this fire hydrant is one of them. Open up the mesh in the Generic Browser and look at the LightMapCoordinateIndex value. If it’s “1”, then the mesh is probably set up for lightmaps. If it’s “0”, it probably isn’t.
So how do we actually turn on the lightmap?
Close the Static Mesh Editor, select the fire hydrant in the scene, and open up its properties (hit F4.) Open up StaticMeshActor, StaticMeshComponent, scroll all the way to the bottom, and open the StaticMeshComponent sub-category.
Right now, “bOverrideLightMapResolution” is checked, and “OverriddenLightMapResolution” is set to 0. The “0” means it’s using vertex lighting.
On CSG surfaces a smaller number meant more detail – that’s because the number specifies how far apart lightmap pixels will be calculated. On a static mesh, you control the size of the lightmap image directly. If you type “4”, it’ll calculate a 4x4 image to paint the lighting onto, which definitely isn’t enough detail. (You’d get better results with vertex lighting!)
Change the number to 64 and bake lighting. You’ll see that the hard lines went away, and lighting generally looks better. You can go higher to get even more precise results, but again, baking will start to take a lot longer and for an object this small it’s probably not necessary.
If you open up the Generic Browser again and look at your map, you can see that the lightmap updated again. It’s got the six sides from the room, plus an additional patch of scattered detail – that’s the lightmap for your fire hydrant!
So now you know how to control lightmap detail on your CSG surfaces and static meshes. But what settings are appropriate?
The general rule is to go as low as you can. If your mesh looks good enough with vertex lighting, use vertex lighting. If your brush looks good enough with the lightmaps set at 32, leave them there.
Any time you increase detail on lightmaps, there are three consequences.
<![if !supportLists]>1) Bake times go up.
<![if !supportLists]>2) Your map gets bigger, which means it takes longer to download and longer to load.
<![if !supportLists]>3) Your map takes up more memory. If it gets too big, it may not load on some systems or on PS3.
So be careful!
If you create your own environment props you may want to add lightmaps to them. Setting this up is pretty simple. All you need to do is add a second UV channel to your mesh, and make sure the UVs follow these guidelines
<![if !supportLists]>- The UVs fit completely within 0-1 texture space
<![if !supportLists]>- The UVs don’t overlap each other.
The best way to do this is to create the UVs in your 3D package (Max or Maya), but we can also auto-generate lightmap UVs inside Unreal. Let’s look at how to do this.
Create a sphere in your 3d package and import it. Double-click the mesh to open up the Static Mesh Editor. Go to View->UV Overlay and you’ll see the default set of UVs.
To create the second UV set, go to Mesh->Generate Unique UVs. Change the “UV Channel …” parameter to 1 and hit OK.
Now change the LightMapCoordinateIndex to 1, and you’ll see the result of the auto-UV generation.
These aren’t the best results – there’s a lot of unused space, and there’s a big uneven seam surrounding the mesh. So let’s look at how to create lightmap UVs in your 3D program. We’ll cover Max and Maya separately, so scroll down to the section that applies to you.
I’m using Max 9 for this demonstration, but the process is the same in any version.
To start, create a sphere. Switch to the Modify tab, and under the Modifier List choose UVW Map.
Switch to Spherical mapping. The key to getting lightmap UVs to work is to change the Map Channel parameter to 2. (This creates a second set of UVs that will be used for lightmapping.)
This should create a good set of UVs that don’t overlap, but we still need to make sure they fit into 0-1 space. Go back to the Modifier List and add an Unwrap UVW modifier. Change the Map Channel to 2, hit “yes” in the dialog that pops up, and hit Edit.
In this case things actually look pretty good, so we don’t need to make any changes. (There are no overlaps and everything is in 0-1 space.) Close the window, save your work, and export the mesh like normal. Import it into Unreal. Open up the Static Mesh editor and set the LightMapCoordinateIndex to 1. Turn on UV Overlay, and you can see the results are the same as you set up in Max.
That’s it! You’re ready to bake lightmaps on this mesh.
This process should be pretty much the same regardless of which version of you’re using, but some of the menus have changed places. These screenshots were taken in Maya 8.5.
To start, create a sphere mesh. Under the Create UVs menu, choose Create Empty UV set. The UV set name doesn’t matter.
Open up the marking menu on your sphere, select UV Sets, and select the second set.
Now any UV work we do will be applied to the second UV channel. At this point you’d lay out the UVs for your mesh, but for this test, just apply spherical mapping.
Now open up the UV Texture Editor so that we can verify the UV layout.
In my case it looks like there’s no overlapping, which is good, but the UVs fall outside of 0-1 space, so lighting wouldn’t bake right.
Scale the UVs down and center them so that they fill the gray box as completely as possible. (If this were “for real”, I’d reconnect the triangles at the top so that I can fill up the entire UV space, but for now this is fine.)
Save your file, export the sphere, and bring it into Unreal. Open up the Static Mesh editor and set the LightMapCoordinateIndex to 1. Turn on UV Overlay, and you can see the results are the same as you set up in Maya.
That’s it! You’re ready to bake lightmaps on this mesh.
Here are a couple additional pointers you can use to set up good lightmap UVs.
Follow the rules – no overlaps, and stay in 0-1 space. Your bake will look broken if you break the rules.
Always fill the full UV space. You may have to stretch the UVs a little, but stretching lightmap UVs a little doesn’t normally hurt..
Don’t let UV clusters get too close to each other. If there’s only a tiny distance between UV clusters and you bake a low-res lightmap, some light will bleed between one surface and another.
UV density doesn’t need to be uniform. If certain parts of the mesh are less important (like the bottom), their UVs can take up a lot less space relative to the rest of the mesh.
Seams in lightmap UVs WILL be visible. Any time there’s a seam, you’ll get an obvious line in the lighting. So if a surface of your object is supposed to be contiguous, do everything you can to stitch UVs together, even if it means some stretching. The “Relax UVs” tools work really well when you’ve stitched your UVs together.
Automatic mapping may seem good enough, but hand-tuning UVs is usually worth it. If the lighting on your mesh looks bad, your mesh looks bad. Spend the extra 10 minutes and do it right.