Lighting in games can sometimes be a confusing mess of seemingly broken textures, jagged shadows, and that one corner that for some reason is too damn dark. Here’s a quick cheat sheet of everything we’ll be discussing.
90% of the time when someone asks why their lights are broken, the answer usually involves lightmap UV’s. Pretty much every model you throw into an engine will need to have lightmap UVs. This can be done within Unity or Unreal pretty easily, but larger studios working on bigger projects opt for having artists create them. Lightmap UVs are a separate set of UV unwrapped textures optimized for lightmaps. While models usually have good UVs that work well with their texture maps, these can usually cause problems for Lightmaps. This is really obvious on models that are low poly and use a color instead of a texture map. These almost never have proper UVs, as they don’t have complex textures to wrap around the model.
Once the Lightmap UVs are made, the next step is to make sure UVs are at a proper scale in the lightmaps. The scale of an object's UVs in a texture is referred to as its texel density.
For the sake of explanation, let's say that we have a cube that has a length of 1m and a texel density of 1 cm. This means that 1 cm is 1 pixel of the texture. If we were to cast a shadow on this object and bake the scene, the shadow would look super jagged up close. By increasing the texel density, you can increase how many pixels a texel gets. If 1 cm gets 10 pixels, the shadow will look much better as more pixels are used in the texture. If you want to learn more about texel density, Leonardo Lezzi has a great infographic that explains it very well. https://www.artstation.com/artwork/qbOqP
Using realistic values sounds like common sense, but many times I find people using wild values without realizing it. The most common mistake is cranking the light’s range to increase its brightness. This will very quickly provide undesired results. Set your range slightly further than the furthest surface that needs to be affected, and then increase the intensity to achieve desired brightness. It’s really easy to accidentally turn up the range instead because at first it appears to do the same thing.
If you’ve got some strange highlights in places you think they shouldn’t be, it's probably a light leak caused by your geometry. To accurately calculate how light should be blocked, an object needs normals that are visible to the intended light source. So for example, a one sided plane won’t block light coming through its back side. Or if your environment is just an inverted cube, light will leak through the edges as the engine attempts to figure out what to do. I like to solve this by extruding the geometry at least a few inches so the light has something to work with. There are many cases, including Unity’s HDRP example scene where it's easiest to have a large box around the environment geometry. If it’s closed off, the player/user will never see it. Shadow boxes are a very common solution.
Last but not least, be careful using more than one directional light. Directional lights are infinite light sources, and so shadows will behave strangely when you’ve got two directional lights in opposite directions. If your goal is to have weird, non realistic lighting, go nuts (not too nuts. There’s a limit in the engine for a reason). If you’re throwing in another directional light because the back side of a building is too dark, look into adjusting the ambient light, or shadow color within your scene/level. Alternatively you can change the light's bounce intensity.
Give our team a call on 972 299-8937 or set up a no obligation consultation through the