Lighting

Show Deprecated
Not Creatable
Service

Fog properties are hidden when Lighting contains an Atmosphere object.

The Lighting service controls the environmental lighting in a game. It includes a range of adjustable properties that can be used to change how lighting appears and interacts with other objects.

Developers can change the color and appearance of lighting in their place using properties such as Lighting.Ambient and Lighting.OutdoorAmbient.

In addition to controlling environmental lighting, the Lighting service also configures any fog in the game using the Lighting.FogColor, Lighting.FogStart and Lighting.FogEnd properties.

Lighting, along with Workspace.CurrentCamera, is one of the two places where PostEffects such as the SunRaysEffect and BlurEffect are displayed once parented to.

Note:

  • Lighting only controls environmental lighting and not dynamic light objects such as the PointLight
  • Prior to the introduction of ServerStorage and ReplicatedStorage lighting was used for storage. This behavior is not supported and should not be used in new work

Code Samples

Day/Night Cycle

1local Lighting = game:GetService("Lighting")
2
3local TIME_SPEED = 60 -- 1 min = 1 hour
4local START_TIME = 9 -- 9am
5
6local minutesAfterMidnight = START_TIME * 60
7local waitTime = 60 / TIME_SPEED
8
9while true do
10 minutesAfterMidnight = minutesAfterMidnight + 1
11
12 Lighting:SetMinutesAfterMidnight(minutesAfterMidnight)
13
14 task.wait(waitTime)
15end

Summary

Properties

The lighting hue applied to areas that are occluded from the sky, such as indoor areas.

The intensity of illumination in the place.

A numerical representation (in hours) of the current time of day used by Lighting.

NOT REPLICATED

The hue represented in light reflected in the opposite surfaces to those facing the sun or moon.

The hue represented in light reflected from surfaces facing the sun or moon.

Ambient light that is derived from the environment.

Specular light derived from environment.

The exposure compensation value.

A Color3 value giving the hue of Lighting's fog.

The depth from the Workspace.CurrentCamera, in studs, at which fog will be completely opaque.

The depth from the Workspace.CurrentCamera, in studs, at which fog begins to show.

The geographic latitude, in degrees, of the scene, influencing the result of Lightings time on the position of the sun and moon.

Toggles voxel-based dynamic lighting for the game.

The lighting hue applied to outdoor areas.

Controls how blurry the shadows are.

A temporary non-scriptable property that determines the lighting system used to render the 3D world (e.g. legacy, Future Is Bright, shadow map).

NOT SCRIPTABLE

A 24 hour string representation of the current time of day used by Lighting.

Events


This event fires when a Lighting property is changed or a Sky is added or removed from Lighting.

Methods


Returns the number of minutes that have passed after midnight for the purposes of lighting.


Returns a Vector3 representing the direction of the moon from the position 0, 0, 0.


Returns the moon's current phase.


Returns a Vector3 representing the direction of the sun from the position 0, 0, 0.


Sets Lighting.TimeOfDay and Lighting.ClockTime to the given number of minutes after midnight.

Properties

Ambient

The lighting hue applied to areas that are occluded from the sky, such as indoor areas.

This property defaults to 0, 0, 0 (black).

As long as the red, green and blue channels of this property do not exceed the corresponding channels in Lighting.OutdoorAmbient the change in hue will be reserved for areas occluded from the sun/moon. The effective Lighting.OutdoorAmbient value is clamped to be greater than or equal to Ambient in all channels. This means, if a channel of Ambient exceeds its corresponding Lighting.OutdoorAmbient channel then the hue will begin to apply to outdoor areas.

Note, when Lighting.GlobalShadows is disabled there is no distinction between areas occluded and areas that are not. In this case Lighting.OutdoorAmbient will be ignored and the hue from the Ambient property will be applied everywhere.

For more properties that influence the color of lighting, please see Lighting.ColorShiftBottom and Lighting.ColorShiftTop.

Brightness

The intensity of illumination in the place.

Changing this value will influence the impact of the light source (sun or moon) on the map's lighting. When brightness is set to 0, there will be no effect due to Lighting.ColorShift_Top or Lighting.ColorShift_Bottom as the light source is having no effect. Note, it will not influence the shadows created by the Lighting.GlobalShadows property.

Whilst this property is not clamped, the effect is clamped between 0 and 2. Meaning setting Brightness to 10 will be no different to setting it to 2.

Note, Lighting.Ambient and Lighting.OutdoorAmbient can also be used to influence how bright a place appears. For example, setting Lighting.OutdoorAmbient to 255, 255, 255 will make the place appear brighter than its default value of 127, 127, 127 (as it is more white).

