Light Sensor 3D

by nanodeath

11

Godot Light Sensor 3D

Do you need to find the total amount of light reaching a point in your Godot 4 3D project? Then you've come to the right place.

This asset contains a "light sensor" -- a tiny camera pointing at a tiny white plane that can be queried to determine how much light is reaching that plane. You can check the color, too, if you care about that.

Demo scene

How to Use

  1. Create a new node of type LightSensor3D.
  2. Move it to the point you want to measure light.
  3. Configure the layer.
  4. Call the refresh() method on it periodically, e.g. every second.
  5. Query it using the available properties, functions, and signals.

Positioning and Orientation

The sensor is not a single point in space, capable of reading detecting light in a sphere. It's a plane, which means a couple things:

  1. It's recommended to place the sensor low to the ground of your game.
  2. It's recommended to orient the sensor so the sensor is pointing "downwards" (this is the default).

These suggestions are assuming you're measuring the amount of light some point on the ground is receiving.

Configuring the Layer

The internal sensor mesh uses the layer you configure on the light sensor itself. You'll want to choose layer(s) based on the following principles:

  1. The layer shouldn't be visible to your main camera, otherwise you'll see a small white plane near the center of the sensor.
  2. The layer should be visible to the lights you want to register on the light sensor, otherwise you won't get the desired readings.

Calling the refresh() Method

Refreshing the sensor's state is pretty expensive, since it requires downloading data from the GPU back to the CPU (see Texture2D#get_image). In my tests, it takes on the order of 0.2ms, which is potentially a big chunk of the frame budget if you have multiple sensors updating every frame. Therefore, it's recommended to only update as often as you need -- once every 250ms or even less often.

Calling refresh() is left up to you. The easiest way to do this is to add a child node of the LightSensor3D of type Timer that:

  • has a wait time of 1 second, or whatever your update frequency need is.
  • does not have one-shot enabled.
  • does have autostart enabled.
  • and lastly and most importantly, triggers the parent node's refresh() method in the timeout signal.

There's an included example scene that does this that you can also check out.

Sanity Check

Things not quite working?

Check:

  1. that your light source is on the correct layer(s) and shadows are enabled. Layers are in the VisualInstance3D subsection, and shadows under Light3D > Shadow.
  2. that your shadow-casting meshes (e.g. MeshInstance3D) are on the expected layer, configured under VisualInstance3D again.
  3. that your LightSensor3D is targeting the layer that's casting light/receiving shadows configured above.

Outputs

name type description
property color Color This is the current color the sensor is seeing.
property light_level float This is the luminance seen by the sensor. 0=dark, 1=bright.
signal color_updated (color: Color) Emitted when the current color changes.
signal light_level_updated (luminance: float) Emitted when the light level changes.
Note that all of these require you to call refresh() before they'll be updated and triggered.

Version

1.0.0

Engine

4.2

Category

3D Tools

Download

Version1.0.0
Download

Support

If you need help or have questions about this plugin, please contact the author.

Contact Author