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.
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.
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.
+1.
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.
2 comments
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.
Thanks! Guess I will have to go with the cached option. They should add a way in the future.