ClockTime

Not Replicated

A numerical representation (in hours) of the current time of day used by Lighting.

Note, this property does not correspond with the actual time of day and will not change during the game unless it has been changed by a script.

For a measure of Lighting's time formatted as a 24 hour string use Lighting.CurrentTime. Changing Lighting.CurrentTime or using Lighting:SetMinutesAfterMidnight() will also change this property.

Using ClockTime requires the time to be normalized:


1minutesAfterMidnight = 0
2while true do
3 minutesAfterMidnight = minutesAfterMidnight + 1
4
5 local minutesNormalised = minutesAfterMidnight % (60 * 24)
6 local hours = minutesNormalised / 60
7
8 Lighting.ClockTime = hours
9
10 wait()
11end
12

Using Lighting.TimeOfDay requires the time to be normalized and a string formatted:


1minutesAfterMidnight = 0
2while true do
3 minutesAfterMidnight = minutesAfterMidnight + 1
4
5 local minutesNormalised = minutesAfterMidnight % (60 * 24)
6 local seconds = minutesNormalised * 60
7 local hours = string.format("%02.f", math.floor(seconds/3600))
8 local mins = string.format("%02.f", math.floor(seconds/60 - (hours*60)))
9 local secs = string.format("%02.f", math.floor(seconds - hours*3600 - mins *60))
10 local timeString = hours..":"..mins..":"..secs
11
12 Lighting.TimeOfDay = timeString
13
14 wait()
15end
16

Using Lighting:SetMinutesAfterMidnight() requires no extra processing:


1minutesAfterMidnight = 0
2while true do
3 minutesAfterMidnight = minutesAfterMidnight + 1
4
5 Lighting:SetMinutesAfterMidnight(minutesAfterMidnight)
6
7 wait()
8end
9

ColorShift_Bottom

The hue represented in light reflected in the opposite surfaces to those facing the sun or moon.

The surfaces of a BasePart influenced by ColorShift_Bottom depends on the position and orientation of the BasePart relative to the sun or moon's position. Where the sun is directly overhead a BasePart, the shift in color will only apply to the bottom surface.

This effect can be increased or reduced by altering Lighting.Brightness.

ColorShift_Bottom influences the opposite surfaces to Lighting.ColorShift_Top

Note, Lighting.ColorShift_Top and ColorShift_Bottom will interact with the Lighting.Ambient and Lighting.OutdoorAmbient properties if they are greater than 0, 0, 0. Also, the influence of ColorShift_Bottom can be very hard to identify when Lighting.GlobalShadows is enabled (as it is by default).

ColorShift_Top

The hue represented in light reflected from surfaces facing the sun or moon.

The surfaces of a BasePart influenced by ColorShift_Top depends on the position and orientation of the BasePart relative to the sun or moon's position. Where the sun is directly overhead a BasePart, the shift in color will only apply to the top surface.

This effect can be increased or reduced by altering Lighting.Brightness.

Whilst ColorShift_Top influences surfaces exposed to light, Lighting.ColorShift_Bottom influences surfaces sheltered from light.

Note, ColorShift_Top and ColorShift_Bottom will interact with the Lighting.Ambient and Lighting.OutdoorAmbient properties if they are greater than 0, 0, 0.

EnvironmentDiffuseScale

Ambient light that is derived from the environment. The value of this property defaults to 0.

It is similar to Lighting.Ambient and Lighting.OutdoorAmbient property but it's dynamic and can change according sky and time of day. It is recommended when this property is increased, Ambient and OutdoorAmbient are decreased accordingly.

Note

  • It also makes skybox show up at night

EnvironmentSpecularScale

Specular light derived from environment. The value of this property defaults to 0.

It will make smooth objects reflect the environment. Especially important to make metal more realistic.

ExposureCompensation

This property determines the exposure compensation amount which applies a bias to the exposure level of the scene prior to the tonemap step. Defaults to 0.

  • A value of +1 indicates twice as much exposure and -1 means half as much exposure.
  • A value of 0 indicates no exposure compensation will be done.
  • Range: -5 to 5

This property is replicated and can be set from scripts or Studio.


1local Lighting = game:GetService("Lighting")
2Lighting.ExposureCompensation = 5
3

You can use this property to adjust the exposure amount prior to the tonemap step to show more detail either in lighter or darker areas. This is needed as we move to a HDR pipeline.

When Lighting.Technology is set to Legacy, this property has no effect.


