LightmapProbe in Godot – Complete Guide

Welcome to our deep dive into the world of dynamic object lighting in Godot 4 using the LightmapProbe class! If you’ve been curious about how to add that extra touch of realism to your game environments, you’re in the right place. LightmapProbes can significantly enhance the lighting of dynamic objects, making your scenes come alive with depth and detail. Whether you’re just starting out or you’re an experienced developer looking to fine-tune your skills, this tutorial is designed to be accessible, informative, and engaging. So let’s illuminate your Godot knowledge, one probe at a time!

What is the LightmapProbe?

In the vibrant world of 3D game development, lighting can make or break the player’s experience. LightmapProbe is a feature in Godot 4 that allows creators to place manual probes within the game scene to influence the lighting of dynamic objects using the LightmapGI system. This node marks the specific spots in your scene where you want to capture lighting information, making it essential for crafting a visually stunning game.

What is it for?

Think of a LightmapProbe as your personal lighting assistant, standing by to cast the perfect glow on dynamic objects such as characters or movable decor. Its main purpose is to take your game’s lighting from good to great by ensuring that these objects receive and react to light as naturally as possible, mimicking real-world lighting conditions. This refinement adds depth, realism, and a touch of magic to your game’s environment.

Why Should I Learn About LightmapProbe?

Understanding how to use LightmapProbe is a game-changer for any Godot developer. Efficiently placed probes can breathe life into your scenes, creating dynamic and responsive lighting that adapts to your game’s environment. By mastering LightmapProbe, you’ll have the ability to:

  • Enhance visual quality by improving the lighting of dynamic objects in your scenes.
  • Control lighting detail in specific areas, sculpting the player’s experience and guiding their attention.
  • Optimize your game’s performance by strategically placing probes where they’re needed most, without overburdening the system with unnecessary calculations.

With these compelling reasons, learning about LightmapProbe is a step towards realizing your vision for a truly immersive game world. So let’s switch on the lights and get started!

CTA Small Image
FREE COURSES AT ZENVA
LEARN GAME DEVELOPMENT, PYTHON AND MORE
ACCESS FOR FREE
AVAILABLE FOR A LIMITED TIME ONLY

Setting Up Your Godot Environment

Before we dive into the code examples, ensure that your Godot environment is set up for 3D game development. You should have Godot 4.0 installed and a new 3D project ready to go. Once you’re set up, let’s start by creating a basic scene.

var scene = PackedScene.new()
var root_node = Spatial.new()
scene.pack(root_node)

Add a MeshInstance to serve as a simple ground:

var ground = MeshInstance.new()
ground.mesh = PlaneMesh.new()
ground.mesh.size = Vector2(10, 10)
ground.mesh.material = SpatialMaterial.new()
root_node.add_child(ground)

With the above code, we’ve created a scene with a flat ground. Now, let’s set up a basic light source:

var light = DirectionalLight.new()
root_node.add_child(light)

Introducing LightmapProbe to the Scene

Now that the basic elements are in place, we can add a LightmapProbe. Start by creating the probe and adding it to the root node:

var light_probe = LightmapProbe.new()
root_node.add_child(light_probe)

The LightmapProbe needs to be properly positioned and sized in your scene. Here’s an example of setting the probe’s extents:

light_probe.extents = Vector3(5, 5, 5)  // This vector should encapsulate the area you want to affect.

For the LightmapProbe to be effective, you must bake the lightmap. Start by creating a GIProbeData resource and assigning it to the probe:

var gi_probe_data = GIProbeData.new()
light_probe.data = gi_probe_data

Then, bake the lightmap by calling:

light_probe.bake(root_node, true)

Configuring LightmapProbe Properties

There are several properties of the LightmapProbe that you can configure to better fit your scene’s requirements. For instance, you might want to adjust the energy and dynamic ranges:

light_probe.energy = 1.5
light_probe.dynamic_range = 4  // Higher values allow for a greater range of light intensities.

To make the light probe capture more accurate lighting information:

light_probe.subdiv = 128  // Adjust subdivision for more granular light capture, mindful of performance implications.

Positioning and Optimizing LightmapProbes

Positioning LightmapProbes strategically throughout your scene is essential for optimum lighting effects. You might often have multiple probes, each with its location and size tailored to specific areas:

// This is how you might set up multiple probes for different areas
var probe1 = LightmapProbe.new()
probe1.extents = Vector3(2, 2, 2)
probe1.transform = Transform(Basis(), Vector3(0, 1, 0))
root_node.add_child(probe1)

