Day Night Weather Cycle - Lighting & Terrain Shader Algorithm + Artificial Sun - Clean Efficient [Open-Source]

This code is something I wrote yesterday, for a project that involved my weather library, and creating a day and night cycle, this model is a what I would consider a shader, it modifies the terrain color and the properties of the lighting via a data format I wrote, the weather influences the lighting and just about every property of the lighting is included.
If you wish to learn about making the best lighting shaders this resource is a good thing to look into. I wanted to share this code without publishing my weather effects library, so I disabled that functionality, but it’s very simple to implement with a value that represents the weather dictionary key. The source code is included here and in an example model with an actor.
Lighting Shader

task.synchronize()
local Lighting=game.Lighting
local player=game.Players.LocalPlayer
local efx=game:GetService("TweenService")
--local fps=player.PlayerGui.CharacterSelect.FPSTiming
local Ter=workspace.Terrain--workspace:GetService("TerrainService")

local function LerpTerrainColor(def,duration)
	task.spawn(function()
		for i = 1, duration do -- do a loop of 30 frames
			for material,goal in def do 
				if material~=Enum.Material.Plastic then
					--print(material)
					--print(Ter.Material)
					local currentcolor=Ter:GetMaterialColor(Enum.Material[material])--Material[material].Color -- get the current color of the material
					local rdiff = goal.r - currentcolor.r -- get the difference of red values
					local gdiff = goal.g - currentcolor.g -- get the difference of green values
					local bdiff = goal.b - currentcolor.b -- get the difference of blue values	
					local newcolor = Color3.new( -- create a new color by adding a fraction of the difference
						currentcolor.r + rdiff * i / duration,
						currentcolor.g + gdiff * i / duration,
						currentcolor.b + bdiff * i / duration
					)
					--print(material)
					--print(newcolor)
					Ter:SetMaterialColor(Enum.Material[material],newcolor) -- set the new color to the material
				end
			end
			task.wait(.0333) -- wait for one frame
		end
	end)