1local Lighting = game:GetService("Lighting")
2
3-- ExposureCompensation has no effect because Lighting's Technology is Legacy
4Lighting.Technology = Enum.Technology.Legacy
5Lighting.ExposureCompensation = 5
6

FogColor

Fog properties are hidden when Lighting contains an Atmosphere object.

A Color3 value giving the hue of Lighting's fog.

How does fog work?

Fog in Roblox is displayed in a plane perpendicular to the Workspace.CurrentCameras direction. It fades between the Lighting.FogStart property where it is not visible, to the Lighting.FogEnd property where it is fully opaque. The effect of fog is it blends color with the FogColor.

At distances greater than Lighting.FogEnd, color will be determined entirely by the FogColor. However at distances between Lighting.FogStart and Lighting.FogEnd the degree to which the color is blended depends on the position.

Roblox's fog uses linear interpolation between Lighting.FogStart and Lighting.FogEnd. This means if Lighting.FogStart is 10 and Lighting.FogEnd is 20, at a distance of 15 studs the fog will be at 50%. That means the color of a pixel at 15 studs will be 50% its normal color blended with 50% of the fog color.


1local Lighting = game:GetService("Lighting")
2-- fog will fade between 25 and 200 studs
3Lighting.FogStart = 25
4Lighting.FogEnd = 200
5

Note, fog does not obscure the skybox.

For more information about fog please see this blog post.

FogEnd

Fog properties are hidden when Lighting contains an Atmosphere object.

The depth from the Workspace.CurrentCamera, in studs, at which fog will be completely opaque.

How does fog work?

Fog in Roblox is displayed in a plane perpendicular to the Workspace.CurrentCameras look direction. It fades between the Lighting.FogStart property where it is not visible, to the FogEnd property where it is fully opaque. The effect of fog is it blends color with the Lighting.FogColor.

At distances greater than FogEnd, color will be determined entirely by the Lighting.FogColor. However at distances between Lighting.FogStart and FogEnd the degree to which the color is blended depends on the position.

Roblox's fog uses linear interpolation between Lighting.FogStart and FogEnd. This means if Lighting.FogStart is 10 and FogEnd is 20, at a distance of 15 studs the fog will be at 50%. That means the color of a pixel at 15 studs will be 50% its normal color blended with 50% of the fog color.


1local Lighting = game:GetService("Lighting")
2-- fog will fade between 25 and 200 studs
3Lighting.FogStart = 25
4Lighting.FogEnd = 200
5

The color of the fog can be adjusted using Lighting.FogColor.

Note, fog does not obscure the skybox.

For more information about fog please see this blog post.

FogStart

Fog properties are hidden when Lighting contains an Atmosphere object.

The depth from the Workspace.CurrentCamera, in studs, at which fog begins to show.

How does fog work?

Fog in Roblox is displayed in a plane perpendicular to the Workspace.CurrentCameras look direction. It fades between the FogStart property where it is not visible, to the Lighting.FogEnd property where it is fully opaque. The effect of fog is it blends color with the Lighting.FogColor.

At distances greater than Lighting.FogEnd, color will be determined entirely by the Lighting.FogColor. However at distances between FogStart and Lighting.FogEnd the degree to which the color is blended depends on the position.

Roblox's fog uses linear interpolation between FogStart and Lighting.FogEnd. This means if FogStart is 10 and Lighting.FogEnd is 20, at a distance of 15 studs the fog will be at 50%. That means the color of a pixel at 15 studs will be 50% its normal color blended with 50% of the fog color.


1local Lighting = game:GetService("Lighting")
2-- fog will fade between 25 and 200 studs
3Lighting.FogStart = 25
4Lighting.FogEnd = 200
5

The color of the fog can be adjusted using Lighting.FogColor.

Note, fog does not obscure the skybox.

For more information about fog please see this blog post.

GeographicLatitude

The geographic latitude, in degrees, of the scene, influencing the result of Lightings time on the position of the sun and moon.

When calculating the position of the sun, the earth's tilt is also taken into account.

Changing GeographicLatitude will alter the position of the sun at every Lighting.TimeOfDay. Developers looking to obtain the sun or moon's position should use Lighting:GetSunDirection() or Lighting:GetMoonDirection().

GlobalShadows

Toggles voxel-based dynamic lighting in the game

What does GlobalShadows do?

When set to true, shadows are rendered in sheltered areas depending on the position of the sun and moon. The lighting hue applied to these areas is determined by the Lighting.Ambient property. The lighting hue in all other areas is determined by the Lighting.OutdoorAmbient property.

