Decal in Godot – Complete Guide

Decals in video game development can take visual details to a whole new level. They are akin to stickers that designers can place over 3D objects within a game, allowing for details like bullet holes, graffiti, or wear and tear to be added without modifying the underlying geometry itself. Embracing decals within your game projects can enrich your environments, make every scene pop with detail, and optimize your game’s performance. As we venture into the world of Godot 4, let’s explore the Decal class — your key to adding these intricate visuals with ease.

What Are Decals?

Decals in the context of game development are overlays that allow textures, such as dirt, signs, scratches, or other details, to be projected onto 3D surfaces. Imagine you’re creating a lived-in urban environment, instead of reworking the fundamental textures of the scene for every scratch and graffiti, you overlay decals to add that layer of detail. This ultimately streamlines the development process and keeps your asset library manageable and efficient.

The Purpose of Using the Decal Class in Godot 4

The purpose of using the Decal class in Godot 4 is primarily to add these visual embellishments without having to alter meshes directly. Decals project textures onto MeshInstance3D and are dynamic in nature, meaning you can move and adjust them in real-time within your game scene. Examples of use cases include:

– Weathering effects on buildings
– Dirt or mud splatters on vehicles and terrains
– Unique patterns and signage on surfaces

Why Learn to Use Decals in Godot 4?

Embracing the Decal class in Godot 4 will significantly uplift your environment design with the following benefits:

– **Visual Diversity**: Increase the variety of visuals in your game without producing new textures for each variation.
– **Performance Efficiency**: Decals are resource-friendly, utilizing texture atlases and clustered rendering optimizations.
– **Dynamic Modifications**: Easily create and manipulate elements like shadows or interactive objects such as laser sights without complex programming.
– **Rendering Compatibility**: Learn to utilize decals within modern forward rendering pipelines, ensuring fidelity on contemporary systems.

Understanding and mastering the use of decals will not only enhance the aesthetic appeal of your games but also offer a practical approach to complex environmental detailing. Let’s dive in and begin our journey with the Decal class, unlocking the potential for breathtaking visual effects within your Godot projects.

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

Creating and Configuring Decal Nodes

Before applying decals, we need a basic understanding of how to create and configure Decal nodes in Godot 4. To start off, here’s how to create a new Decal node geared up for action:

var my_decal = Decal.new()
my_decal.material = preload("res://path_to_your/decal_material.tres")
my_decal.cull_mask = 1
add_child(my_decal)

Once you’ve created and added the Decal node to your scene, you may want to tweak its properties to fit your scenario:

my_decal.normal_fade = 0.5
my_decal.scale = Vector3(2, 2, 2)
my_decal.uv_scale = Vector2(1, 1)

These lines of code adjust the appearance of the decal, scaling it and setting how it fades based on the surface angles to which it is applied.

Manipulating Decal Position and Orientation

To correctly place a decal onto a surface, you will need to manipulate its position and orientation accordingly:

my_decal.global_transform.origin = Vector3(0, 1, 0) # Position
my_decal.global_transform.basis = Basis() # Reset orientation
my_decal.look_at(transform.origin + Vector3(0, 0, 1), Vector3.UP) # Align with surface

The above code positions the decal at a certain point in 3D space and ensures it is facing the right direction based on the normal of the surface we are targeting.

Adjusting Decal Textures and Materials

Customizing your decals further involves tweaking textures and materials. Below is how you can load and assign a diffuse texture to the decal:

var decal_texture = preload("res://path_to_your/diffuse_texture.png")
var decal_material = preload("res://path_to_your/decal_material.tres")
decal_material.set_texture(ShaderMaterial.TEXTURE_ALBEDO, decal_texture)
my_decal.material = decal_material

Dynamic Decal Adjustments at Runtime

In some cases, you might want to adjust decals dynamically during gameplay. This can be achieved by modifying the decal’s properties through code. For instance, to change the emission color dynamically, you could add:

my_decal.material.set("parameters/emission_color", Color(1, 0, 0))

To adjust the decal’s size at runtime, perhaps in response to an in-game event, use:

my_decal.scale = my_decal.scale.linear_interpolate(Vector3(4, 4, 4), 0.1)

This will gradually increase the size of your decal, simulating, for example, the expansion of a stain or the growth of vegetation.

