Texture in Godot – Complete Guide

Textures are like the digital paint for our 3D models and 2D sprites, giving life and detail to simple shapes and forms within games and simulations. As we dive into the pixel-rich world of Godot 4, we will discover the power of the Texture class—a foundational element in creating visually stunning and high-performance gaming experiences. The journey through Godot’s texturing capabilities will not only enhance your game’s aesthetics but also strengthen your understanding of applied texture techniques. Whether you are at the start of your game development adventure or an experienced developer looking to brush up on the latest Godot 4 features, mastering textures will significantly impact the quality and feel of your projects.

What is the Texture Class?

The Texture class in Godot 4 serves as the core for all texture resources within the engine. But what exactly is a texture? In essence, it’s a bitmap image applied to the surface of a 3D model or 2D graphic, creating additional detail, color, and realism. In technical terms, textures are data containers that hold the information necessary for rendering graphics with different appearances and properties, such as diffuse color, transparency, and reflectivity.

What is it for?

Textures breathe life into virtual environments and characters. Imagine a world without textures—3D shapes would appear flat, monochromatic, and uninviting. Textures are used for a myriad of purposes in game development:

– Creating visual complexity without adding geometric detail
– Enhancing performance by simulating high-resolution data
– Establishing mood and atmosphere within game worlds

Why Should I Learn It?

Learning about textures is more than just a foray into the artistic side of game development; it’s a deep dive into an area where art meets technology. Textures can affect game performance, drive storytelling, and create immersive environments that keep players engaged. A solid grasp of how to use the Texture class effectively in Godot 4 enables you to:

– Elevate your game’s visual quality
– Optimize graphics for better performance
– Innovate with creative visual effects
– Understand the intricacies of game art in a hands-on way

Given their significance in the gaming industry, knowing how to work with textures will be an invaluable skill as you craft your own unique game experiences.

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

Loading and Displaying a Texture

Let’s begin by loading a texture into our Godot project and displaying it within a 2D scene. The process is straightforward and serves as the foundation for more complex texture operations.

First, we load the texture into a variable:

var my_texture = preload("res://path/to/your/texture.png")

Next, we create a Sprite node and assign the loaded texture to it:

var sprite = Sprite.new()
sprite.texture = my_texture
add_child(sprite)

The above code snippet can be placed in the _ready() function of a Node script to ensure it executes once the node is ready in the scene.

Manipulating Texture Properties

Textures in Godot have properties that can be manipulated to alter their appearance. Let’s look at how to modify a texture’s flip and repeat properties:

You can flip the texture horizontally or vertically using the flip_h and flip_v properties of the Sprite node:

sprite.flip_h = true
sprite.flip_v = true

To make a texture repeat (tile) across a surface, you’ll often use it on a TextureRect node for UI elements, or materials in 3D:

var texture_rect = TextureRect.new()
texture_rect.texture = my_texture
texture_rect.rect_min_size = Vector2(400, 400) # Set the min size to see the tiling effect
texture_rect.texture_flags = Texture.FLAG_REPEAT # Enable repeating
add_child(texture_rect)

The texture_flags property is a bitmask, and by setting it to Texture.FLAG_REPEAT, you instruct Godot to tile the texture.

Applying Texture to a 3D Model

In a 3D scene, textures are associated with materials to define the object’s surface appearance. Here’s how to apply a texture to a 3D model using a SpatialMaterial:

First, create a new material for your 3D object:

var material = SpatialMaterial.new()

Then, set the albedo texture of the material (which is essentially the base color texture):

material.albedo_texture = my_texture

Finally, assign this material to the mesh instance of your model:

var mesh_instance = $YourMeshInstancePath
mesh_instance.material_override = material

Remember to replace `$YourMeshInstancePath` with the actual path to your MeshInstance node in the scene tree.

Creating an Animated Texture

Godot also allows for animated textures, which are particularly useful for creating dynamic 2D effects. Here’s how to set up an AnimatedTexture:

Create the AnimatedTexture and add frames to it:

var animated_texture = AnimatedTexture.new()
animated_texture.frames = 5 # Assuming we have 5 frames

# Now we load and assign each frame
for i in 0..4:
    var frame = preload("res://path/to/frame_" + str(i) + ".png")
    animated_texture.set_frame_texture(i, frame)
    animated_texture.set_frame_delay(i, 0.1) # Set a delay of 0.1 seconds between frames

Assign the animated texture to a Sprite node:

var sprite = Sprite.new()
sprite.texture = animated_texture
add_child(sprite)
animated_texture.play()

This sets up a simple 5-frame animation, with each frame showing for 0.1 seconds. Don’t forget to call `animated_texture.play()` to start the animation. This is a simple and powerful way to bring movement to your game’s textures.