end
local TimeDictionary = {
	Evening = {
		ClockTime = 0,
		Ambient = Color3.fromRGB(0, 0, 0),
		Brightness = 0,
		ColorShift_Bottom = Color3.fromRGB(0, 0, 0),
		ColorShift_Top = Color3.fromRGB(0, 0, 0),
		EnvironmentDiffuseScale = 0.5,
		ExposureCompensation = -2,
		EnvironmentSpecularScale = 0.5,
		OutdoorAmbient = Color3.fromRGB(0, 0, 0),
		FogColor = Color3.fromRGB(0, 0, 0),
		FogEnd = 120,
		FogStart = 0,

	},
	Day = {
		ClockTime = 6,
		Ambient = Color3.fromRGB(128, 128, 128),
		Brightness = 2,
		ExposureCompensation = 0,
		ColorShift_Bottom = Color3.fromRGB(255, 170, 0),
		ColorShift_Top = Color3.fromRGB(255, 200, 100),
		EnvironmentDiffuseScale = 0.3,
		EnvironmentSpecularScale = 0.3,
		OutdoorAmbient = Color3.fromRGB(128, 128, 128),
		FogColor = Color3.fromRGB(255, 200, 100),
		FogEnd = 300,
		FogStart = 180,
	},
	Morning = {
		ClockTime = 8,
		Ambient = Color3.fromRGB(249, 255, 213),
		Brightness = 3,
		ExposureCompensation = .25,
		ColorShift_Bottom = Color3.fromRGB(255, 250, 115),
		ColorShift_Top = Color3.fromRGB(255, 255, 255),
		EnvironmentDiffuseScale = 0.4,
		EnvironmentSpecularScale = 0.4,
		OutdoorAmbient = Color3.fromRGB(255, 255, 255),
		FogColor = Color3.fromRGB(255, 255, 255),
		FogEnd = 260,
		FogStart = 180,
	},
	Afternoon = {
		ClockTime = 12,
		Ambient = Color3.fromRGB(255, 255, 255),
		Brightness = 4,
		ColorShift_Bottom = Color3.fromRGB(255, 255, 255),
		ColorShift_Top = Color3.fromRGB(255, 255, 255),
		EnvironmentDiffuseScale = 0.5,
		ExposureCompensation = 0,
		EnvironmentSpecularScale = 0.5,
		OutdoorAmbient = Color3.fromRGB(255, 255, 255),
		FogColor = Color3.fromRGB(255, 255, 255),
		FogEnd = 240,
		FogStart = 160,
	},
	Night = {
		ClockTime = 18,
		Ambient = Color3.fromRGB(255, 140, 0),
		Brightness = 2,
		ColorShift_Bottom = Color3.fromRGB(255, 100, 0),
		ColorShift_Top = Color3.fromRGB(255, 150, 50),
		EnvironmentDiffuseScale = 0.6,
		ExposureCompensation = -1,
		EnvironmentSpecularScale = 0.6,
		OutdoorAmbient = Color3.fromRGB(255, 140, 0),
		FogColor = Color3.fromRGB(255, 150, 50),
		FogEnd = 125,
		FogStart = 20,
	},
	Midnight = {
		ClockTime = 24,
		Ambient = Color3.fromRGB(0, 0, 0),
		Brightness = 0,
		ColorShift_Bottom = Color3.fromRGB(0, 0, 0),
		ColorShift_Top = Color3.fromRGB(0, 0, 0),
		EnvironmentDiffuseScale = 0.5,
		ExposureCompensation = -2,
		EnvironmentSpecularScale = 0.5,
		OutdoorAmbient = Color3.fromRGB(0, 0, 0),
		FogColor = Color3.fromRGB(0, 0, 0),
		FogEnd = 120,
		FogStart = 0,

	},


}
local WeatherDictionary = {
	-- influence the lighting
	Sunny = {
		Ambient = Vector3.new(50, 50, 50), -- added to the rgb values
		Brightness = 1, -- added brightness
		ExposureCompensation = 0.25, -- added brightness
		ColorShift_Bottom = Vector3.new(50, 50, 50), -- more toward whites
		ColorShift_Top = Vector3.new(50, 50, 50),
		EnvironmentDiffuseScale = 0.25, -- makes everything more fuzzy
		EnvironmentSpecularScale = 0.25,
		OutdoorAmbient = Vector3.new(50, 50, 50),
		FogColor = Vector3.new(50, 50, 50),
		FogStart = 200
	},
	Blizzard = {
		Ambient = Vector3.new(50, 50, 50), -- added to the rgb values
		Brightness = 2, -- added brightness
		ExposureCompensation = 0.25, -- added brightness
		ColorShift_Bottom = Vector3.new(50, 50, 50), -- more toward whites
		ColorShift_Top = Vector3.new(50, 50, 50),
		EnvironmentDiffuseScale = 0.25, -- makes everything more fuzzy
		EnvironmentSpecularScale = 0.25,
		OutdoorAmbient = Vector3.new(50, 50, 50),
		FogColor = Vector3.new(50, 50, 50),
		FogStart = 0
	},
	["Dark Rain"] = {
		Ambient = Vector3.new(-50, -50, -50),
		Brightness = -1,
		ExposureCompensation = -0.5,
		ColorShift_Bottom = Vector3.new(-50, -50, -50),
		ColorShift_Top = Vector3.new(-50, -50, -50),
		EnvironmentDiffuseScale = 0.2,
		EnvironmentSpecularScale = 0.2,
		OutdoorAmbient = Vector3.new(-50, -50, -50),
		FogColor = Vector3.new(-50, -50, -50),
		FogStart = 50
	},
	["Dust storm"] = {
		Ambient = Vector3.new(50, 25, -25),
		Brightness = 1.5,
		ExposureCompensation = 0.1,
		ColorShift_Bottom = Vector3.new(50, 25, -25),
		ColorShift_Top = Vector3.new(50, 25, -25),
		EnvironmentDiffuseScale = 0.3,
		EnvironmentSpecularScale = 0.3,
		OutdoorAmbient = Vector3.new(50, 25, -25),
		FogColor = Vector3.new(50, 25, -25),
		FogStart = 100
	},
	["Fire storm"] = {
		Ambient = Vector3.new(50, -25, -50),
		Brightness = 3,
		ExposureCompensation = 0.5,
		ColorShift_Bottom = Vector3.new(50, -25, -50),
		ColorShift_Top = Vector3.new(50, 0, -25),
		EnvironmentDiffuseScale = 0.4,
		EnvironmentSpecularScale = 0.4,
		OutdoorAmbient = Vector3.new(50, -25, -50),
		FogColor = Vector3.new(50, -50, -50),
		FogStart = 0
	},
	["Foggy"] = {
		Ambient = Vector3.new(25, 25, 25),
		Brightness = -1,
		ExposureCompensation = -0.2,
		ColorShift_Bottom = Vector3.new(25, 25, 25),
		ColorShift_Top = Vector3.new(25, 25, 25),
		EnvironmentDiffuseScale = 0.5,
		EnvironmentSpecularScale = 0.5,
		OutdoorAmbient = Vector3.new(25, 25, 25),
		FogColor = Vector3.new(25, 25, 25),
		FogStart = 0
	},
	["Hail storm"] = {
		Ambient = Vector3.new(50, 50, 50),
		Brightness = -1.5,
		ExposureCompensation = -0.3,
		ColorShift_Bottom = Vector3.new(50, 50, 50),
		ColorShift_Top = Vector3.new(50, 50, 50),
		EnvironmentDiffuseScale = 0.35,
		EnvironmentSpecularScale = 0.35,
		OutdoorAmbient = Vector3.new(50, 50, 50),
		FogColor = Vector3.new(50, 50, 50),
		FogStart = 75
	},
	["Rain"] = {
		Ambient = Vector3.new(-25, -25, -25),
		Brightness = -1.5,
		ExposureCompensation = 0,
		ColorShift_Bottom = Vector3.new(-25, -25, -25),
		ColorShift_Top = Vector3.new(-25, -25, -25),
		EnvironmentDiffuseScale = 0.3,
		EnvironmentSpecularScale = 0.3,
		OutdoorAmbient = Vector3.new(-25, -25, -25),
		FogColor = Vector3.new(-25, -25, -25),
		FogStart = 50
	},
	["Sleet"] = {
		Ambient = Vector3.new(50, 50, 50),
		Brightness = -.75,
		ExposureCompensation = -0.2,
		ColorShift_Bottom = Vector3.new(50, 50, 50),
		ColorShift_Top = Vector3.new(50, 50, 50),
		EnvironmentDiffuseScale = 0.4,
		EnvironmentSpecularScale = 0.4,
		OutdoorAmbient = Vector3.new(50, 50, 50),
		FogColor = Vector3.new(50, 50, 50),
		FogStart = 0
	},
	["Snow"] = {
		Ambient = Vector3.new(50, 50, 50),
		Brightness = 2,
		ExposureCompensation = 0.4,
		ColorShift_Bottom = Vector3.new(50, 50, 50),
		ColorShift_Top = Vector3.new(50, 50, 50),
		EnvironmentDiffuseScale = 0.5,
		EnvironmentSpecularScale = 0.5,
		OutdoorAmbient = Vector3.new(50, 50, 50),
		FogColor = Vector3.new(50, 50, 50),
		FogStart = 20
	},
	["Thunder storm"] = {
		Ambient = Vector3.new(-50, -50, -50),
		Brightness = -1,
		ExposureCompensation = -0.3,
		ColorShift_Bottom = Vector3.new(-50, -50, -50),
		ColorShift_Top = Vector3.new(-50, -50, -50),
		EnvironmentDiffuseScale = 0.2,
		EnvironmentSpecularScale = 0.2,
		OutdoorAmbient = Vector3.new(-50, -50, -50),
		FogColor = Vector3.new(-50, -50, -50),
		FogStart = 50
	},
}
local v3 = Vector3.new
local WeatherColorDictionary = {
	-- influence the lighting
	Sunny = {
		["Asphalt"] = v3(50, 50, 50),
		["Basalt"] = v3(50, 50, 50),
		["Brick"] = v3(50, 30, 20),
		["Cobblestone"] = v3(30, 30, 20),
		["Concrete"] = v3(30, 30, 20),
		["CrackedLava"] = v3(50, 0, 0),
		["Glacier"] = v3(50, 50, 50),
		["Grass"] = v3(30, 50, 20),
		["Ground"] = v3(30, 30, 20),
		["Ice"] = v3(50, 50, 50),
		["LeafyGrass"] = v3(30, 50, 20),
		["Limestone"] = v3(50, 50, 50),
		["Mud"] = v3(30, 30, 20),
		["Pavement"] = v3(30, 30, 20),
		["Rock"] = v3(30, 30, 20),
		["Salt"] = v3(50, 50, 50),
		["Sand"] = v3(30, 30, 20),
		["Sandstone"] = v3(30, 30, 20),
		["Slate"] = v3(30, 30, 20),
		["Snow"] = v3(50, 50, 50),
		["WoodPlanks"] = v3(0, 0, 0), -- no affect wood planks are always inside houses
	},
	Blizzard = {
		["Asphalt"] = v3(50, 50, 50),
		["Basalt"] = v3(50, 50, 50),
		["Brick"] = v3(50, 30, 20),
		["Cobblestone"] = v3(30, 30, 20),
		["Concrete"] = v3(30, 30, 20),
		["CrackedLava"] = v3(50, 0, 0),
		["Glacier"] = v3(50, 50, 50),
		["Grass"] = v3(30, 50, 20),
		["Ground"] = v3(30, 30, 20),
		["Ice"] = v3(50, 50, 50),
		["LeafyGrass"] = v3(30, 50, 20),
		["Limestone"] = v3(50, 50, 50),
		["Mud"] = v3(30, 30, 20),
		["Pavement"] = v3(30, 30, 20),
		["Rock"] = v3(30, 30, 20),
		["Salt"] = v3(50, 50, 50),
		["Sand"] = v3(30, 30, 20),
		["Sandstone"] = v3(30, 30, 20),
		["Slate"] = v3(30, 30, 20),
		["Snow"] = v3(50, 50, 50),
		["WoodPlanks"] = v3(0, 0, 0), -- no affect wood planks are always inside houses
	},
	["Dark Rain"] = {
		["Asphalt"] = v3(-50, -50, -50),
		["Basalt"] = v3(-50, -50, -50),
		["Brick"] = v3(-30, -30, -30),
		["Cobblestone"] = v3(-30, -30, -30),
		["Concrete"] = v3(-30, -30, -30),
		["CrackedLava"] = v3(-50, 0, 0),
		["Glacier"] = v3(-50, -50, -50),
		["Grass"] = v3(-30, -50, -30),
		["Ground"] = v3(-30, -30, -30),
		["Ice"] = v3(-50, -50, -50),
		["LeafyGrass"] = v3(-30, -50, -30),
		["Limestone"] = v3(-50, -50, -50),
		["Mud"] = v3(-30, -30, -30),
		["Pavement"] = v3(-30, -30, -30),
		["Rock"] = v3(-30, -30, -30),
		["Salt"] = v3(-50, -50, -50),
		["Sand"] = v3(-30, -30, -30),
		["Sandstone"] = v3(-30, -30, -30),
		["Slate"] = v3(-30, -30, -30),
		["Snow"] = v3(-50, -50, -50),
		["WoodPlanks"] = v3(0, 0, 0), -- no affect wood planks are always inside houses
	},
	["Dust storm"] = {
		["Asphalt"] = v3(30, 20, 10),
		["Basalt"] = v3(30, 20, 10),
		["Brick"] = v3(30, 20, 10),
		["Cobblestone"] = v3(30, 20, 10),
		["Concrete"] = v3(30, 20, 10),
		["CrackedLava"] = v3(30, 0, 0),
		["Glacier"] = v3(30, 20, 10),
		["Grass"] = v3(30, 20, 10),
		["Ground"] = v3(30, 20, 10),
		["Ice"] = v3(30, 20, 10),
		["LeafyGrass"] = v3(30, 20, 10),
		["Limestone"] = v3(30, 20, 10),
		["Mud"] = v3(30, 20, 10),
		["Pavement"] = v3(30, 20, 10),
		["Rock"] = v3(30, 20, 10),
		["Salt"] = v3(30, 20, 10),
		["Sand"] = v3(30, 20, 10),
		["Sandstone"] = v3(30, 20, 10),
		["Slate"] = v3(30, 20, 10),
		["Snow"] = v3(30, 20, 10),
		["WoodPlanks"] = v3(0, 0, 0), -- no affect wood planks are always inside houses
	},
	["Fire storm"] = {
		["Asphalt"] = v3(50, 0, 0),
		["Basalt"] = v3(50, 0, 0),
		["Brick"] = v3(50, 0, 0),
		["Cobblestone"] = v3(50, 0, 0),
		["Concrete"] = v3(50, 0, 0),
		["CrackedLava"] = v3(50, 0, 0),
		["Glacier"] = v3(50, 0, 0),
		["Grass"] = v3(50, 0, 0),
		["Ground"] = v3(50, 0, 0),
		["Ice"] = v3(50, 0, 0),
		["LeafyGrass"] = v3(50, 0, 0),
		["Limestone"] = v3(50, 0, 0),
		["Mud"] = v3(50, 0, 0),
		["Pavement"] = v3(50, 0, 0),
		["Rock"] = v3(50, 0, 0),
		["Salt"] = v3(50, 0, 0),
		["Sand"] = v3(50, 0, 0),
		["Sandstone"] = v3(50, 0, 0),
		["Slate"] = v3(50, 0, 0),
		["Snow"] = v3(50, 0, 0),
		["WoodPlanks"] = v3(0, 0, 0),
	},-- no affect wood planks are always inside houses
	["Foggy"] = {
		["Asphalt"] = v3(20, 20, 20),
		["Basalt"] = v3(15, 15, 15),
		["Brick"] = v3(30, 20, 10),
		["Cobblestone"] = v3(25, 25, 15),
		["Concrete"] = v3(25, 25, 20),
		["CrackedLava"] = v3(30, -10, -10),
		["Glacier"] = v3(40, 30, 50),
		["Grass"] = v3(10, 20, 5),
		["Ground"] = v3(20, 15, 10),
		["Ice"] = v3(40, 35, 45),
		["LeafyGrass"] = v3(15, 25, 10),
		["Limestone"] = v3(45, 40, 35),
		["Mud"] = v3(10, 5, 0),
		["Pavement"] = v3(30, 30, 25),
		["Rock"] = v3(20, 25, 30),
		["Salt"] = v3(40, 35, 30),
		["Sand"] = v3(25, 20, 15),
		["Sandstone"] = v3(20, 15, 10),
		["Slate"] = v3(15, 20, 25),
		["Snow"] = v3(20, 20, 20),
		["WoodPlanks"] = v3(0, 0, 0)
	},
	["Hail storm"] = {
		["Asphalt"] = v3(10, 10, 10),
		["Basalt"] = v3(10, 10, 10),
		["Brick"] = v3(20, 15, 10),
		["Cobblestone"] = v3(15, 15, 10),
		["Concrete"] = v3(15, 15, 10),
		["CrackedLava"] = v3(20, -20, -20),
		["Glacier"] = v3(30, 25, 40),
		["Grass"] = v3(5, 10, 0),
		["Ground"] = v3(15, 10, 5),
		["Ice"] = v3(30, 25, 35),
		["LeafyGrass"] = v3(10, 20, 5),
		["Limestone"] = v3(35, 30, 25),
		["Mud"] = v3(5, 0, -5),
		["Pavement"] = v3(20, 20, 15),
		["Rock"] = v3(15, 20, 25),
		["Salt"] = v3(30, 25, 20),
		["Sand"] = v3(20, 15, 10),
		["Sandstone"] = v3(15, 10, 5),
		["Slate"] = v3(10, 15, 20),
		["Snow"] = v3(10, 10, 10),
		["WoodPlanks"] = v3(0, 0, 0)
	},
	["Thunder storm"] = {
		["Asphalt"] = v3(-10, -10, -10),
		["Basalt"] = v3(-10, -10, -10),
		["Brick"] = v3(-20, -15, -10),
		["Cobblestone"] = v3(-15, -15, -10),
		["Concrete"] = v3(-15, -15, -10),
		["CrackedLava"] = v3(-20, -20, -20),
		["Glacier"] = v3(-30, -25, 40),
		["Grass"] = v3(-5, -10, 0),
		["Ground"] = v3(-15, 10, 5),
		["Ice"] = v3(-30, -25, 35),
		["LeafyGrass"] = v3(-10, 20, 5),
		["Limestone"] = v3(35, 30, 25),
		["Mud"] = v3(5, 0, -5),
		["Pavement"] = v3(20, 20, 15),
		["Rock"] = v3(15, 20, 25),
		["Salt"] = v3(30, 25, 20),
		["Sand"] = v3(20, 15, 10),
		["Sandstone"] = v3(15, 10, 5),
		["Slate"] = v3(10, 15, 20),
		["Snow"] = v3(10, 10, 10),
		["WoodPlanks"] = v3(0, 0, 0)
	},
	["Rain"] = {
		["Asphalt"] = v3(5, 5, 5),
		["Basalt"] = v3(5, 5, 5),
		["Brick"] = v3(15, 10, 5),
		["Cobblestone"] = v3(10, 10, 5),
		["Concrete"] = v3(10, 10, 5),
		["CrackedLava"] = v3(15, -25, -25),
		["Glacier"] = v3(20, 15, 30),
		["Grass"] = v3(0, 5, -5),
		["Ground"] = v3(10, 5, 0),
		["Ice"] = v3(20, 15, 25),
		["LeafyGrass"] = v3(5, 15, 0),
		["Limestone"] = v3(25, 20, 15),
		["Mud"] = v3(0, -5, -10),
		["Pavement"] = v3(15, 15, 10),
		["Rock"] = v3(10, 15, 20),
		["Salt"] = v3(20, 15, 10),
		["Sand"] = v3(15, 10, 5),
		["Sandstone"] = v3(10, 5, 0),
		["Slate"] = v3(5, 10, 15),
		["Snow"] = v3(5, 5, 5),
		["WoodPlanks"] = v3(0, 0, 0)
	},
	["Sleet"] = {
		["Asphalt"] = v3(0, 0, 0),
		["Basalt"] = v3(0, 0, 0),
		["Brick"] = v3(10, 5, 0),
		["Cobblestone"] = v3(5, 5, 0),
		["Concrete"] = v3(5, 5, 0),
		["CrackedLava"] = v3(10, -30, -30),
		["Glacier"] = v3(10, 5, 20),
		["Grass"] = v3(-5, 0, -10),
		["Ground"] = v3(5, 0, -5),
		["Ice"] = v3(10, 5, 15),
		["LeafyGrass"] = v3(0, 10, -5),
		["Limestone"] = v3(15, 10, 5),
		["Mud"] = v3(-5, -10, -15),
		["Pavement"] = v3(10, 10, 5),
		["Rock"] = v3(5, 10, 15),
		["Salt"] = v3(10, 5, 0),
		["Sand"] = v3(10, 5, 0),
		["Sandstone"] = v3(5, 0, -5),
		["Slate"] = v3(0, 5, 10),
		["Snow"] = v3(0, 0, 0),
		["WoodPlanks"] = v3(0, 0, 0)
	},
	["Snow"] = {
		["Asphalt"] = v3(-10, -10, -10),
		["Basalt"] = v3(-10, -10, -10),
		["Brick"] = v3(5, 0, -5),
		["Cobblestone"] = v3(0, 0, -5),
		["Concrete"] = v3(0, 0, -5),
		["CrackedLava"] = v3(5, -35, -35),
		["Glacier"] = v3(0, -5, 10),
		["Grass"] = v3(-10, -5, -15),
		["Ground"] = v3(0, -5, -10),
		["Ice"] = v3(0, -5, 5),
		["LeafyGrass"] = v3(-5, 5, -10),
		["Limestone"] = v3(5, 0, -5),
		["Mud"] = v3(-10, -15, -20),
		["Pavement"] = v3(5, 5, 0),
		["Rock"] = v3(0, 5, 10),
		["Salt"] = v3(5, 0, -5),
		["Sand"] = v3(5, 0, -5),
		["Sandstone"] = v3(0, -5, -10),
		["Slate"] = v3(-5, 0, 5),
		["Snow"] = v3(-10, -10, -10),
		["WoodPlanks"] = v3(0, 0, 0)
	},
}
local TimeColorDictionary = {
	Evening = {
		["Asphalt"] = Color3.fromRGB(65, 68, 61),
		["Basalt"] = Color3.fromRGB(46, 56, 61),
		["Brick"] = Color3.fromRGB(79, 48, 36),
		["Cobblestone"] = Color3.fromRGB(94, 87, 63),
		["Concrete"] = Color3.fromRGB(102, 92, 83),
		["CrackedLava"] = Color3.fromRGB(255, 0, 0), -- very bright emitting light
		["Glacier"] = Color3.fromRGB(93, 135, 234),
		["Grass"] = Color3.fromRGB(33, 66, 16),
		["Ground"] = Color3.fromRGB(52, 47, 30),
		["Ice"] = Color3.fromRGB(86, 171, 224),
		["LeafyGrass"] = Color3.fromRGB(57, 93, 32),
		["Limestone"] = Color3.fromRGB(172, 158, 139),
		["Mud"] = Color3.fromRGB(43, 35, 28),
		["Pavement"] = Color3.fromRGB(98, 98, 94),
		["Rock"] = Color3.fromRGB(65, 83, 88),
		["Salt"] = Color3.fromRGB(198, 185, 167),
		["Sand"] = Color3.fromRGB(157, 154, 113),
		["Sandstone"] = Color3.fromRGB(115, 73, 51),
		["Slate"] = Color3.fromRGB(62, 65, 79),
		["Snow"] = Color3.fromRGB(165, 169, 185),
		["WoodPlanks"] = Color3.fromRGB(52, 35, 24),
	},
	Day = {
		["Asphalt"] = Color3.fromRGB(94, 99, 89),
		["Basalt"] = Color3.fromRGB(62, 68, 80),
		["Brick"] = Color3.fromRGB(130, 80, 59),
		["Cobblestone"] = Color3.fromRGB(116, 108, 78),
		["Concrete"] = Color3.fromRGB(116, 108, 79),
		["CrackedLava"] = Color3.fromRGB(127, 0, 0),
		["Glacier"] = Color3.fromRGB(129, 176, 234),
		["Grass"] = Color3.fromRGB(52, 106, 26),
		["Ground"] = Color3.fromRGB(102, 92, 59),
		["Ice"] = Color3.fromRGB(129, 192, 224),
		["LeafyGrass"] = Color3.fromRGB(80, 132, 46),
		["Limestone"] = Color3.fromRGB(214, 197, 173),
		["Mud"] = Color3.fromRGB(56, 46, 36),
		["Pavement"] = Color3.fromRGB(146, 146, 140),
		["Rock"] = Color3.fromRGB(102, 108, 111),
		["Salt"] = Color3.fromRGB(198, 189, 181),
		["Sand"] = Color3.fromRGB(143, 125, 95),
		["Sandstone"] = Color3.fromRGB(137, 90, 71),
		["Slate"] = Color3.fromRGB(80, 84, 102),
		["Snow"] = Color3.fromRGB(195, 199, 218),
		["WoodPlanks"] = Color3.fromRGB(104, 76, 57),
	},
	Morning = {
		["Asphalt"] = Color3.fromRGB(155, 165, 121),
		["Basalt"] = Color3.fromRGB(93, 102, 120),
		["Brick"] = Color3.fromRGB(166, 101, 76),
		["Cobblestone"] = Color3.fromRGB(116, 114, 94),
		["Concrete"] = Color3.fromRGB(105, 116, 105),
		["CrackedLava"] = Color3.fromRGB(127, 0, 0),
		["Glacier"] = Color3.fromRGB(129, 176, 234),
		["Grass"] = Color3.fromRGB(59, 152, 31),
		["Ground"] = Color3.fromRGB(113, 94, 63),
		["Ice"] = Color3.fromRGB(129, 192, 224),
		["LeafyGrass"] = Color3.fromRGB(61, 136, 44),
		["Limestone"] = Color3.fromRGB(214, 197, 173),
		["Mud"] = Color3.fromRGB(56, 46, 36),
		["Pavement"] = Color3.fromRGB(163, 163, 157),
		["Rock"] = Color3.fromRGB(91, 97, 111),
		["Salt"] = Color3.fromRGB(198, 170, 151),
		["Sand"] = Color3.fromRGB(166, 163, 114),
		["Sandstone"] = Color3.fromRGB(162, 106, 84),
		["Slate"] = Color3.fromRGB(106, 111, 135),
		["Snow"] = Color3.fromRGB(235, 246, 255),
		["WoodPlanks"] = Color3.fromRGB(115, 87, 59),
	},
	Afternoon = {
		["Asphalt"] = Color3.fromRGB(120, 125, 115),
		["Basalt"] = Color3.fromRGB(80, 90, 100),
		["Brick"] = Color3.fromRGB(150, 90, 70),
		["Cobblestone"] = Color3.fromRGB(130, 120, 90),
		["Concrete"] = Color3.fromRGB(130, 120, 90),
		["CrackedLava"] = Color3.fromRGB(150, 0, 0),
		["Glacier"] = Color3.fromRGB(140, 190, 240),
		["Grass"] = Color3.fromRGB(60, 120, 30),
		["Ground"] = Color3.fromRGB(110, 100, 70),
		["Ice"] = Color3.fromRGB(140, 200, 230),
		["LeafyGrass"] = Color3.fromRGB(90, 140, 50),
		["Limestone"] = Color3.fromRGB(220, 200, 180),
		["Mud"] = Color3.fromRGB(60, 50, 40),
		["Pavement"] = Color3.fromRGB(150, 150, 140),
		["Rock"] = Color3.fromRGB(110, 120, 120),
		["Salt"] = Color3.fromRGB(200, 190, 180),
		["Sand"] = Color3.fromRGB(150, 130, 100),
		["Sandstone"] = Color3.fromRGB(140, 100, 80),
		["Slate"] = Color3.fromRGB(90, 95, 110),
		["Snow"] = Color3.fromRGB(200, 205, 220),
		["WoodPlanks"] = Color3.fromRGB(110, 80, 60),
	},
	Night = {
		["Asphalt"] = Color3.fromRGB(50, 55, 50),
		["Basalt"] = Color3.fromRGB(40, 50, 60),
		["Brick"] = Color3.fromRGB(70, 40, 30),
		["Cobblestone"] = Color3.fromRGB(80, 75, 55),
		["Concrete"] = Color3.fromRGB(90, 80, 70),
		["CrackedLava"] = Color3.fromRGB(100, 0, 0),
		["Glacier"] = Color3.fromRGB(80, 120, 200),
		["Grass"] = Color3.fromRGB(30, 60, 15),
		["Ground"] = Color3.fromRGB(40, 35, 20),
		["Ice"] = Color3.fromRGB(70, 140, 190),
		["LeafyGrass"] = Color3.fromRGB(50, 80, 25),
		["Limestone"] = Color3.fromRGB(150, 140, 120),
		["Mud"] = Color3.fromRGB(35, 30, 20),
		["Pavement"] = Color3.fromRGB(80, 80, 75),
		["Rock"] = Color3.fromRGB(50, 65, 70),
		["Salt"] = Color3.fromRGB(170, 160, 140),
		["Sand"] = Color3.fromRGB(120, 110, 80),
		["Sandstone"] = Color3.fromRGB(100, 65, 45),
		["Slate"] = Color3.fromRGB(50, 55, 70),
		["Snow"] = Color3.fromRGB(140, 145, 160),
		["WoodPlanks"] = Color3.fromRGB(50, 35, 20),
	},
	Midnight = {--same as evening
		["Asphalt"] = Color3.fromRGB(65, 68, 61),
		["Basalt"] = Color3.fromRGB(46, 56, 61),
		["Brick"] = Color3.fromRGB(79, 48, 36),
		["Cobblestone"] = Color3.fromRGB(94, 87, 63),
		["Concrete"] = Color3.fromRGB(102, 92, 83),
		["CrackedLava"] = Color3.fromRGB(255, 0, 0), -- very bright emitting light
		["Glacier"] = Color3.fromRGB(93, 135, 234),
		["Grass"] = Color3.fromRGB(33, 66, 16),
		["Ground"] = Color3.fromRGB(52, 47, 30),
		["Ice"] = Color3.fromRGB(86, 171, 224),
		["LeafyGrass"] = Color3.fromRGB(57, 93, 32),
		["Limestone"] = Color3.fromRGB(172, 158, 139),
		["Mud"] = Color3.fromRGB(43, 35, 28),
		["Pavement"] = Color3.fromRGB(98, 98, 94),
		["Rock"] = Color3.fromRGB(65, 83, 88),
		["Salt"] = Color3.fromRGB(198, 185, 167),
		["Sand"] = Color3.fromRGB(157, 154, 113),
		["Sandstone"] = Color3.fromRGB(115, 73, 51),
		["Slate"] = Color3.fromRGB(62, 65, 79),
		["Snow"] = Color3.fromRGB(165, 169, 185),
		["WoodPlanks"] = Color3.fromRGB(52, 35, 24),
	},
}
--local weathermap=require(game.ReplicatedStorage.GlobalSpells.ChatbotAlgorithm.ChatModule.MaterialWeatherMap)