Remember, mastering these basics is essential as they form the foundation of more sophisticated effects and ingame mechanics involving decals. Keep practicing these fundamentals, and you’ll be creating visually stunning and highly interactive game worlds in no time!As we delve further into the intricacies of the Decal class in Godot 4, let’s look at how we can handle different scenarios where decals can add an extra layer of realism and interactivity to our game environments.

Applying Projections to Irregular Surfaces

Decals project textures onto any surface, but adjusting them perfectly on irregular shapes can be tricky. To ensure a decal wraps around such surfaces smoothly, Godot’s Decal node offers the `normal_fade` property. Here’s how you can control it through code:

my_decal.normal_fade = 0.2

With a low `normal_fade`, the decal will blend more seamlessly on complex surfaces, making the projection less dependent on the angle of the surface normal.

Tweaking UVs for Texture Repeats

Sometimes, you might want a single decal to repeat its texture across a larger area. This can be done by adjusting the UV properties:

my_decal.uv_scale = Vector2(5, 5) # Repeat the texture 5 times over both axes

By increasing the `uv_scale`, you repeat the decal’s texture, which is perfect for creating patterns like tiled floors or repeated warnings on industrial equipment.

Creating Temporary Decals

In dynamic game scenarios, such as marking locations where a player has been hit, we might want our decals to fade away after a time. Here is a way to create temporary decals:

var my_decal = Decal.new()
# set up your decal parameters
my_deal.material = preload("res://path_to_your/decal_material.tres") 

# this method will remove the decal after 5 seconds
func _on_Hit():
    add_child(my_decal)
    yield(get_tree().create_timer(5), "timeout")
    remove_child(my_decal)

This code snippet adds the decal on a hit event and uses Godot’s coroutine-like functionality with `yield` to wait for 5 seconds before removing the decal.

Blending Decals with Environment

To make decals look as if they are naturally part of the environment, blending is key. Here’s how you set the decal material’s blend mode:

my_decal.material.set("parameters/blend_mode", DecalMaterial.BLEND_MODE_MIX)

There are several blend modes available, like `BLEND_MODE_MIX`, `BLEND_MODE_ADD`, `BLEND_MODE_SUB`, etc., allowing for various visual effects.

Handling Decal Occlusion

In more intricate scenes, you may want decals hidden behind objects to not be visible. Godot deals with this through the culling process:

my_decal.cull_mask = 1 # This decal will only be visible on layers included in cull_mask

Setting up the `cull_mask` ensures that a decal only projects onto surfaces that are part of the defined layers, controlling the visibility as required by the game design.

Interaction with Lighting

Dynamic lighting can significantly impact the appearance of decals, making them integrate seamlessly into the scene or stand out as light hits them. To modify a decal’s emission strength based on the surrounding light:

func _process(delta):
    var light_strength = calculate_light_strength() # custom function
    my_decal.material.set("parameters/emission_strength", light_strength)

The `calculate_light_strength` function would be a custom function you create to determine current lighting conditions and adjust the decal emission strength accordingly.

By implementing these code examples, you can begin to see the depth of Godot’s Decal class, allowing a game designer to create more immersive environments with functionality that uplifts both aesthetics and gameplay. Keep experimenting with different properties and their possible runtime adjustments, and you’ll soon harness the full potential of using decals in Godot 4.Decals are best utilized when combined with Godot’s shader capabilities. This gives us even more control over how they interact with the game environment, specifically with lighting and player actions. Let’s enhance our decal usage with shader code and Godot script examples.

Using Shaders with Decals

Shaders provide a powerful way to control the appearance of decals dynamically. In the example below, we can adjust how a decal reacts to light in the scene using a shader.

shader_type spatial;
render_mode unshaded;

void fragment() {
    ALBEDO = texture(SCREEN_TEXTURE, SCREEN_UV).rgb;
}

Here, a simple shader is applied to the decal, which ignores the scene’s lighting (`render_mode unshaded`) and uses the screen’s texture directly. This can create effects like glow-in-the-dark stickers or electronic screens that don’t reflect environmental light.

Creating Animated Decals

Animated decals can add dynamic elements to any surface, such as a flickering neon sign or a screen displaying changing images.

shader_type spatial;
uniform sampler2D frames[4];
uniform float frame;

void fragment() {
    ALBEDO = texture(frames[int(mod(frame + TIME, 4))], UV).rgb;
}