Stay tuned for the next installment, where we’ll cover even more ground on working with textures in Godot 4, including shaders and real-time texture manipulation!In advanced texturing techniques, you’ll learn how to blend textures together, use textures as masks, create reflections, and utilize normal maps for added realism. These techniques are essential for developing visually complex games that captivate players.

Blending Textures

Blending multiple textures together can create sophisticated surfaces. Here’s a simple way to blend two textures using a ShaderMaterial:

First, create a ShaderMaterial:

var shader_material = ShaderMaterial.new()

Assign a shader to the material that blends two textures:

shader_material.shader_code = """
shader_type canvas_item;

uniform sampler2D texture1 : hint_albedo;
uniform sampler2D texture2 : hint_albedo;

void fragment() {
    vec4 color1 = texture(texture1, UV);
    vec4 color2 = texture(texture2, UV);
    COLOR = mix(color1, color2, 0.5); // Blends texture1 and texture2 evenly
}
"""

Next, set the textures as uniforms:

shader_material.set_shader_param("texture1", preload("res://path/to/your/first_texture.png"))
shader_material.set_shader_param("texture2", preload("res://path/to/your/second_texture.png"))

Finally, apply the ShaderMaterial to a Sprite node:

var sprite = Sprite.new()
sprite.material = shader_material
add_child(sprite)

Using Textures as Masks

Texture masking allows you to control where a texture appears on a sprite. In this example, a mask texture determines the visibility of the sprite’s texture:

shader_material.shader_code = """
shader_type canvas_item;

uniform sampler2D texture : hint_albedo;
uniform sampler2D mask : hint_albedo;

void fragment() {
    vec4 tex_color = texture(texture, UV);
    float mask_value = texture(mask, UV).r; // Using the red channel as the mask
    tex_color.a *= mask_value; // Apply the masking
    COLOR = tex_color;
}
"""

shader_material.set_shader_param("texture", preload("res://path/to/your/texture.png"))
shader_material.set_shader_param("mask", preload("res://path/to/your/mask_texture.png"))

Applying this material to a Sprite node, it will only show “texture” where “mask” is white.

Creating Reflections

Reflections can be simulated in Godot using cube maps or reflection probes for 3D scenes. Here’s how you can apply a simple reflection effect using an environment map on a 3D object:

var env_map_texture = preload("res://path/to/your/env_map.png")
var reflective_material = SpatialMaterial.new()
reflective_material.metallic = 0.9
reflective_material.roughness = 0.1
reflective_material.reflection_texture = env_map_texture

mesh_instance.material_override = reflective_material

Your 3D model will now have a reflective surface that simulates the environment.

Using Normal Maps

Normal maps are great for adding detail to surfaces without increasing the polygon count. Here’s how to apply a normal map to a 3D model:

First, load the normal map texture:

var normal_map = preload("res://path/to/your/normal_map.png")

Create your material and set the normal map:

var material_with_normal = SpatialMaterial.new()
material_with_normal.normal_enabled = true
material_with_normal.normal_texture = normal_map

mesh_instance.material_override = material_with_normal

This will create the illusion of depth on the surface of your 3D model, based on the normal map.

These examples cover several crucial techniques for enhancing the visual appeal of your games with Godot 4. Each method allows for further exploration and creativity, such as adjusting the blend ratios, creating animated masks, or adding complexity to reflections and normal maps for increased realism. Remember, experimentation is key—so take these snippets and tweak them to see how they can best serve your game’s visual narrative.Textures are an essential aspect of enriching the visual experience in games. Continuing from the foundational techniques we’ve already covered, let’s delve into more advanced texturing methods within Godot 4. This will allow us to create even more detailed and interactive visual experiences.

Dynamic Texture Modification

Sometimes, you might want to modify a texture on-the-fly during gameplay. Godot’s Image class makes it a seamless process. Here is an example of how to change an image’s color to grayscale:

First, we need to get the Image from our texture:

var texture = preload("res://path/to/your/texture.png")
var image = texture.get_data()
image.lock()

Then, we can iterate over each pixel and adjust its color:

for var x in range(image.get_width()):
    for var y in range(image.get_height()):
        var color = image.get_pixel(x, y)
        var gray = (color.r + color.g + color.b) / 3.0
        image.set_pixel(x, y, Color(gray, gray, gray))

Don’t forget to unlock the image and create a new texture from it:

image.unlock()
var new_texture = ImageTexture.new()
new_texture.create_from_image(image)

Now, new_texture holds the modified texture that you can apply to any node that uses textures.

Displacement Mapping

Displacement mapping can create the illusion of complex geometry by displacing vertices based on a heightmap texture. A ShaderMaterial is used to apply this effect in real-time:

shader_material.shader_code = """
shader_type spatial;

uniform sampler2D heightmap;
uniform float height_scale;

void vertex() {
    vec3 normal_displacement = texture(heightmap, UV).rgb;
    VERTEX += normalize(NORMAL) * normal_displacement.r * height_scale;
}
"""

Here, the vertex shader reads the red channel of the heightmap and uses it to displace the vertices along their normals.

Screen-space Effects with Textures

With Godot, you can employ textures to develop screen-space effects like vignetting or color grading. For instance, by using a Viewport node’s RenderTarget, you can implement post-processing effects:

var viewport = get_viewport()
var screen_texture = viewport.get_texture()
var screen_material = ShaderMaterial.new()

screen_material.shader_code = """
shader_type canvas_item;

void fragment() {
    vec4 tex_color = texture(SCREEN_TEXTURE, SCREEN_UV);
    // Apply vignette effect to tex_color
    // Apply color grading to tex_color
    COLOR = tex_color;
}
"""

You’ll replace the comments with suitable operations to achieve your desired effect, such as multiplying with a vignette pattern or altering tex_color’s channels for color grading.

Texture Arrays and 3D Textures

Godot 4 introduced TextureArray and Texture3D, powerful tools for specific texturing scenarios like creating atlases for terrain or volumetric effects.

var texture_array = TextureArray.new()
texture_array.create_from_images(your_images_array) // your_images_array is an array of Image objects

Once you have your TextureArray, you can apply it to a ShaderMaterial, and manipulate it within a shader.

For texture 3D, the process is similar, involving volumetric textures which are useful for effects like smoke or fire:

var texture_3d = Texture3D.new()
texture_3d.create_from_images(your_images_array) // Your images are slices of the 3D texture

Inside your shader, these types of textures open up numerous possibilities, allowing for more complex and high-fidelity graphics manipulation.

Texture Projection

The ability to project textures onto surfaces can be utilized to achieve various effects, such as dynamic shadows or decals. Here is a simple example of texture projection onto a plane:

shader_material.shader_code = """
shader_type spatial;

uniform sampler2D decal_texture;
uniform mat4 projector_matrix;

void fragment() {
    vec4 projector_coords = projector_matrix * vec4(VERTEX, 1.0);
    projector_coords.xyz /= projector_coords.w; // Normalize
    projector_coords.xy = projector_coords.xy * 0.5 + 0.5; // Map to UV space
    vec4 decal_color = texture(decal_texture, projector_coords.xy);
    COLOR.rgb = mix(COLOR.rgb, decal_color.rgb, decal_color.a); // Blend decal with existing color
}
"""

In this shader, projector_matrix is the transformation matrix representing the projector’s position and orientation, transforming each vertex into the projector’s view space.

Through these advanced texturing techniques in Godot 4, a developer can greatly enhance the visual depth and immersion of their game, which is critical for creating memorable and engaging player experiences. At Zenva, we understand the importance of staying current with the latest in game development, and incorporating these techniques will certainly provide that cutting edge.

Continuing Your Godot Journey

As you’ve begun to unravel the complexities and possibilities of texturing in Godot 4, you might be wondering what your next steps should be. Your journey in game development is just starting to get exciting, and there’s so much more to explore and master. With the power of Godot 4 and the skills you’ve acquired thus far, you’re well on your way to bringing incredible game ideas to life.

To continue expanding your knowledge and expertise, we highly recommend diving into our comprehensive Godot Game Development Mini-Degree. This collection of courses is meticulously designed to guide you through building cross-platform games with Godot 4. You’ll engage with a variety of essential topics ranging from GDScript and gameplay control flow to intricate game mechanics across different genres. The flexible, self-paced structure of our courses ensures that you can advance your skills around your schedule, making learning accessible and convenient.

For those eager to deepen their understanding of Godot across an array of applications, be sure to explore our wider selection of Godot courses. Whether starting as a beginner or enhancing your existing development prowess, our courses are designed to support you every step of the way. Embrace the opportunity to create, learn, and grow with Zenva—your next game development breakthrough awaits.

Conclusion

In the realm of game development, the power of texturing cannot be understated. With Godot 4, you’ve unlocked just a portion of the boundless potential for visual storytelling and immersive gameplay. We’ve explored the foundational aspects of the Texture class and even glimpsed the advanced techniques capable of bringing your virtual worlds to life. But remember, every great game starts with a single pixel, and every legendary game developer begins with an understanding of the basics.

Your quest for game development mastery continues, and we at Zenva are here to guide you every pixel of the way. Take the next bold step in your development journey by enrolling in our Godot Game Development Mini-Degree. Transform your passion into expertise, and your game ideas into reality. Your adventure has just begun – let’s keep creating, learning, and excelling together!

FREE COURSES
Python Blog Image

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