When disabled, shadows are not drawn and no distinction is made between indoor and outdoor areas. As a result, the Lighting.Ambient property determines the lighting hue and Lighting.OutdoorAmbient will do nothing.

Shadows are calculated using a voxel system, and each lighting voxel is 4x4x4 studs. This means objects need to be larger than 4x4x4 studs to display a realistic shadow. Shadows are also recalculated when BaseParts are moving.

Note, this property is unrelated to shadows from characters which are displayed regardless of what GlobalShadows is set to.

For more information about Roblox's dynamic lighting, please see this blog post.

Toggling GlobalShadows

Developers toggling the GlobalShadows setting will notice that disabling it makes the place considerably darker. This is because when GlobalShadows is disabled Lighting.Ambient is used to calculate the lighting hue in both indoor and ourdoor spaces. This darkness can be resolved by setting Lighting.Ambient to a higher value such as Lighting.OutdoorAmbient's default value of 127, 127, 127.

In most cases developers are recommended to leave GlobalShadows enabled due to the superior visual appearance. See Lighting Properties guide for a comparison.

OutdoorAmbient

The lighting hue applied to outdoor areas.

This property defaults to 127, 127, 127.

As long as the red, green and blue channels of Lighting.Ambient do not exceed the corresponding channels in this property, the hue of the lighting in outdoor areas will be determined by this property. The effective OutdoorAmbient value is clamped to be greater than or equal to Lighting.Ambient in all channels. This means, if a channel of Lighting.Ambient exceeds its corresponding OutdoorAmbient channel then the hue of Lighting.Ambient will begin to apply to outdoor areas.

Note, when Lighting.GlobalShadows is disabled there is no distinction between areas occluded from the sky and areas that are not. In this case OutdoorAmbient will be ignored and the hue from the Lighting.Ambient property will be applied everywhere.

For more properties that influence the color of lighting, please see Lighting.ColorShift_Bottom and Lighting.ColorShift_Top.

ShadowSoftness

Controls how blurry the shadows are. The value of this property defaults to 0.2.

This property only works when Lighting.Technology mode is ShadowMap or Future and the device is capable of ShadowMap.

Technology

Not Scriptable

This property determines the lighting system used to render the 3D world (e.g. legacy, Future is Bright, shadow map). It is only changeable in Studio. Its purpose is to facilitate a smooth transition to the Future Is Bright system. See the Technology enum for details on each available system.

TimeOfDay

A 24 hour string representation of the current time of day used by Lighting.

Note, this property does not correspond with the actual time of day and will not change during the game unless it has been changed by a script.

For a numeric measure of Lighting's time use Lighting.ClockTime. Changing Lighting.ClockTime or using Lighting:SetMinutesAfterMidnight() will also change this property.

Using TimeOfDay requires the time to be normalized and a string formatted:


1minutesAfterMidnight = 0
2while true do
3 minutesAfterMidnight = minutesAfterMidnight + 1
4
5 local minutesNormalised = minutesAfterMidnight % (60 * 24)
6 local seconds = minutesNormalised * 60
7 local hours = string.format("%02.f", math.floor(seconds/3600))
8 local mins = string.format("%02.f", math.floor(seconds/60 - (hours*60)))
9 local secs = string.format("%02.f", math.floor(seconds - hours*3600 - mins *60))
10 local timeString = hours..":"..mins..":"..secs
11
12 Lighting.TimeOfDay = timeString
13
14 wait()
15end
16

Using Lighting.ClockTime requires the time to be normalized:


1minutesAfterMidnight = 0
2while true do
3 minutesAfterMidnight = minutesAfterMidnight + 1
4
5 local minutesNormalised = minutesAfterMidnight % (60 * 24)
6 local hours = minutesNormalised / 60
7
8 Lighting.ClockTime = hours
9
10 wait()
11end
12

Using Lighting:SetMinutesAfterMidnight() requires no extra processing:


1minutesAfterMidnight = 0
2while true do
3 minutesAfterMidnight = minutesAfterMidnight + 1
4
5 Lighting:SetMinutesAfterMidnight(minutesAfterMidnight)
6
7 wait()
8end
9

Events

LightingChanged

This event fires when a Lighting property is changed or a Sky is added or removed from Lighting.

Although this event fires when most properties of Lighting are changed, developers should be aware of the few exceptions:

In cases where this behavior is not desired, the Instance.Changed event or Instance:GetPropertyChangedSignal() function can be used.

Parameters

skyChanged: boolean

Code Samples

Lighting.LightingChanged