--local Event=script.Parent.Parent.Remote

local DayLength = 6 * 24 -- Total length of a day in minutes
local interupt=nil
--local Daynight=Event.Parent.DayNight
local lightefx

local function HeartMoon()
	local	Sky=Lighting:FindFirstChild("Sky")
	local	Hearts=player.leaderstats.Hearts.Value
	if Hearts<=120 then Sky.SunAngularSize=	.1+Hearts/2 else Sky.SunAngularSize=60 end
end
local function Light(properties, transition_time)
	return efx:Create(Lighting, TweenInfo.new(transition_time), properties)
end

local function applyNoise(properties, rgbThreshold, numberThreshold,weather)
	local function addNoise(value, threshold)
		return value + math.random(-threshold, threshold)
	end

	local function addNoiseToColor(color, threshold)
		return Color3.fromRGB(
			math.clamp(addNoise(color.R * 255, threshold), 0, 255),
			math.clamp(addNoise(color.G * 255, threshold), 0, 255),
			math.clamp(addNoise(color.B * 255, threshold), 0, 255)
		)
	end

	local noisyProperties = {}
	for key, value in pairs(properties) do

		if typeof(value) == "Color3" then
			noisyProperties[key] = addNoiseToColor(value, rgbThreshold)
		elseif typeof(value) == "number" then
			noisyProperties[key] = addNoise(value, numberThreshold)
		else
			noisyProperties[key] = value
		end
	end

	return noisyProperties
