Get ambient light level at any point

I want to bump this thread, but as a feature request.

As pointed out in the thread, it is possible~ish to achieve this based on knowing where all your lights are and where the sun is, and @Maximum_ADHD made a cool module to handle it. However, doing it this way becomes infeasible and slow when you have a lot of lights around.

Also, after playing around with CloneTrooper’s module for a little bit, I found that it didn’t always provide accurate results. I haven’t worked through that though, so I don’t know if it’s the fault of his code or if there might be inherent limitations to the method that would further justify adding this as a feature.

16 Likes

What’s the use case for this?

In the original post:

And I want it so I can make a light sensor for Lumber Tycoon, the building sandbox game part of it. The use cases for that sensor would be so that users can wire the sensor to have their lights automatically turned on at night. However, to promote more creative uses, I don’t want it to be based only on time of day. They could hook it up to more things, like having a door automatically open when you approach it in a vehicle with your headlights on.

2 Likes
  • Having a light turn on when it becomes dark
  • Studio camera light that turns on when you’re in dark caves so you can see what you’re working with
  • Monster night vision that enables when it gets dark
  • Street lamps that come on when the area around them is dark
  • HUD that lights up in the dark (like your car’s dash when your lights turn on when it’s dark)
  • Vampire (or any other monster) damaged by sunlight
  • Spawn monsters in dark places
  • Detect how much a plant should grow based on its light level
  • Magic spells (light & dark) which require there to be a certain light level to cast

The voxel grid already stores this information, so it’d be much better for it to provide these already-calculated values instead of us having to slowly (and inaccurately) calculate them in Lua.

7 Likes

Checking if enemies can see you in a stealth game based on light (hidden when in shadows)

4 Likes

Thief

It’s the only reason you should need.

2 Likes

I may have written it someplace else but this API would place constraints on our lighting implementation that may be hard to maintain in the future.

Basically currently lighting is computed on CPU so we could implement this kind of API but going forward we plan to migrate to a GPU-only solution, which would require a completely separate implementation for this API to avoid GPU readback.

So while it’s not too hard to implement this right now, going forward this API may become problematic to support.

8 Likes

Hmmm, I’ve been thinking about experimenting with a home grown solution (since I don’t have enough personal projects on my plate already :). It’d require shooting rays from the point in question to the nearest light sources and to the sky given the current angle of the sun. If all of those rays hit things, or travel further than the light sources radius, then there is shadow. The clients method of calculating ambient occlusion makes this trickier though, you’ll need to at least know the thickness of any object you hit with the sky ray and maybe shoot several of them out in a shotgun pattern

Edit: I guess that’s why the OP was about “ambient light level” :slight_smile:

1 Like

I thought I’d bump this topic after recently coming across it in my game development. It’s been a few years, so here’s a formal feature request with some previous replies considered:

Feature Request
As a Roblox developer, it is currently too hard to check light levels and color at a given position.

The only way to do this currently is through estimates, such as what @CloneTrooper1019’s 2015 module (as mentioned in the original post) does. This module checks the hue of light at a given position using cone math and raycasting. This is useful, but the module still has issues and an API method would be a large improvement.

Module Issues
  1. The module is outdated. It was created before FIB implementations, which means it doesn’t work as well with non-legacy lighting (especially shadows).

  2. It’s not as efficient as an internal API method could be. It has to iterate through the entire workspace to find point lights and calculate them. (Restatement from OP)

  3. Like @Defaultio said in the original post, it’s not very accurate. Here are three GIFs that show speific issues with the module, the cube represents the position input into the module and the bar at the bottom represents the result returned by the module:
    e3830bef0f80a82cb3280fcb13d18e05
    ad602f78240c298094bf03bbd5151db4
    916fa989dbcebdd28adc2e9a011776a4
    I believe the first two may be solvable with adjustments to the cone math & color lerping, however it still wouldn’t be as accurate as it could be. I can’t think of an accurate solution to the third shadow issue.

Methods:
Methods such as the proposed below could return info about lighting at a position, and could be easily accessible under a service such as Lighting.

Methods

A method to return the color at a position, returns a Color3.

game:GetService("Lighting"):GetLightHue(Vector3.new())

A method to return the brightness at a position, returns a number between 0 and 1.

game:GetService("Lighting"):GetLightValue(Vector3.new())

Or, the two methods compiled into one, returns a Color3 with both hue and brightness/value:

game:GetService("Lighting"):GetLightColor(Vector3.new())

It’d also be useful to know if the light is affected and/or produced by an artificial source instead of ambient lighting, but I can’t think of a method to do so. Maybe as a second value returned by the above methods?

Why is this useful?

@EchoReaper compiled a list of useful situations in post #4,

  • Having a light turn on when it becomes dark
  • Studio camera light that turns on when you’re in dark caves so you can see what you’re working with
  • Monster night vision that enables when it gets dark
  • Street lamps that come on when the area around them is dark
  • HUD that lights up in the dark (like your car’s dash when your lights turn on when it’s dark)
  • Vampire (or any other monster) damaged by sunlight
  • Spawn monsters in dark places
  • Detect how much a plant should grow based on its light level
  • Magic spells (light & dark) which require there to be a certain light level to cast

Issues
@zeuxcg responded in 2016 (in post #7) that this API could be problematic in the future due to planned implementation of GPU-only lighting calculation. Is there any chance has this changed since the release of shadowmap and FIB?

Any solutions/feedback/uses are all appreciated!

8 Likes

I’ve recently discovered that the game.SoundService has the option to apply reverb to sounds. This would be cool for maybe when players enter caves and stuff.

As a Roblox developer, it is currently too hard to achieve a more immersive sound experience.

My solution is to add a light detection thing for a basepart that detects the light level.

If Roblox is able to address this issue, it would improve my development experience because my game would be a bit neater and a bit more immersive to play. Finally i’d be able to detect when a player is in a dark place and just makes it more reverb ish.

As a Roblox developer, it is currently nearly impossible to find how illuminated a surface is at any point by lights and the sun. I’d like to dynamically change a SurfaceGui’s brightness based on the amount of light hitting it, but currently that is not possible without some heavy calculations. I brainstormed some ways to do this, and eventually came to this: I’d loop through the game’s descendants once, and collect all lights into a table. I’d also do this on DescendantAdded. Then, every frame or so, loop through those and check if the point I’d like to check is within the range of the light, and then raycast to it and determine the illumination based on that. I’d also do this with the sun, and calculate the relative sun direction based on GeographicLatitude and time of day.

Obviously, this is a lot, and there are tons of edge cases to handle. Plus, it’s pretty resource intensive as you could end up casting many lengthy rays in a short period time. And most of all, doing all of this (especially efficiently) would require a moderately advanced skillset so if you are a new developer (which this platform is built around) this is pretty much out of the question.

I’d suggest that there would be a new API in lighting, such as GetIlluminationAtPoint which takes a point and returns a value from 0 to 1; 0 being completely dark and 1 being fully illuminated. Would be happy to answer any more questions if anyone has any. Thank you!

6 Likes