var probe2 = LightmapProbe.new()
probe2.extents = Vector3(3, 3, 3)
probe2.transform = Transform(Basis(), Vector3(5, 1, 0))
root_node.add_child(probe2)

// Remember to bake each probe
probe1.bake(root_node, true)
probe2.bake(root_node, true)

Your LightmapProbes should cover areas that are most affected by dynamic objects. Optimize by reducing the subdivision in less critical areas:

probe2.subdiv = 64  // Use lower subdivisions for areas where detail is less important.

In the next part of our tutorial, we’ll expand on how to dynamically interact with LightmapProbes at runtime and adjust their properties based on game events, creating an even more immersive experience for the player. Stay tuned for more hands-on examples that will further illuminate your Godot expertise!

Great, you’re now familiar with setting up and positioning LightmapProbes. Let’s explore how to interact with these probes at runtime to respond to game events and dynamically adjust the lighting. These runtime interactions can help create a more dynamic and responsive game environment.

One simple interaction is to change the energy property of a LightmapProbe to simulate a light dimming effect:

// Assuming 'probe' is a reference to an existing LightmapProbe
probe.energy -= 0.1 if probe.energy > 0 else 0

In games, you often want environmental changes to reflect in-game events. For example, here’s how you might adjust the probe’s interior_ambient color when a player activates a special object:

// Trigger this when the player activates the object
probe.interior_ambient_color = Color(0.8, 0.5, 0.3)  // A warm, ambient glow

Increasing and decreasing the dynamic_range can be used to simulate sudden changes in light intensity, such as an explosion:

// Simulate an explosion effect by changing the dynamic range
var start_range = probe.dynamic_range
probe.dynamic_range = 10  // Beginning of the explosion
yield(get_tree().create_timer(0.5), "timeout")  // Wait for 0.5 seconds
probe.dynamic_range = start_range  // Restore the original dynamic range

Another scenario might involve moving a probe to follow a dynamic light source, like a character’s torch:

// This could be run in a process function or called when the character moves
probe.global_transform.origin = character.global_transform.origin

If you have multiple LightmapProbes in a scene, you can selectively enable or disable them based on player location or scene changes to optimize performance:

// Enable or disable a probe based on the player's proximity
var player_distance = player.global_transform.origin.distance_to(probe.global_transform.origin)
probe.enabled = player_distance < 10  // Enable only if the player is within 10 units

In scenarios where lighting needs to change over time, for example, to simulate a day-night cycle, you might want to interpolate between different colors:

// Gradually change the ambient light color to simulate dusk
var start_color = probe.interior_ambient_color
var end_color = Color(0.1, 0.1, 0.5)  // Dusk color
var elapsed_time = 0.0
var total_time = 10.0  // Transition over 10 seconds

while elapsed_time < total_time:
    elapsed_time += get_process_delta_time()
    var t = elapsed_time / total_time
    probe.interior_ambient_color = start_color.linear_interpolate(end_color, t)
    yield(get_tree().idle_frame, "idle_frame")  // Wait until next frame to continue

Finally, you might want to dynamically adjust the extents of a LightmapProbe during runtime. Here’s an example where we change the extents based on a gameplay mechanic, like a magical field growing:

// Assume 'field_extent' is a Vector3 that grows based on some game logic
probe.extents = probe.extents.linear_interpolate(field_extent, 0.1)

These are just a few examples of how you can use LightmapProbe properties to create a dynamic lighting system within your Godot 4 game. By experimenting with and understanding these properties, you can create vivid and memorable experiences that resonate with players. The key is to find the right balance that serves both the aesthetic of your game and its performance. Happy developing!

Let’s further evolve our nighttime effect by simulating how objects might cast longer and more pronounced shadows as evening approaches:

// Adjust the 'direction' of the sun's light to lower angles
var sun_light = DirectionalLight.new()
var sunset_angle = Vector3(deg2rad(15), 0, 0)  // Sun sets to 15 degrees
var tween = Tween.new()
add_child(tween)
tween.interpolate_method(sun_light, "set_rotation_degrees", sun_light.rotation_degrees, sunset_angle, 5, Tween.TRANS_LINEAR, Tween.EASE_IN)
tween.start()

Notice that this code snippet uses a Tween to smoothly transition the rotation angle of the sun, which represents our directional light, over time.

Next, consider the ambient light changing as night falls. To tweak these properties, the code below incrementally darkens the ambient light’s color using Godot’s Color methods:

// Dimming ambient light to simulate evening time
var ambient_light = WorldEnvironment.new()
var ambient_twilight_color = Color(0.1, 0.1, 0.2)
ambient_light.environment.ambient_light_color = ambient_light.environment.ambient_light_color.darkened(0.01)
if ambient_light.environment.ambient_light_color.brighter_than(ambient_twilight_color):
    yield(get_tree().create_timer(0.2), "timeout")  // Change every 0.2 seconds
else:
    ambient_light.environment.ambient_light_color = ambient_twilight_color

Here we’re also using a timer to regularly darken the ambient light until it reaches the twilight color.

Creating a flickering light effect can add tension or intrigue to a scene. Here’s how we might script a flickering torchlight using the Emission property and randomization:

// Assuming 'torch' is a SpatialMaterial already set up on a MeshInstance
while true:
    var flicker_intensity = rand_range(0.5, 2.0)
    torch.emission_energy = flicker_intensity
    yield(get_tree().idle_frame, "idle_frame")  // Flicker effect in each frame

Animated lighting is yet another way to bring life to our scenes, like simulating moving water reflections or a swinging overhead light:

// Animate a spotlight to swing back and forth
var spotlight = SpotLight.new()
var start_rotation = Vector3(0, 0, 0)  // Start aligned to the global axis
var end_rotation = Vector3(0, deg2rad(30), 0)  // 30 degrees rotation on the Y axis
tween.interpolate_method(spotlight, "set_rotation", start_rotation, end_rotation, 2, Tween.TRANS_SINE, Tween.EASE_IN_OUT)
tween.start()

The Tween node is again used for smooth interpolation of the rotation property, creating a swinging motion that dynamically changes the spotlight’s direction.

Finally, the intensity and range of a light source might be tied to player actions or in-game mechanics, such as powering up a machine or activating an ancient artifact:

// Powering up a light source upon player interaction
func power_up_light(machine_light, max_energy, increment, duration):
    var elapsed_time = 0.0
    while elapsed_time  max_energy:
            machine_light.light_energy = max_energy 
            break
        elapsed_time += get_process_delta_time()
        yield(get_tree().idle_frame, "idle_frame")

In this case, a function power_up_light is created that can be called with parameters specifying the light to be powered, the maximum energy level, how much to increment the energy on each step, and how long the power-up process should last.

These examples demonstrate a range of dynamic lighting changes and the code required to achieve them in Godot 4. By incorporating these techniques, you will be able to create more diverse and engaging environments. Play around with different lighting conditions in your game to discover exciting new possibilities and create the atmosphere that best fits your game’s theme.

Continue Your Game Development Journey

We hope this tutorial has ignited your passion for creating dynamic and immersive game environments in Godot 4. There’s a whole universe of possibilities waiting for you to explore and master. To keep expanding your knowledge and skills, we invite you to check out our Godot Game Development Mini-Degree. This comprehensive program will take you from the basics to the more advanced aspects of game creation using the powerful Godot 4 engine.

Whether you’re a beginner looking to get started or an experienced developer aiming to brush up on the latest features, our Mini-Degree has got you covered. You’ll learn about game development using 2D and 3D assets, craft intricate gameplay control flows, and even delve into creating various game mechanics for different genres. The beauty of learning with us is the flexibility to access our courses any time and progress at your own pace, with project-based content that keeps you engaged and building real-world skills.

If you’re eager to broaden your scope even further, explore our full range of Godot courses. With this diverse selection, you can dive deeper into specific areas or add new techniques to your development repertoire. At Zenva, our goal is to equip you with the knowledge that can help turn your game development dreams into reality. So why wait? Continue your journey with us and level up your game development skills today!

Conclusion

Lighting is a crucial ingredient in the recipe for an engaging and immersive game world. By following this tutorial, you’ve learned how to use the LightmapProbe class in Godot 4 to enhance the realism of your dynamic objects with advanced lighting techniques. Remember, the skills you acquire here are just the beginning. With each new feature you master, your ability to create compelling and visually stunning games grows exponentially.

Don’t stop here—take what you’ve learned and build upon it with our Godot Game Development Mini-Degree. This is your opportunity to harness the full potential of Godot 4 and bring your most imaginative game ideas to life. Progress through carefully crafted lessons, gain confidence in your development abilities, and become part of the thriving community of creators who share your passion for making games. The world is waiting to play what you create, so join us at Zenva, and let’s make game development dreams come true together.

FREE COURSES
Python Blog Image

FINAL DAYS: Unlock coding courses in Unity, Godot, Unreal, Python and more.