end
local function applyWeatherTransformation(lightingData, weatherData)
	local function addVector3ToColor3(color, vector)
		return Color3.fromRGB(
			math.clamp(color.R * 255 + vector.X, 0, 255),
			math.clamp(color.G * 255 + vector.Y, 0, 255),
			math.clamp(color.B * 255 + vector.Z, 0, 255)
		)
	end

	local transformedData = {}
	for key, value in pairs(lightingData) do
		if typeof(value) == "Color3" and weatherData[key] then
			transformedData[key] = addVector3ToColor3(value, weatherData[key])
		elseif typeof(value) == "number" and weatherData[key] then
			if string.find(key,"Fog")==nil then
				transformedData[key] = math.clamp(value + weatherData[key],-2,4)
			else 
				transformedData[key] = value + weatherData[key]
			end
		else
			transformedData[key] = value
		end
	end

	return transformedData
end


local function updateGeographicLatitude()
	local character = player.Character or player.CharacterAdded:Wait()
	local rootPart = character:WaitForChild("HumanoidRootPart")
	-- Calculate the latitude based on the position of the HumanoidRootPart
	local latitude = (rootPart.Position.X + rootPart.Position.Z) % 360
	-- Set the GeographicLatitude of the Lighting
	return latitude
end


local character = player.Character or player.CharacterAdded:Wait()
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")

