3D lights and shadows

Introduction

Light sources emit light that mixes with the materials and produces a visibleresult. Light can come from several types of sources in a scene:

  • From the material itself, in the form of the emission color (though it doesnot affect nearby objects unless baked or screen-space indirect lighting is enabled).

  • Light nodes: DirectionalLight3D, OmniLight3D and SpotLight3D.

  • Ambient light in theEnvironment orReflection probes.

  • Global illumination (LightmapGI,VoxelGI orSDFGI).

The emission color is a material property. You can read more about itin theStandard Material 3D and ORM Material 3D tutorial.

See also

You can compare various types of lights in action using the3D Lights and Shadows demo project.

Light nodes

There are three types of light nodes:DirectionalLight3D,OmniLight3D andSpotLight3D. Let's take a look at the commonparameters for lights:

../../_images/light_params.png

Each property has a specific function:

  • Color: Base color for emitted light.

  • Energy: Energy multiplier. This is useful for saturating lights or working withHigh dynamic range lighting.

  • Indirect Energy: Secondary multiplier used with indirect light (light bounces). This works withUsing Lightmap global illumination, VoxelGI or SDFGI.

  • Volumetric Fog Energy: Secondary multiplier used with volumetric fog. This only has an effect when volumetric fog is enabled.

  • Negative: Light becomes subtractive instead of additive. It's sometimes useful to manually compensate some dark corners.

  • Specular: Affects the intensity of the specular blob in objects affected by this light. At zero, this light becomes a pure diffuse light.

  • Bake Mode: Sets the bake mode for the light. SeeUsing Lightmap global illumination.

  • Cull Mask: Objects that are in the selected layers below will be affected by this light.Note that objects disabled via this cull mask will still cast shadows.If you don't want disabled objects to cast shadows, adjust theCast Shadowproperty on the GeometryInstance3D to the desired value.

See also

SeePhysical light and camera units if you wish to use real worldunits to configure your lights' intensity and color temperature.

Light number limits

When using the Forward+ renderer, Godot uses aclustering approach forreal-time lighting. As many lights as desired can be added (as long asperformance allows). However, there's still a default limit of 512clusteredelements that can be present in the current camera view. A clustered element isan omni light, a spot light, adecal or areflection probe. This limit can be increased by adjustingMax Clustered ElementsinProject Settings > Rendering > Limits > Cluster Builder.

When using the Mobile renderer, there is a limitation of 8 OmniLights + 8 SpotLightsper mesh resource. There is also a limit of 256 OmniLights + 256 SpotLights thatcan be rendered in the current camera view. These limits currently cannot be changed.

When using the Compatibility renderer, up to 8 OmniLights + 8 SpotLights can berendered per mesh resource. This limit can be increased in the advanced ProjectSettings by adjustingMax Renderable Elementsand/orMax Lights per ObjectinRendering > Limits > OpenGL, at the cost of performance and longer shadercompilation times. The limit can also be decreased to reduce shader compilationtimes and improve performance slightly.

With all rendering methods, up to 8 DirectionalLights can be visible at a time.However, each additional DirectionalLight with shadows enabled will reduce theeffective shadow resolution of each DirectionalLight. This is becausedirectional shadow atlas is shared between all lights.

If the rendering limit is exceeded, lights will start popping in and out duringcamera movement, which can be distracting. EnablingDistance Fade on lightnodes can help reduce this issue while also improving performance. Splittingyour meshes into smaller portions can also help, especially for level geometry(which also improves culling efficiency).

If you need to render more lights than possible in a given renderer,consider usingbaked lightmaps with lights' bakemode set toStatic. This allows lights to be fully baked, which also makesthem much faster to render. You can also use emissive materials with anyglobal illumination techniqueas a replacement for light nodes that emit light over a large area.

Shadow mapping

