DirectionalLight3D in Godot – Complete Guide

When embarking on the journey of game development, mastering the use of lighting can take your game from looking flat and unpolished to a visually stunning experience. In the vibrant world of 3D rendering, one light that plays a pivotal role is the DirectionalLight3D in Godot 4. It can make or break the immersive atmosphere you’re trying to create. In this tutorial, we will dive deep into the DirectionalLight3D class and explore its capabilities and functionalities.

What is DirectionalLight3D?

// Creating a DirectionalLight3D node in Godot 4
var light = DirectionalLight3D.new()
add_child(light)

A DirectionalLight3D in Godot 4 is akin to having your very own virtual sun or moon that casts parallel rays of light across the entire scene. This kind of light is particularly adept at simulating natural, outdoor lighting where the source, like the sun, is effectively at an infinite distance from the objects it illuminates.

The Purpose of DirectionalLight3D in Godot 4

Why would you use a DirectionalLight3D instead of other types of light? It’s all about scope and performance:

– Models an infinite number of parallel rays covering the scene.
– Perfect for capturing the essence of sunlight or moonlight.
– Offers a balancing act between quality and performance for large-scale environments.

Why Should You Learn About DirectionalLight3D?

Understanding DirectionalLight3D is cornerstone knowledge for any budding or seasoned game developer:

– **Highly Relevant Skill**: Lighting is fundamental in 3D game development; without proper lighting, even the most beautifully designed game can fail to impress.

– **Unique Visual Effects**: Learn how to simulate different times of day, weather conditions, and even manipulate the mood and atmosphere of your game scenes.

– **Performance Optimization**: Different settings and modes of the DirectionalLight3D can drastically improve the performance of your game without compromising on its visual quality.

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

Configuring a DirectionalLight3D Node

Once you’ve added a DirectionalLight3D to your scene, the next step is to configure its properties to achieve the desired effect. Here’s how you can control the direction of the light:

// Adjusting the rotation to point the light downward
light.rotation_degrees = Vector3(50, 30, 0)

Not only can you adjust the rotation, but you can also experiment with color and intensity:

// Giving the light a warm, sunset hue
light.color = Color(1, 0.5, 0.3)
// Setting the intensity of the light
light.energy = 0.8

The DirectionalLight3D node has a parameter called ‘shadow_enabled’ that allows you to enable or disable shadows:

// Enabling shadows for the directional light
light.shadow_enabled = true

To further fine-tune the shadows, you can adjust the shadow parameters for quality and performance:

// Increasing shadow detail
light.shadow_normal_bias = 1.1
light.shadow_contact = 0.03
light.shadow_reverse_cull_face = true

Casting Shadows with DirectionalLight3D

Shadows add depth and realism to the scene. Here’s how we adjust the DirectionalLight3D to create crisp, realistic shadows:

// Creating sharper shadows
light.shadow_max_distance = 100
light.directional_shadow_mode = DirectionalLight3D.SHADOW_ORTHOGONAL

As performance is key, especially in large scenes, balancing shadow detail and processing requirements is crucial:

// Adjusting shadow split parameters for performance
light.shadow_split_1 = 0.05
light.shadow_split_2 = 0.1
light.shadow_split_3 = 0.5

Dynamic Lighting Effects

Dynamic lighting can bring your scenes to life. Here’s a simple script that can simulate a day-night cycle with DirectionalLight3D:

// Attach this script to the DirectionalLight3D node
extends DirectionalLight3D

func _process(delta):
    rotation_degrees.x += 10 * delta
    if rotation_degrees.x > 360:
        rotation_degrees.x = 0

For even more control, we can change not only the rotation but also the color of the light to represent different times of day:

// Changing light color over time can simulate sunrise or sunset
if rotation_degrees.x < 180:
    color = Color(1, 0.5, 0.3)  # Sunset
else:
    color = Color(0.3, 0.4, 1)  # Night

Integrating with Environment for Atmospheric Effects

A DirectionalLight3D can dramatically affect the environment node’s tonemap and sky. Adjust the following settings for a striking atmosphere:

// Setting environment properties to complement directional light
var environment = WorldEnvironment.new()
environment.environment.tonemap_mode = Environment.TONE_MAPPER_ACES
environment.environment.bg_mode = Environment.BG_SKY
add_child(environment)