local sunDirection = Lighting:GetSunDirection()

-- Calculate the position for the light sword
local swordOffset = sunDirection * 40 -- Adjust the multiplier to set the distance from the player
local swordPosition = humanoidRootPart.Position + swordOffset

-- Create the light sword
local lightSword = Instance.new("Part")
lightSword.Name = "LightSword"
lightSword.Size = Vector3.new(1, 1, 1)
lightSword.Transparency=1
lightSword.CastShadow=false
lightSword.CFrame = CFrame.new(swordPosition,humanoidRootPart.Position)
lightSword.Anchored = true
--lightSword.BrickColor = BrickColor.new("Bright yellow")

-- Add a light source to the sword
local pointLight = Instance.new("SpotLight")
pointLight.Parent = lightSword
pointLight.Brightness = 1 -- Adjust brightness as needed
pointLight.Range = 60 -- Adjust range as needed
pointLight.Shadows=true
-- Parent the sword to the workspace
lightSword.Parent = workspace
local sunl=nil
local function runlightsetting(v, previousTime,key)
	v.GeographicLatitude = updateGeographicLatitude()

	local duration = (v.ClockTime - previousTime) * (DayLength / 24)	
	local def=TimeColorDictionary[key]
	LerpTerrainColor(def,15*duration)

	task.desynchronize()
	local c=applyNoise(v, 50, 0.25)

	--local weatherstate=player.PlayerGui.Bars.WeatherState
	--if WeatherDictionary[weatherstate.Value]~=nil then
	--	c=applyWeatherTransformation(c, WeatherDictionary[weatherstate.Value])
	--	applyWeatherTransformation(def,WeatherDictionary[weatherstate.Value])
	--end




	previousTime = v.ClockTime		
	task.synchronize()
	if sunl then sunl:Cancel() end
	sunl=efx:Create(pointLight,TweenInfo.new(duration),{Brightness=c.Brightness,Color=c.OutdoorAmbient})
	sunl:Play()
	if lightefx~=nil then
		lightefx:Cancel()
	end

	lightefx=Light(c, duration)

	lightefx:Play()
	--	task.desynchronize()
	local incre=duration/30
	for t=1, 30 do 
		task.wait(incre)
		local sunDirection = Lighting:GetSunDirection()
		local character = player.Character --or player.CharacterAdded:Wait()
		local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
		local swordOffset = sunDirection * 40 -- Adjust the multiplier to set the distance from the player
		local swordPosition = humanoidRootPart.Position + swordOffset

		lightSword.CFrame = CFrame.new(swordPosition,humanoidRootPart.Position)

		if interupt then
			break
		end
	end

