Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Get lighting value of specific point?

Since the dynamic lighting system is voxel based, is there a way to get the lighting value of a specific voxel?

I need to have a script detect the lighting present at certain points.

2 comments

0

You can try iterating through all the lights in a map once and cache that value for later if the map is static. You can cast a ray from a point to the sky to check if it's obstructed (i.e. if it's under a shadow). There does not exist a trivial or elegant way of getting the light level at a certain point.

0

Thanks! Guess I will have to go with the cached option. They should add a way in the future.

1 answer

✓ Accepted answer

Look backwards

Okay, so realistically this is exactly the same as looking forwards, but that's normally against the point. To get the most basic sense of if it is illuminated, you'll have to use a lot of raycasting to get the visibility of lights.

local desc = function(i)
    local queue = {};
    local returns = {};
    local v = i;
    while v do
        local t = v:GetChildren();
        for i = 1, #t do
            local v = t[i]
	    if v:IsA("PointLight") then
                returns[#returns+1] = v;
	    end
            queue[#queue+1] = v;
        end;
        v = queue[#queue];
        queue[#queue] = nil;
    end;
    return returns;
end;

local CachedLights;
local function GetBasicLighting(Point, useImpliedSkyLight)
CachedLights = CachedLights or desc(workspace);
local LightingValue = 0;
if useImpliedSkyLight then
	if not workspace:FindPartOnRay(Ray.new(Point, game.Lighting:GetSunDirection()*500)) then
		LightingValue = 1;
	end;
end;
for i=1,#CachedLights do
	local v = CachedLights[i];
	local p = v.Parent;
	while not (p:IsA("Part") or p == workspace) do p = p.Parent end;
	if p ~= workspace then
		pos = p.Position;
		local dir = pos-Point;
		if dir.magnitude < v.Range then
			if workspace:FindPartOnRay(Ray.new(Point,dir)) == p then
				LightingValue = LightingValue + v.Brightness*(dir.magnitude/v.Range);
			end;
		end;
	end;
end;
return LightingValue;
end;

How does it work?
Really basically. First it checks if it can see the sun. If it can, it assumes it's fully illuminated. After that, it goes through all of the PointLights (And assumes only PointLights) and checks if it can see them, if they're in range, and then adds their brightness as a fraction based on the range.
I'd actually use an RGB value and convert that to brightness later but there's not much difference from a basic standpoint, but if you were being pedantic and really didn't care about performance then that would be the 100% accurate performance-eating lighting value grabber.

2 comments

0

+1.

0

What I currently have is a list of object values pointing to every spot/point light that I want to check with. Upon calling a modulefunction checkLight(target) it iterates raycasts through all the light objects to determine distance and total brightness. Thanks for your answer :)

This discussion is preserved as it was. New answers, comments, and votes are closed.