Unity Manual

Light troubleshooting and performance

Lights can be rendered using either of two methods:

Vertex lighting calculates the illumination only at the vertices of meshes and interpolates the vertex values over the rest of the surface. Some lighting effects are not supported by vertex lighting but it is the cheaper of the two methods in terms of processing overhead. Also, this may be the only method available on older graphics cards.

Pixel lighting is calculated separately at every screen pixel. While slower to render, pixel lighting does allow some effects that are not possible with vertex lighting. Normal-mapping, light cookies and realtime shadows are only rendered for pixel lights. Additionally, spotlight shapes and point light highlights look much better when rendered in pixel mode.

Comparison of a spotlight rendered in pixel vs vertex mode

Lights have a big impact on renderingThe process of drawing graphics to the screen (or to a render texture). By default, the main camera in Unity renders its view to the screen. More infoSee in Glossary speed, so lighting quality must be traded off against frame rate. Since pixel lights have a much higher rendering overhead than vertex lights, Unity will only render the brightest lights at per-pixel quality and render the rest as vertex lights. The maximum number of pixel lights can be set in the Quality window for standalone build targets.

You can favour a light to be rendered as a pixel light using its Render Mode property. A light with the mode set to Important will be given higher priority when deciding whether or not to render it as a pixel light. With the mode set to Auto (the default), Unity will classify the light automatically based on how much a given object is affected by the light. The lights that are rendered as pixel lights are determined on an object-by-object basis.

Lighting window statistics

The bottom of the Lighting window displays statistics showing important metrics with regard to run time performance. See documentation on the Lighting window for more details.

Shadow performance

Realtime shadows have quite a high rendering overhead, so you should use them sparingly. Any objects that might cast shadows must first be rendered into the shadow map and then that map will be used to render objects that might receive shadows. Enabling shadows has an even bigger impact on performance than the pixel/vertex trade-off mentioned above.

Soft shadows have a greater rendering overhead than hard shadows but this only affects the GPU and does not cause much extra CPU work.

The Quality window includes a Shadow Distance value. Objects that are beyond this distance from the cameraA component which creates an image of a particular viewpoint in your scene. The output is either drawn to the screen or captured as a texture. More infoSee in Glossary will be rendered with no shadows at all. Since the shadows on distant objects will not usually be noticed anyway, this can be a useful optimisation to reduce the number of shadows that must be rendered.

A particular issue with directional lights is that a single light can potentially illuminate the whole of a sceneA Scene contains the environments and menus of your game. Think of each unique Scene file as a unique level. In each Scene, you place your environments, obstacles, and decorations, essentially designing and building your game in pieces. More infoSee in Glossary. This means that the shadow map will often cover a large portion of the scene at once and this makes the shadows susceptible to a problem known as “perspective aliasing”. Simply put, perspective aliasing means that shadow map pixels seen close to the camera look enlarged and “chunky” compared to those farther away. Although you can just increase the shadow map resolution to reduce this effect, the result is that rendering resources are wasted for distant areas whose shadow map looked fine at the lower resolution.

A good solution to the problem is therefore to use separate shadow maps that decrease in resolution as the distance from camera increases. These separate maps are known as cascades. From the Quality window, you can choose zero, two or four cascades; Unity will calculate the positioning of the cascades within the camera’s frustum. Note that cascades are only enabled for directional lights. See directional light shadows page for details.

How the size of a shadow map is calculated

The first step in calculating the size of the map is to determine the area of the screen view that the light can illuminate. For directional lights, the whole screen can be illuminated but for spot lights and point lights, the area is the onscreen projection of the shape of the light’s extent (a sphere for point lights or a cone for spot lights). The projected shape has a certain width and height in pixels on the screen; the larger of those two values is then taken as the light’s “pixel size”.

When the shadow map resolution is set to High (from the Quality window) the shadow map’s size is calculated as follows:

Directional lights: NextPowerOfTwo (pixelSize * 1.9), up to a maximum of 2048.

Point lights: NextPowerOfTwo (pixelSize * 0.5), up to a maximum of 512.

If the graphics card has 512MB or more video memory, the upper shadow map limits are increased to 4096 for directional lights, 2048 for spot lights and 1024 for point lights.

At Medium shadow resolution, the shadow map size is half the value for High resolution and for Low, it is a quarter of the size.

Point lights have a lower limit on size than the other types is because they use cubemapsA collection of six square textures that can represent the reflections in an environment or the skybox drawn behind your geometry. The six squares form the faces of an imaginary cube that surrounds an object; each face represents the view along the directions of the world axes (up, down, left, right, forward and back). More infoSee in Glossary for shadows. That means that six cubemap faces at this resolution must be kept in video memory at once. They are also quite expensive to render, as potential shadow casters might need to be rendered into all six cubemap faces.

Troubleshooting shadows

If you find that one or more objects are not casting shadows then you should check the following points:

Old graphics hardware may not support shadows. See below for a list of minimal hardware specs that can handle shadows.

Shadows can be disabled in the Quality window. Make sure that you have the correct quality level enabled and that shadows are switched on for that setting.

All Mesh RenderersA mesh component that takes the geometry from the Mesh Filter and renders it at the position defined by the object’s Transform component. More infoSee in Glossary in the scene must be set up with their Receive Shadows and Cast Shadows correctly set. Both are enabled by default but check that they haven’t been disabled unintentionally.

Only opaque objects cast and receive shadows so objects using the built-in Transparent or Particle shaders will neither cast nor receive. Generally, you can use the Transparent Cutout shaders instead for objects with “gaps” such as fences, vegetation, etc(Ericsson Texture Compression) A block-based texture format that compresses textures to significantly reduce file sizes without causing a noticable reduction in image quality. More infoSee in Glossary. Custom ShadersA small script that contains the mathematical calculations and algorithms for calculating the Color of each pixel rendered, based on the lighting input and the Material configuration. More infoSee in Glossary must be pixel-lit and use the Geometry render queue.

Objects using VertexLit shaders can’t receive shadows but they can cast them.

With the Forward rendering path, some shaders allow only the brightest directional light to cast shadows (in particular, this happens with Unity’s legacy built-in shaders from 4.x versions). If you want to have more than one shadow-casting light then you should use the Deferred ShadingA rendering path that places no limit on the number of lights that can affect a GameObject. All lights are evaluated per-pixel, which means that they all interact correctly with normal maps and so on. Additionally, all lights can have cookies and shadows. More infoSee in Glossaryrendering pathThe technique Unity uses to render graphics. Choosing a different path affects the performance of your game, and how lighting and shading are calculated. Some paths are more suited to different platforms and hardware than others. More infoSee in Glossary instead. You can enabled your own shaders to support “full shadows” by using the fullforwardshadowssurface shaderUnity’s code generation approach that makes it much easier to write lit shaders than using low level vertex/pixel shader programs. More infoSee in Glossary directive.

Hardware support for shadows

Built-in shadows work on almost all devices supported by Unity. The following cards are supported on each platform:

PC (Windows/Mac/Linux)

Generally all GPUs support shadows. Exceptions might occur in some really old GPUs (for example, Intel GPUs made in 2005).

Mobile

iPhone 4 does not support shadows. All later models starting with iPhone 4S and iPad 2 support shadows.

Android: Requires Android 4.0 or later, and GL_OES_depth_texture support. Most notably, some Android Tegra 2/3-based Android devices do not have this, so they don’t support shadows.