end

--Daynight:GetPropertyChangedSignal("Value"):ConnectParallel(function()
--	interupt=true
--	if lightefx~=nil then
--		lightefx:Cancel()
--	end		
--	if Daynight.Value==1 then		
--		local v=TimeDictionary.Day
--		local previousTime=v.ClockTime
--		runlightsetting(v, previousTime)
--		interupt=false
--	else 		
--		local v=TimeDictionary.Night
--		local previousTime=v.ClockTime
--		runlightsetting(v, previousTime)
--		interupt=false
--	end

--end)
Lighting.FogEnd=190

while true do
	local previousTime = 0

	for key, v in pairs(TimeDictionary) do

		if interupt then 
			break
		end	
	--	HeartMoon()
		--local Floormat=player.PlayerGui.Musicplayer.FloorMaterial.Value
		task.synchronize()
	--	weathermap.SetWeather(Floormat,player)	

		runlightsetting(v, previousTime,key)
		if interupt then 
			break
		end
	end
	task.wait(.1)
end

The features I would like to highlight is;

  1. LerpTerrainColor function that gradually changes the terrain color to the desired shade.
  2. Night time, Morning, Afternoon, Evening, Midnight mapping to desired lighting effect of every property of the lighting.
  3. Weather Influence. Influence the lighting via your weather effects.
  4. Dynamic Sun Latitude Positioning that changes depending on the player’s position,
  5. Looping Day/Night Cycle,
  6. Very performant, uses less than a third of a percent of resources on most devices. (tween service) Only one tween is played at a time, and implementation of task.desynchronize where possible.
  7. Artificial Sun, a light source is positioned where the sun is in the sky (impemented as a spotlight facing the player) a specified radius from the player, enhancing the effect of the sun and allowing for custom sun colors.
  8. Snippets showing examples of additional features, I had to disable some minor features to share this from my project. Included are commented sections demonstrating resetting the day/night cycle when say a character goes to sleep and wakes up. Or You have weather, have a dynamic sun size.
  9. Applies noise to the color for every cycle adding more variance to the appearance of the atmosphere.
    This currently only uses native objects such as lighting, and terrain, and a light emitter to be an alternative to Depth of field, Blur and Bloom or you could add that functionality yourself and I may do it myself and update this resource.
