--METHOD 2 PARAMS
local PIXELS_PER_WAIT = 1000
local WAIT_PERIOD = 0

local LocalPlayer = game.Players.LocalPlayer
local LocalHumanoidRootPart = LocalPlayer.Character:WaitForChild("Head")
local terminate = false
local uis = game:GetService("UserInputService")

function RaycastSingular(i)
	if i > GRID_HEIGHT * GRID_WIDTH or terminate then
		return
	end
	
	local width = (GRID_WIDTH - ((i - 1) % GRID_WIDTH + 1) - (GRID_WIDTH / 2))
	local height = (GRID_HEIGHT - (math.floor((i - 1) / GRID_WIDTH) + 1)) - (GRID_HEIGHT / 2)
	
	--raycast ahead keeping RAYCAST_OFFSET in mind
	local rayParam = RaycastParams.new()
	rayParam.FilterDescendantsInstances = {LocalPlayer.Character}
	rayParam.FilterType = Enum.RaycastFilterType.Exclude

	local pos1 = workspace.CurrentCamera.CFrame
	local pos2 = (pos1 * CFrame.Angles(math.rad(height * RAYCAST_OFFSET), math.rad(width * RAYCAST_OFFSET), 0)).lookVector

	local raycastResult = workspace:Raycast(pos1.Position, pos2 * 1000, rayParam)

	if raycastResult then

		local colorValue

		local hitPart = raycastResult.Instance
		if hitPart and hitPart:IsA("BasePart") then
			local fadeAway = math.clamp(raycastResult.Distance / FOG_MULTIPLIER, 1, FOG_MAX)
			colorValue = Color3.new(hitPart.Color.r * fadeAway, hitPart.Color.g * fadeAway, hitPart.Color.b * fadeAway)
		else

			--make a color of black from 128,128,128 to 0,0,0 depending on the distance of hit
			local distance = (raycastResult.Position - LocalHumanoidRootPart.Position).Magnitude
			local colorValue = math.floor(128 * (1 - distance / 1000))

			if colorValue < 0 then
				colorValue = 0
			end

			colorValue = Color3.new(colorValue, colorValue, colorValue)
		end

		script.Parent.Container:WaitForChild(tostring(i)).BackgroundColor3 = colorValue

	else
		script.Parent.Container:WaitForChild(tostring(i)).BackgroundColor3=Color3.fromRGB(85, 170, 255)
	end

	i += 1
end

function RaycastAndApply()
	--raycast from the HumanoidRootPart forwards GRID_WIDTH * GRID_HEIGHT, offsetting by RAYCAST_OFFSET studs
	local i = 1
	for height = math.round(GRID_HEIGHT / 2), -math.round(GRID_HEIGHT/2), -1 do
		for width = math.round(GRID_WIDTH / 2) - 1, -math.round(GRID_WIDTH / 2), -1 do
			if i > GRID_HEIGHT * GRID_WIDTH or terminate then
				return
			end
			--raycast ahead keeping RAYCAST_OFFSET in mind
			local rayParam = RaycastParams.new()
			rayParam.FilterDescendantsInstances = {LocalPlayer.Character}
			rayParam.FilterType = Enum.RaycastFilterType.Exclude
			
			local pos1 = workspace.CurrentCamera.CFrame
			local pos2 = (pos1 * CFrame.Angles(math.rad(height * RAYCAST_OFFSET), math.rad(width * RAYCAST_OFFSET), 0)).lookVector
			
			local raycastResult = workspace:Raycast(pos1.Position, pos2 * 1000, rayParam)
			
			if raycastResult then
				
				local colorValue

				local hitPart = raycastResult.Instance
				if hitPart and hitPart:IsA("BasePart") then
					local fadeAway = math.clamp(raycastResult.Distance / FOG_MULTIPLIER, 1, FOG_MAX)
					colorValue = Color3.new(hitPart.Color.r * fadeAway, hitPart.Color.g * fadeAway, hitPart.Color.b * fadeAway)
				else
					
					--make a color of black from 128,128,128 to 0,0,0 depending on the distance of hit
					local distance = (raycastResult.Position - LocalHumanoidRootPart.Position).Magnitude
					local colorValue = math.floor(128 * (1 - distance / 1000))
					
					if colorValue < 0 then
						colorValue = 0
					end
					
					colorValue = Color3.new(colorValue, colorValue, colorValue)
				end
				
				script.Parent.Container:WaitForChild(tostring(i)).BackgroundColor3 = colorValue
				
			else
				script.Parent.Container:WaitForChild(tostring(i)).BackgroundColor3=Color3.fromRGB(85, 170, 255)
			end
			
			if CALMDOWN_RENDER then
				wait(CALMDOWN_RENDER)
			end
			
			i += 1
		end
	end
end

game.Close:Connect(function()
	terminate = true
end)

function notify(title, text)
	local CoreGui = game:GetService("StarterGui")

	CoreGui:SetCore("SendNotification", {
		Title = title;
		Text = text;
		Duration = 5;
	})
end


uis.InputBegan:Connect(function(input, processed)
	if processed then
		return
	end
	if input.KeyCode == Enum.KeyCode.Q then
		FOG_MAX = math.max(FOG_MAX - 1, 1)
		notify("Fog Level", "was changed to " .. FOG_MAX)
	end
	if input.KeyCode == Enum.KeyCode.E then
		FOG_MAX += 1
		notify("Fog Level", "was changed to " .. FOG_MAX)
	end
end)

if RENDER_METHOD == 1 then
	while true do
		wait(CALMDOWN)
		--clearAllTiles()
		RaycastAndApply()
		--wait(1)
		if terminate then
			break
		end
	end
else
	while true do
		wait(WAIT_PERIOD)
		for pixels = 1, PIXELS_PER_WAIT do
			RaycastSingular(math.random(1, GRID_HEIGHT*GRID_WIDTH))
		end
		if terminate then
			break
		end
	end
end