By changing the sky’s parameters, we can create a more cohesive lighting and environmental design:

// Adjusting the sky properties
environment.environment.sky_rotation_degrees = Vector3(0, 0, 0)
environment.environment.sky_custom_fov = 65
environment.environment.sky_orientation = Environment.SKY_ORIENTATION_DISABLED

In the next part of our tutorial, we will delve into more advanced usage examples, such as making the light dynamically interact with game objects and scripting user interactions to change lighting conditions on the fly. Stay tuned to expand your understanding of Godot’s lighting capabilities!Dynamic interaction of lights with game objects adds another layer of realism to your scenes. Let’s explore how to use signals and scripting to react to in-game events with lighting changes.

Responding to Game Events with Light Changes

Imagine you want your DirectionalLight3D to change intensity based on certain events, like a player entering a specific zone. Here’s how you can set that up:

// In the area's script
signal player_entered

func _on_Area_body_entered(body):
    if body.name == "Player":
        emit_signal("player_entered")

In your light node script, you would then connect to this signal and adjust the light accordingly:

// In the DirectionalLight3D script
func _ready():
    var area = get_node("Area")
    area.connect("player_entered", self, "_on_player_entered")

func _on_player_entered():
    energy = 2.0  // Brighten the light

Now, let’s implement a lighting effect that gives the impression of a cloud passing over the sun:

// Creating a cloud cover effect
func _process(delta):
    var time = OS.get_ticks_msec() / 1000.0
    energy = 1.0 + 0.3 * sin(time * 0.5)

Creating a Flickering Light Effect

Flickering lights can be used to create an eerie or unsettling atmosphere. Here’s how you could implement such an effect:

// Simulating a flickering light
func _process(delta):
    energy = rand_range(0.9, 1.1)  // Randomly adjust light intensity

Animating Light Color and Intensity

To animate lights in a more controlled fashion, you can use Tweens for smooth transitions between states. Here’s an example of transitioning from day to night:

// Attach a Tween node to the DirectionalLight3D node
// Then use the following code in your DirectionalLight3D script
var tween = get_node("Tween")
tween.interpolate_property(self, "color",
    Color(1, 0.5, 0.3), Color(0.1, 0.1, 0.5), 5,
    Tween.TRANS_QUAD, Tween.EASE_IN_OUT)

tween.start()

For a more complex animation, you can queue color and rotation changes to simulate a full day-night cycle:

tween.interpolate_property(self, "color",
    Color(1, 0.7, 0.4), Color(0, 0, 0.3), 10,
    Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
tween.interpolate_property(self, "rotation_degrees",
    Vector3(50, 30, 0), Vector3(-50, 30, 0), 10,
    Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
tween.start()

Interacting with the Player’s Actions

Lighting can also dynamically respond to the player’s actions. Consider a scenario in which using an in-game item alters the environmental light. Here’s how you could script that interaction:

// In the light or player script
func use_lantern():
    if has_node("DirectionalLight3D"):
        var directional_light = get_node("DirectionalLight3D")
        directional_light.color = Color(1, 0.9, 0.6)  // Warm lantern light
        directional_light.energy = 0.5                 // Dimmer than sunlight

This setup helps create a connection between the player’s inventory and the world’s illumination, making for an interactive and immersive gaming experience.

When it comes to lighting in Godot 4, the possibilities are extensive. Using simple scripts and node properties accurately can have a profound impact on the aesthetics and ambience of your game. Remember, it’s not just about making your game look pretty — illumination can tell a story, guide the player, and even affect gameplay mechanics. As we continue to explore the depth of Godot’s lighting system, always consider how these techniques can serve the game you are building, and have fun experimenting!Continuing our deep-dive into lighting with Godot 4, let’s introduce advanced techniques to further enhance the dynamics of your game’s visual experience.

One often-overlooked feature is the power of light to not only illuminate but also to cast dynamic shadows that add realism to your game world. Here’s how you can dynamically adjust the shadow properties in response to environmental changes:

// Dynamically changing shadow detail based on game conditions
func adjust_shadow_detail(high_detail : bool):
    if high_detail:
        shadow_max_distance = 500
        shadow_detail = DirectionalLight3D.SHADOW_DETAIL_HIGH
    else:
        shadow_max_distance = 200
        shadow_detail = DirectionalLight3D.SHADOW_DETAIL_MEDIUM

Keeping the gamer’s experience fresh with varying lighting is crucial. To set up a system where the lighting changes according to the player’s health, consider the following script:

// Connect to player's health_changed signal
func _ready():
    var player = get_node("Player")
    player.connect("health_changed", self, "_on_player_health_changed")

func _on_player_health_changed(health : float):
    color = Color(1, health, health)  // Redden the light as health decreases
    energy = health  // Dim the light as health decreases

Now, let’s introduce a scenario where the DirectionalLight3D color and intensity adjust according to the time the player has survived in the game:

// Light adjusts according to player's survival time
func _process(delta):
    var survival_time = get_node("Player").survival_time
    color = Color(1, 1, 1).linear_interpolate(Color(0.3, 0.1, 0.1), survival_time / 60.0)
    energy = 1.0 - 0.5 * (survival_time / 60.0)

Interactivity can also extend to natural phenomena. Let’s make the light react to a magical in-game event such as the player casting a spell:

// Player script
signal spell_cast

func cast_spell():
    emit_signal("spell_cast")

// DirectionalLight3D script
func _ready():
    var player = get_node("Player")
    player.connect("spell_cast", self, "_on_spell_cast")

func _on_spell_cast():
    tween.interpolate_property(self, "color",
        color, Color(0.4, 0.1, 0.6), 1,
        Tween.TRANS_SINE, Tween.EASE_IN_OUT)
    tween.start()

Let’s also look at how lighting can influence not only the visual aspect but also gameplay. We can script the DirectionalLight3D to signal when it’s too dark for the player to see:

// Script attached to DirectionalLight3D
signal too_dark_to_see

func _process(delta):
    if energy < 0.3:
        emit_signal("too_dark_to_see")

Finally, let’s add some complexity by making the light not only dynamic but also by giving the player control over it:

// Script attached to the player
func toggle_headlamp():
    var headlamp = get_node("DirectionalLight3D")
    headlamp.shadow_enabled = !headlamp.shadow_enabled
    if headlamp.shadow_enabled:
        headlamp.color = Color(1, 1, 1)
        headlamp.energy = 0.7
    else:
        headlamp.color = Color(0.3, 0.3, 1)
        headlamp.energy = 0.3

All these scripts showcase the flexibility and dynamism of the DirectionalLight3D in Godot 4, enhancing the gameplay experience. Lighting isn’t just about what the player sees but how they interact with and perceive the game world. Whether it’s the gloomy depths of a cave or the vibrant hills on a sunny day, lighting sets the stage for every in-game action, ensuring a memorable and engaging experience for the player. As you continue to explore Godot’s rich lighting system, consider how each parameter you adjust contributes to the narrative and feel of your game.

Continuing Your Game Development Journey with Godot 4

Your exploration of Godot 4 and its robust lighting system doesn’t have to end here. To take your skills to even greater heights, we invite you to join our Godot Game Development Mini-Degree. This comprehensive curriculum will empower you with deeper knowledge across a variety of game development areas, from mastering the use of assets and the GDScript programming language to implementing engaging gameplay control flows and dynamic combat mechanics.

Whether you are just starting out or looking to refine your expertise, this mini-degree is designed to accommodate your learning pace, offering the flexibility to dive into lessons anytime and anywhere. Plus, for an even broader collection of resources, our range of Godot courses caters to various interests and skill levels. At Zenva, we’re dedicated to providing high-quality content that suits your learning journey. With our Godot Game Development Mini-Degree, create compelling games and build a portfolio that will bring you success in the game development industry.

Conclusion

As we’ve illuminated the path to mastering DirectionalLight3D in Godot 4, remember that lighting is more than a visual tool—it’s a storytelling device that can evoke emotions and guide your players through unforgettable experiences. The art of game development is an ever-evolving craft, and with Godot 4’s powerful features at your fingertips, there’s no limit to the immersive worlds you can create. Your adventure as a game developer is ongoing, and we’re here to support every step of your learning odyssey.

Ready to bring your luminous visions to life? Embark on a journey with our Godot Game Development Mini-Degree and let your creativity shine. Unlock the full potential of your game development prowess, and take pride in the dazzling experiences you craft for players around the world. Together, let’s light up the gaming universe—one pixel at a time!

FREE COURSES
Python Blog Image

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