Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
5

Get lighting value of specific point?

Asked by 9 years ago

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.

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. XAXA 1569 — 9y
0
Thanks! Guess I will have to go with the cached option. They should add a way in the future. Sweetwater101 50 — 9y

1 answer

Log in to vote
2
Answered by 9 years ago

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.

0
+1. XAXA 1569 — 9y
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 :) Sweetwater101 50 — 8y
Ad

Answer this question