5 Likes

Don’t spotlights have a very limited range?

1 Like

They have a range of 60 so it’s position that many units away, it was the final thing I added, what’s cool about it is it emits from the direction of the sun facing towards the player. so you could use that to give the sun a more lighting effect

in the code the part is position 40 units away from the player in the position of the sun

local swordOffset = sunDirection * 40 -- Adjust the multiplier to set the distance from the player
local swordPosition = humanoidRootPart.Position + swordOffset

The artificial sun’s light color and brightness is determined by the outdoor ambient and brightness of the current condition as a neat way to implement the lighting effect.

2 Likes

Can you show a video of this? This seems quite cool but it lacks a video.

2 Likes

Buildings can be bigger than 40 studs. How do you make sure that there’s no sun inside of buildings?

1 Like

That’s a good point I have changed it to a surface light with an object that is 120 x 40 x 1 studs on the front Face. positioned 55 studs away, this effect would work better for simulated the sun more effectively, in addition you can add other lights, such as a dynamic light object that is determined by an object value to highlight a target, or a spotlight pointlight to achieve your desired effect.

I would suggest the above change and expand the distance to 60, this is a potentially more performant and an alternative/enhancement option to global lighting. In my tests the light shines through windows, (shadows enabled in the light object) in the occasion a player is inside a building I am currently using the floor material to change the weather, so if the floor material is a specified type I could disable/ change the weather to the appropriate value using native functionality.
The spotlight was a bit choppy in my tests inside buildings, but the surface light covering the rendering distance is more flexible, and effective at simulated the light from the sun.

The code is fortunately very simple, and elegantly written, all of the datapoints in the TimeDictionary are properties of the lighting, this format is interchangeable with tweens.
The TimeColorDictionary is useful because it maps all of the materials of the terrain, and adjust the color based on the time. This is the most process intensive part because it gradually changes the color of the terrain for the amount of duration (frames) steps. It’s a good starting point it’s relatively complete to me, but the open sourced version here has the weather influence commented out but you can reimplement it by defining a weather condition via a string.