This shader cycles through an array of textures over time to create an animation effect. The `frame` uniform can be modified via GDScript to control the animation speed or sequence.

Applying Decals with Collision

We can use decals interactively; for instance, after a gunshot, a bullet hole decal can be applied precisely where the collision happens.

func _shoot_ray():
    var space_state = get_world().direct_space_state
    var ray_origin = camera.global_transform.origin
    var ray_end = ray_origin + camera.global_transform.basis.z * max_ray_distance
    var result = space_state.intersect_ray(ray_origin, ray_end, collision_mask)
    
    if result:
        var bullet_decal = Decal.new()
        bullet_decal.material = preload("res://bullet_hole.tres")
        bullet_decal.global_transform.origin = result.position
        bullet_decal.look_at(result.position + result.normal, Vector3.UP)
        add_child(bullet_decal)

In this example, an `intersect_ray` function determines the collision point and normal, and a new decal is placed at that position, facing the correct direction.

Blending Decals with Transitions

Smooth transitions are often essential for realistic effects, such as a decal appearing over time as paint being sprayed. We can animate the blend factor of a decal material to achieve this:

func _on_spray_paint(position):
    var paint_spray = Decal.new()
    paint_spray.material = preload("res://spray_paint.tres")
    paint_spray.global_transform.origin = position
    # Assume 'sprite' is already a part of the scene.
    add_child(paint_spray)
    var tween = Tween.new()
    add_child(tween)
    tween.interpolate_property(paint_spray.material, "parameters/blend_width",
                                0.0, 1.0, 1.0,
                                Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
    tween.start()

In this GDScript example, a Tween node is used to animate the `blend_width` property of the decal material from 0 to 1 over one second, simulating the effect of paint appearing on a surface.

Adjusting Decal with User Input

To let players interact with decals, such as scratching off a lottery ticket in-game, we can use player input to control the UVs or other material properties.

func _input(event):
    if event is InputEventMouseMotion and event.button_mask & InputEvent.BUTTON_MASK_LEFT:
        var mouse_uv = get_mouse_uv_from_position(event.position)
        var decal_to_scratch = get_decal_at_uv(mouse_uv)
        if decal_to_scratch:
            decal_to_scratch.adjust_uv(mouse_uv)

This script takes mouse movement with a button pressed to adjust the UVs or other properties of a selected decal based on custom `get_mouse_uv_from_position` and `get_decal_at_uv` functionalities.

Leveraging Godot 4’s Decal class combined with shader programming and scripting allows for deeply immersive and customizable environments. Be sure to experiment with these examples and concepts to push the boundaries of what’s possible with decals in your own games!

Continue Your Game Development Journey

Now that you’ve dipped your toes into the world of decals with Godot 4 and seen the potential they hold to amplify your game environments, the journey doesn’t end here. To keep honing your skills and expanding your game development toolkit, Zenva Academy invites you to explore our Godot Game Development Mini-Degree. This curriculum is designed to guide you through the many facets of game creation, covering essential topics like 2D and 3D assets, gameplay control flow, and UI systems.

We provide you with the flexibility to learn at your own pace with our project-based courses, accessible 24/7, so you can continue to balance your learning with your personal schedule. Suitable for both beginners and veterans, our Godot courses (available here) will ensure you are well-equipped to tackle the challenges of game development and turn your visions into playable realities.

So, keep learning, keep experimenting, and keep building. The world of game development is vast and full of possibilities, and Zenva Academy is here to support you on every step of your game development voyage. Let’s create something amazing together.

Conclusion

Our adventure into the realm of Godot 4 and its Decal class has just scratched the surface of what’s possible when you pair creativity with powerful tools. Whether you’re aiming to add subtle details or eye-catching visual effects to your games, understanding how to effectively implement decals is a game-changer. With Zenva Academy’s comprehensive Godot Game Development Mini-Degree, you can continue to build on this foundation and unlock new dimensions of game creation.

Embrace the opportunity to deepen your skill set, challenge your creative limits, and join a community of like-minded developers. With each tutorial, each line of code, and each completed project, you’re not just developing games—you’re crafting experiences that capture imaginations. So, what are you waiting for? Let’s bring your game development dreams to life with Zenva Academy, where every course is a step towards mastering the art of game creation.

FREE COURSES
Python Blog Image

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