Lights can optionally cast shadows. This gives them greater realism (light doesnot reach occluded areas), but it can incur a bigger performance cost.There is a list of generic shadow parameters, each also has a specific function:

  • Enabled: Check to enable shadow mapping in this light.

  • Opacity: Areas occluded are darkened by this opacity factor. Shadows arefully opaque by default, but this can be changed to make shadows translucentfor a given light.

  • Bias: When this parameter is too low, self-shadowing occurs. When toohigh, shadows separate from the casters. Tweak to what works best for you.

  • Normal Bias: When this parameter is too low, self-shadowing occurs. When toohigh, shadows appear misaligned from the casters. Tweak to what works best for you.

  • Transmittance Bias: When this parameter is too low, self-shadowingoccurs on materials that have transmittance enabled. When too high, shadowswill not affect materials that have transmittance enabled consistently. Tweakto what works best for you.

  • Reverse Cull Face: Some scenes work better when shadow mapping is renderedwith face-culling inverted.

  • Blur: Multiplies the shadow blur radius for this light. This works withboth traditional shadow mapping and contact-hardening shadows (lights withAngular Distance orSize greater than0.0). Higher values resultin softer shadows, which will also appear to be more temporally stable formoving objects. The downside of increasing shadow blur is that it will makethe grainy pattern used for filtering more noticeable.See alsoShadow filter mode.

  • Caster Mask: Shadows are only cast by objects in these layers. Note thatthis mask does not affect which objects shadows are castonto.

../../_images/lights_and_shadows_blur.webp

Tweaking shadow bias

Below is an image of what tweaking bias looks like. Default values work for mostcases, but in general, it depends on the size and complexity of geometry.

If theShadow Bias orShadow Normal Bias is set too low for a given light,the shadow will be "smeared" onto the objects. This will cause the light'sintended appearance to darken, and is calledshadow acne:

../../_images/lights_and_shadows_acne.webp

On the other hand, if theShadow Bias orShadow Normal Bias is set toohigh for a given light, the shadow may appear to be disconnected from theobject. This is calledpeter-panning:

../../_images/lights_and_shadows_peter_panning.webp

In general, increasingShadow Normal Bias is preferred over increasingShadow Bias. IncreasingShadow Normal Bias does not cause as muchpeter-panning as increasingShadow Bias, but it can still resolvemost shadow acne issues efficiently. The downside of increasingShadow NormalBias is that it can make shadows appear thinner for certain objects.

Any sort of bias issues can be fixed byincreasing the shadow map resolution,at the cost of decreased performance.

Note

Tweaking shadow mapping settings is an art – there are no "one size fitsall" settings. To achieve the best visuals, you may need to use differentshadow bias values on a per-light basis.

Note on Appearance Changes: When enabling shadows on a light, be aware that the light'sappearance might change compared to when it's rendered without shadows in the compatibilityrenderer. Due to limitations with older mobile devices, shadows are implemented using a multi-passrendering approach so lights with shadows are rendered in sRGB space instead of linear space.This change in rendering space can sometimes drastically alter the light's appearance. To achieve a similarappearance to an unshadowed light, you may need to adjust the light's energy setting.

Directional light

