How to Tell the "Light Level" of a Surface?

Hello,

I want to be able to tell the “light level” of a surface on a part. If you’ve played minecraft before, each block has a light level. I want to achieve a similar result in Roblox. In simpler terms, how could I determine if a player is in the light or in the dark? I’ve tried experimenting with regions and parts, but I’m looking for something more dynamic.

Thank you

4 Likes

You could find the distance between the light block and the player, and apply it to some sort of math function to determine a light level.

local function returnLightLevel(distance: number)
    if distance == 0 then
        return math.huge
    end

    return (1 / math.pow(distance, 2)) -- 1/x^2
end
-- Now you can scale the value however you like
1 Like

Hi @TheBrainy06 ,

Thank you for the response. While your idea does work, it doesn’t take into account for walls. I’ll tinker with it and add some sort of ray cast and see if it works.

Thank you

It’s hard to quantify the brightness of a surface. For one you could raycast to every light in the world, and then do the calculation to find brightness. Also include the sun. It gets more complicated as you need to determine if a part is even being lit by a surface anyway, especially if it’s an angled light.

You could use raycasts, or if your game is voxel based, you could use something like an Octree to raycast to nearby voxels.

math.pow is slow; use
^ operator intead

1 Like

For the very simple case of assuming the whole block will have uniform lighting you can simply raycast from the block to any light sources that would hit it to determine if it’s lit. If you need more complexity though you’ll basically have to get a projection of whatever may be casting a shadow from the lights perspective and use that to mask out the light. I will note though that once you start getting to that level depending on use case you may hit performance limitations quickly. If you just need to tell if a player is in a shadow, that’s one isPartInProjectedHull check per object per light which is fine with simple objects and limited lights, but a problem like handling shading is infeasible on the cpu in real time for any notable viewport size.

Wait what? Can you explain how to use an octree alongside a voxel-based spatial organization system? I feel like raycasting with octrees might be more of a computation redundancy than other methods that could be possible in a voxel structure.

To OP, I also think that the case that Minecraft has involves discretizing light filling, so that each block can store its own light data. On Roblox, unless you structure your game to work in the same way, you’ll get something that doesn’t look right because the default light instances don’t fill in discrete, identically sized “blocks.”

So you have these voxels right, you add them to an Octree data structure. Then, you can query for just the voxels around you pretty efficiently without having to loop through all the blocks in the world. Check this out for more information.

Isn’t a lookup in a uniform spatial hash faster than a lookup in an octree?

It depends on the use case, but I believe Octrees would be better in this case.

What does this mean? I am still learning about rendering, and I’d like to know more. I thought that a lookup in a voxel hash could be O(1) while a lookup in an octree is O(log(n))..?

I was thinking using a lighting system like Minecraft, so there would be grids and each block would have a light value. And then I could just smooth out the lighting on the client. Thank you for the reply.

1 Like