1local Lighting = game:GetService("Lighting")
2
3local function onLightingChanged(skyboxChanged)
4 if skyboxChanged then
5 print("Skybox has changed")
6 else
7 print("The skybox did not change.")
8 end
9end
10
11Lighting.LightingChanged:Connect(onLightingChanged)

Methods

GetMinutesAfterMidnight

Returns the number of minutes that have passed after midnight for the purposes of lighting.

This number will be nearly identical to Lighting.ClockTime multiplied by 60.

This number will not always be equal to the value given in Lighting:SetMinutesAfterMidnight() as it returns minutes after midnight in the current day.

For Lightings time formatted as a string, see Lighting.TimeOfDay.


Returns

The number of minutes after midnight.

Code Samples

Lighting:GetMinutesAfterMidnight

1local Lighting = game:GetService("Lighting")
2
3Lighting.TimeOfDay = "14:00:00"
4
5print(Lighting:GetMinutesAfterMidnight())

GetMoonDirection

Returns a Vector3 representing the direction of the moon from the position 0, 0, 0.

Note, when the moon has 'set' and is no longer visible, the Vector3 returned by this function will continue to point towards the moon below the map.

Developers looking to change the positioning of the moon should use the Lighting.ClockTime or Lighting.GeographicLatitude properties.

A variant of this function exists for obtaining the direction of the sun, Lighting:GetSunDirection().


Returns

Vector3 representing the direction of the moon from the position 0, 0, 0.

Code Samples

Lighting:GetMoonDirection

1local Lighting = game:GetService("Lighting")
2
3Lighting.TimeOfDay = "14:00:00"
4
5print(Lighting:GetMoonDirection())

GetMoonPhase

Returns the moon's current phase. There is no way to change the moon's phase so this will always return 0.75


Returns

GetSunDirection

Returns a Vector3 representing the direction of the sun from the position 0, 0, 0.

Note, when the sun has set and is no longer visible, the Vector3 returned by this function will continue to point towards the sun below the map.

Developers looking to change the positioning of the sun should use the Lighting.ClockTime or Lighting.GeographicLatitude properties.

A variant of this function exists for obtaining the direction of the moon, Lighting:GetMoonDirection().


Returns

Vector3 representing the direction of the sun from the position 0, 0, 0.

Code Samples

Lighting:GetSunDirection

1local Lighting = game:GetService("Lighting")
2
3Lighting.TimeOfDay = "14:00:00"
4Lighting.GeographicLatitude = 41.73
5
6print(Lighting:GetSunDirection())

SetMinutesAfterMidnight

Sets Lighting.TimeOfDay and Lighting.ClockTime to the given number of minutes after midnight.

How can I make a day / night script?

SetMinutesAfterMidnight allows a numerical value to be used, for example in a day/night cycle Script, without the need to convert to a string in the format required by Lighting.TimeOfDay. It also allows values greater than 24 hours to be given that correspond to times in the next day. See the code snippets below for an example.

Using Lighting.TimeOfDay requires the time to be normalized and a string formatted:


1minutesAfterMidnight = 0
2while true do
3 minutesAfterMidnight = minutesAfterMidnight + 1
4
5 local minutesNormalised = minutesAfterMidnight % (60 * 24)
6 local seconds = minutesNormalised * 60
7 local hours = string.format("%02.f", math.floor(seconds/3600))
8 local mins = string.format("%02.f", math.floor(seconds/60 - (hours*60)))
9 local secs = string.format("%02.f", math.floor(seconds - hours*3600 - mins *60))
10 local timeString = hours..":"..mins..":"..secs
11
12 Lighting.TimeOfDay = timeString
13
14 wait()
15end
16

Using Lighting.ClockTime requires the time to be normalized:


1minutesAfterMidnight = 0
2while true do
3 minutesAfterMidnight = minutesAfterMidnight + 1
4
5 local minutesNormalised = minutesAfterMidnight % (60 * 24)
6 local hours = minutesNormalised / 60
7
8 Lighting.ClockTime = hours
9
10 wait()
11end
12

Using Lighting:SetMinutesAfterMidnight() requires no extra processing:


1minutesAfterMidnight = 0
2while true do
3 minutesAfterMidnight = minutesAfterMidnight + 1
4
5 Lighting:SetMinutesAfterMidnight(minutesAfterMidnight)
6
7 wait()
8end
9

Parameters

minutes: number

The number of minutes after midnight.


Returns

Code Samples

Setting Lighting Time

1local Lighting = game:GetService("Lighting")
2
3Lighting:SetMinutesAfterMidnight(840)