This is the most common type of light and represents a light source very faraway (such as the sun). It is also the cheapest light to compute and should beused whenever possible (although it's not the cheapest shadow-map to compute,but more on that later).

Directional light models an infinite number of parallel light rayscovering the whole scene. The directional light node is represented by a big arrow whichindicates the direction of the light rays. However, the position of the nodedoes not affect the lighting at all and can be anywhere.

../../_images/light_directional.png

Every face whose front-side is hit by the light rays is lit, while the othersstay dark. Unlike most other light types, directional lights don't have specificparameters.

The directional light also offers aAngular Distance property, whichdetermines the light's angular size in degrees. Increasing this above0.0will make shadows softer at greater distances from the caster, while alsoaffecting the sun's appearance in procedural sky materials. This is called acontact-hardening shadow (also known as PCSS).

For reference, the angular distance of the Sun viewed from the Earth isapproximately0.5. This kind of shadow is expensive, so check therecommendations inPCSS recommendations if settingthis value above0.0 on lights with shadows enabled.

Directional shadow mapping

To compute shadow maps, the scene is rendered (only depth) from an orthogonalpoint of view that covers the whole scene (or up to the max distance). There is,however, a problem with this approach because objects closer to the camerareceive low-resolution shadows that may appear blocky.

To fix this, a technique namedParallel Split Shadow Maps (PSSM) is used.This splits the view frustum in 2 or 4 areas. Each area gets its own shadow map.This allows small areas close to the viewer to have the same shadow resolutionas a huge, far-away area. When shadows are enabled for DirectionalLight3D, thedefault shadow mode is PSSM with 4 splits. In scenarios where an object is largeenough to appear in all four splits, it results in increased draw calls. Specifically,such an object will be rendered five times in total: once for each of the four shadowsplits and once for the final scene rendering. This can impact performance, understandingthis behavior is important for optimizing your scene and managing performance expectations.

../../_images/lights_and_shadows_pssm_explained.webp

With this, shadows become more detailed:

../../_images/lights_and_shadows_directional_mode.webp

To control PSSM, a number of parameters are exposed:

../../_images/lights_and_shadows_directional_shadow_params.webp

Each split distance is controlled relative to the camera far (or shadowMax Distance if greater than0.0).0.0 is the eye position and1.0 is where the shadow ends at a distance. Splits are in-between.Default values generally work well, but tweaking the first split a bit is commonto give more detail to close objects (like a character in a third-person game).

Always make sure to set a shadowMax Distance according to what the sceneneeds. A lower maximum distance will result in better-looking shadows and betterperformance, as fewer objects will need to be included in shadow rendering. Youcan also adjustFade Start to control how aggressive the shadow fade-outshould be at a distance. For scenes where theMax Distance fully covers thescene at any given camera position, you can increaseFade Start to1.0to prevent the shadow from fading at a distance. This should not be done inscenes whereMax Distance doesn't fully cover the scene, as the shadow willappear to be suddenly cut off at a distance.

Sometimes, the transition between a split and the next can look bad. To fixthis, theBlend Splits option can be turned on, which sacrifices detail andperformance in exchange for smoother transitions:

../../_images/blend_splits.png

TheShadow > Normal Bias parameter can be used to fix special cases ofself-shadowing when objects are perpendicular to the light. The only downside isthat it makes the shadow a bit thinner. Consider increasingShadow > NormalBias before increasingShadow > Bias in most situations.

Lastly,Pancake Size is a property that can be adjusted to fix missingshadows when using large objects with unsubdivided meshes. Only change thisvalue if you notice missing shadows that are not related to shadow biasingissues.

Omni light

Omni light is a point source that emits light spherically in all directions up to a givenradius.

../../_images/light_omni.png

In real life, light attenuation is an inverse function, which means omni lights don't have a radius.This is a problem because it means computing several omni lights would become demanding.

To solve this, aRange parameter is introduced together with an attenuation function.

../../_images/light_omni_params.png

These two parameters allow tweaking how this works visually in order to find aesthetically pleasing results.

../../_images/light_attenuation.png

ASize parameter is also available in OmniLight3D. Increasing this valuewill make the light fade out slower and shadows appear blurrier when far awayfrom the caster. This can be used to simulate area lights to an extent. This iscalled acontact-hardening shadow (also known as PCSS). This kind of shadow isexpensive, so check the recommendations inPCSS recommendations if setting this value above0.0 on lights with shadows enabled.

../../_images/lights_and_shadows_pcss.webp

Omni shadow mapping

Omni light shadow mapping is relatively straightforward. The main issue thatneeds to be considered is the algorithm used to render it.

Omni Shadows can be rendered as eitherDual Paraboloid orCube mapped.Dual Parabolid renders quickly, but can cause deformations, whileCubeis more correct, but slower. The default isCube, but consider changing ittoDual Parabolid for lights where it doesn't make much of a visualdifference.

../../_images/lights_and_shadows_dual_parabolid_vs_cubemap.webp

If the objects being rendered are mostly irregular and subdivided, DualParaboloid is usually enough. In any case, as these shadows are cached in ashadow atlas (more on that at the end), it may not make a difference inperformance for most scenes.

Omni lights with shadows enabled can make use of projectors. The projectortexture willmultiply the light's color by the color at a given point on thetexture. As a result, lights will usually appear to be darker once a projectortexture is assigned; you can increaseEnergy to compensate for this.

Omni light projector textures require a special 360° panorama mapping, similartoPanoramaSkyMaterial textures.

With the projector texture below, the following result is obtained:

../../_images/lights_and_shadows_omni_projector_example.webp../../_images/lights_and_shadows_omni_projector.webp

Tip

If you've acquired omni projectors in the form of cubemap images, you can usethis web-based conversion toolto convert them to a single panorama image.

Spot light

Spot lights are similar to omni lights, except they emit light only into a cone(or "cutoff"). They are useful to simulate flashlights,car lights, reflectors, spots, etc. This type of light is also attenuated towards theopposite direction it points to.

Spot lights share the sameRange,Attenuation andSize as OmniLight3D,and add two extra parameters:

  • Angle: The aperture angle of the light.

  • Angle Attenuation: The cone attenuation, which helps soften the cone borders.

Spot shadow mapping

Spots feature the same parameters as omni lights for shadow mapping. Renderingspot shadow maps is significantly faster compared to omni lights, as only oneshadow texture needs to be rendered (instead of rendering 6 faces, or 2 in dualparabolid mode).

Spot lights with shadows enabled can make use of projectors. The projectortexture willmultiply the light's color by the color at a given point on thetexture. As a result, lights will usually appear to be darker once a projectortexture is assigned; you can increaseEnergy to compensate for this.

Unlike omni light projectors, a spot light projector texture doesn't need tofollow a special format to look correct. It will be mapped in a way similar to adecal.

With the projector texture below, the following result is obtained:

../../_images/lights_and_shadows_spot_projector_example.webp../../_images/lights_and_shadows_spot_projector.webp

Note

Spot lights with wide angles will have lower-quality shadows than spotlights with narrow angles, as the shadow map is spread over a largersurface. At angles wider than 89 degrees, spot light shadows will stopworking entirely. If you need shadows for wider lights, use an omni lightinstead.

Shadow atlas

Unlike Directional lights, which have their own shadow texture, omni and spotlights are assigned to slots of a shadow atlas. This atlas can be configured inthe advanced Project Settings (Rendering > Lights And Shadows > Positional Shadow).

The resolution applies to the whole shadow atlas. This atlas is divided into four quadrants:

../../_images/lights_and_shadows_shadow_quadrants.webp

Each quadrant can be subdivided to allocate any number of shadow maps; the following is the default subdivision:

../../_images/lights_and_shadows_shadow_quadrants2.webp

The shadow atlas allocates space as follows:

  • The biggest shadow map size (when no subdivision is used) represents a light the size of the screen (or bigger).

  • Subdivisions (smaller maps) represent shadows for lights that are further away from view and proportionally smaller.

Every frame, the following procedure is performed for all lights:

  1. Check if the light is on a slot of the right size. If not, re-render it and move it to a larger/smaller slot.

  2. Check if any object affecting the shadow map has changed. If it did, re-render the light.

  3. If neither of the above has happened, nothing is done, and the shadow is left untouched.

If the slots in a quadrant are full, lights are pushed back to smaller slots,depending on size and distance. If all slots in all quadrants are full, somelights will not be able to render shadows even if shadows are enabled on them.

The default shadow allocation strategy allows rendering up to 88 lights withshadows enabled in the camera frustum (4 + 4 + 16 + 64):

  1. The first and most detailed quadrant can store 4 shadows.

  2. The second quadrant can store 4 other shadows.

  3. The third quadrant can store 16 shadows, with less detail.

  4. The fourth and least detailed quadrant can store 64 shadows, with even less detail.

Using a higher number of shadows per quadrant allows supporting a greater amountof total lights with shadows enabled, while also improving performance (asshadows will be rendered at a lower resolution for each light). However,increasing the number of shadows per quadrant comes at the cost of lower shadowquality.

In some cases, you may want to use a different allocation strategy. For example,in a top-down game where all lights are around the same size, you may want toset all quadrants to have the same subdivision so that all lights have shadowsof similar quality level.

Balancing performance and quality

Shadow rendering is a critical topic in 3D rendering performance. It's importantto make the right choices here to avoid creating bottlenecks.

Directional shadow quality settings can be changed at runtime by calling theappropriateRenderingServer methods.

Positional (omni/spot) shadow quality settings can be changed at runtime on therootViewport.

Shadow map size

High shadow resolutions result in sharper shadows, but at a significantperformance cost. It should also be noted thatsharper shadows are not alwaysmore realistic. In most cases, this should be kept at its default value of4096 or decreased to2048 for low-end GPUs.

If positional shadows become too blurry after decreasing the shadow map size,you can counteract this by adjusting theshadow atlas quadrants to containfewer shadows. This will allow each shadow to be rendered at a higher resolution.

Shadow filter mode

Several shadow map quality settings can be chosen here. The defaultSoft Lowis a good balance between performance and quality for scenes with detailedtextures, as the texture detail will help make the dithering pattern less noticeable.

However, in projects with less detailed textures, the shadow dithering patternmay be more visible. To hide this pattern, you can either enableTemporal antialiasing (TAA),AMD FidelityFX Super Resolution 2.2 (FSR2),Fast approximate antialiasing (FXAA), or increase the shadow filter quality toSoft Medium or higher.

TheSoft Very Low setting will automatically decrease shadow blur to makeartifacts from the low sample count less visible. Conversely, theSoft HighandSoft Ultra settings will automatically increase shadow blur to bettermake use of the increased sample count.

../../_images/lights_and_shadows_filter_quality.webp

16-bits versus 32-bit

By default, Godot uses 16-bit depth textures for shadow map rendering. This isrecommended in most cases as it performs better without a noticeable differencein quality.

If16 Bits is disabled, 32-bit depth textures will be used instead. Thiscan result in less artifacting in large scenes and large lights with shadowsenabled. However, the difference is often barely visible, yet this can have asignificant performance cost.

Light/shadow distance fade

OmniLight3D and SpotLight3D offer several properties to hide distant lights.This can improve performance significantly in large scenes with dozens of lightsor more.

PCSS recommendations

Percentage-closer soft shadows (PCSS) provide a more realistic shadow mappingappearance, with the penumbra size varying depending on the distance between thecaster and the surface receiving the shadow. This comes at a high performancecost, especially for directional lights.

To avoid performance issues, it's recommended to:

  • Only use a handful of lights with PCSS shadows enabled at a given time. Theeffect is generally most visible on large, bright lights. Secondary lightsources that are more faint usually don't benefit much from using PCSSshadows.

  • Provide a setting for users to disable PCSS shadows. On directional lights,this can be done by setting the DirectionalLight3D'slight_angular_distance property to0.0 in a script. On positionallights, this can be done by setting the OmniLight3D or SpotLight3D'slight_size property to0.0 in a script.

Projector filter mode

The way projectors are rendered also has an impact on performance. TheRendering > Textures > Light Projectors > Filter advanced project settinglets you control how projector textures should be filtered.Nearest/Linear donot use mipmaps, which makes them faster to render. However, projectors willlook grainy at distance.Nearest/Linear Mipmaps will look smoother at adistance, but projectors will look blurry when viewed from oblique angles. Thiscan be resolved by usingNearest/Linear Mipmaps Anisotropic, which is thehighest-quality mode, but also the most expensive.

If your project has a pixel art style, consider setting the filter to one of theNearest values so that projectors use nearest-neighbor filtering. Otherwise,stick toLinear.


User-contributed notes

Please read theUser-contributed notes policy before submitting a comment.