PortableCompressedTexture2D in Godot – Complete Guide

Welcome to this in-depth exploration of the PortableCompressedTexture2D class in Godot 4. Today, we’re going to unravel the intricacies of this powerful feature that can significantly optimize your games’ performance and storage requirements. Whether you’re taking your first steps into game development or you’re an experienced coder broadening your toolkit, understanding the functionalities of compressed textures can be a game-changer for your projects.

What is PortableCompressedTexture2D?

The PortableCompressedTexture2D class is a tool that allows game developers to store and manage compressed textures efficiently. But why is this class so critical for your game’s performance?

  • It enables the storing of textures in a compressed format on the disk, which saves space and reduces load times.
  • It can be configured for different purposes, such as 2D or 3D rendering, making it versatile for various game types.
  • The class supports various compression modes to suit different platform targets, from desktop to mobile.

What is it for?

The class’s primary function is to store textures in a way that is easily portable between different systems and hardware. It does so by providing multiple compression modes tailored for specific use cases:

  • Lossless and Lossy modes for 2D games, focusing on quality and performance balance.
  • Specific compression such as S3TC or BPTC for desktop, with ETC2 recommended for mobile.
  • A universal option, Basis Universal, to cover a wider range of platforms.

Why should I learn it?

Learning how to use PortableCompressedTexture2D places potent capabilities at your fingertips:

– **Optimized storage**: Disc space is critical, and compressed textures significantly reduce the size of your game files.
– **Faster loading times**: Smaller textures load faster, leading to better player experiences, especially for large, asset-heavy games.
– **Cross-platform support**: The flexibility to support different platforms without extensive rework saves time and resources, enabling you to reach a broader audience.

Stay tuned as we deep dive into the code and practical examples on how to leverage the PortableCompressedTexture2D class to enhance your game development process.

CTA Small Image

Creating a New PortableCompressedTexture2D

To start using PortableCompressedTexture2D in your Godot 4 projects, you’ll first need to create an instance of the class. Here’s how you can create a new PortableCompressedTexture2D:

var my_compressed_texture = PortableCompressedTexture2D.new()

Once you’ve created an instance, you’ll want to load an existing texture into it. Below is an example of how to load a texture from a file:

var texture_path = "res://path_to_your_texture.png"
var error = my_compressed_texture.load(texture_path)

Always ensure that you handle any errors that might occur during the loading process:

if error != OK:
    push_error("An error occurred while loading the texture: " + str(error))

Setting Compression Mode

The next step is setting the compression mode according to your needs. Whether you target desktop or mobile platforms, you can select an appropriate mode. Here’s an example of setting the mode to S3TC for desktop:

my_compressed_texture.compression_mode = PortableCompressedTexture2D.COMPRESSION_S3TC

For mobile platforms, you might choose ETC2:

my_compressed_texture.compression_mode = PortableCompressedTexture2D.COMPRESSION_ETC2

It’s essential to configure this before saving or using the texture, as changing the compression mode later will require recompression.

Saving Compressed Textures

After configuring your texture, you’ll now want to save it to disk for later use. Saving a texture as a .ctex file is straightforward:

var save_path = "res://path_to_save_texture.ctex"
var error = my_compressed_texture.save(save_path)

if error != OK:
    push_error("Failed to save compressed texture: " + str(error))

It’s a good practice to always manage errors during saving, as it helps debug issues with file permissions or incorrect paths.

Using Compressed Textures in Your Game

Once you have your texture compressed and saved, you can use it in your game. To use a compressed texture on a sprite, for instance, you’d do the following:

var compressed_texture_path = "res://path_to_your_compressed_texture.ctex"
var compressed_texture = load(compressed_texture_path)

var sprite = Sprite.new()
sprite.texture = compressed_texture

This allows you to place the sprite in your game scene with the compressed texture applied seamlessly.

Remember, the principles covered here are just the beginning. As you get more familiar with PortableCompressedTexture2D, you’ll discover many more ways to leverage this in your game development, ensuring you maintain high performance and visual fidelity across platforms.Continuing with our tutorial, let’s dive deeper into the practical usage of PortableCompressedTexture2D in Godot 4 with more code snippets that take you through essential functionalities step by step. Remember that thorough testing and error handling are key to ensuring robustness in your game’s texture handling.

When you want to programmatically set the texture’s format, Godot offers a range of options. You can choose a format that balances quality and performance based on your game’s needs. Here is how to set a texture to use the ETC2 format, which is well-suited for mobile projects:

my_compressed_texture.format = Image.FORMAT_ETC2_RGB8

With the format properly set, you might want to process or modify the texture data directly before saving or using the texture. Godot’s image manipulation methods become available once you access the underlying Image object:

var image = my_compressed_texture.get_data_as_image()
# Perform pixel manipulation, note that coordinates and color are just an example.
image.set_pixel(10, 20, Color(1.0, 0.0, 0.0, 1.0))

# Update the texture with the modified image

For cases where you need to ensure that a texture fits certain criteria, such as being a power of two, you can check and resize accordingly:

if not image.is_size_power_of_two():

Sometimes, it might be important to generate mipmaps for your texture to ensure better quality when textures are downscaled. Here’s how you can generate mipmaps:


In instances where you need to directly access or manipulate the compressed data, Godot’s StreamPeerBuffer class can come in handy:

var buffer = StreamPeerBuffer.new()
# ... use the buffer to manipulate the compressed data directly

And when your game needs to update its textures on-the-fly, such as for dynamic content or downloadable assets, here’s how you could reload the compressed texture from a server or local storage:

var new_texture_path = "res://new_path_to_your_texture.ctex"

Once you’ve made your changes, don’t forget to assign the updated texture to your game objects to see the changes take effect:

# Assuming you have a reference to a game object with a texture
var game_object_with_texture = get_node("YourGameObjectNodePath")
game_object_with_texture.texture = my_compressed_texture

These examples should give you a wide range of tools to effectively manage and manipulate textures within your Godot 4 projects. Efficient texture management is critical as it impacts not only the visual quality but also the performance of your games. Using PortableCompressedTexture2D, you’ll streamline your workflow, conserve game resources, and provide a smoother experience for your players. Dive into these functionalities, test them in your own projects, and continue to discover the power of Godot’s highly versatile engine.In your journey with PortableCompressedTexture2D, you may encounter scenarios where the actions aren’t as straightforward as loading or saving. Here are additional code snippets that highlight some other functionalities and how you can implement them.

When working with animated textures, you might need to handle each frame differently. Suppose you have an animated texture with several frames; you could process each frame like so:

var frame_count = my_compressed_texture.get_frame_count()
for frame in range(frame_count):
    var frame_image = my_compressed_texture.get_data_as_image(frame)
    # Do something with each frame_image

For optimization, it’s often necessary to determine the original size of the texture before compression. You can retrieve the original dimensions like this:

var original_width = my_compressed_texture.get_original_width()
var original_height = my_compressed_texture.get_original_height()
# Now you can use original_width and original_height for calculations or UI adjustments.

Additionally, consider scenarios where you want to compare two textures to see if they are identical. This might come into play when implementing caching mechanisms or before performing resource-intensive operations:

var another_compressed_texture = ... # Load or create another PortableCompressedTexture2D
if my_compressed_texture.get_data_hash() == another_compressed_texture.get_data_hash():
    print("The textures are identical.")
    print("The textures are different.")

If your game’s design allows the player to create or modify textures, such as drawing on a canvas or customizing elements, you might need to update the compressed texture from a raw PoolByteArray:

var raw_data = PoolByteArray() # Assume this is filled with data
my_compressed_texture.create_from_image(Image.new(), raw_data)

In instances where you would like to offer players the ability to undo or redo steps, you might handle the texture data in a stack-like structure and revert to the previous state:

var texture_stack = [] # Use an array as a simple stack
# When making a change, push the current state

# To undo, pop the last state and apply it
var previous_texture_image = texture_stack.pop_back()

Sometimes you’ll want to ensure a consistent look under different lighting conditions. If the texture is to be used as part of a 3D material, you may also need to create a normal map from the texture:

var normal_map = my_compressed_texture.get_data_as_image().duplicate()
my_3D_material.albedo_texture = my_compressed_texture
my_3D_material.normal_map = normal_map

Remember that each project is unique, and so are its requirements. Through these code examples, you’ve seen the flexibility of PortableCompressedTexture2D in addressing a broad range of scenarios. Our goal at Zenva is to empower you with the knowledge to make the best technical decisions for your game development process. Utilize these methods and examples as a foundation, experiment with them, and tailor them to suit the specific needs of your Godot 4 projects.

Where to Go Next in Your Game Development Journey

Embarking on your journey through the Godot 4 engine and the world of PortableCompressedTexture2D is only the beginning. To expand your knowledge further and build upon the foundation laid in this tutorial, the Godot Game Development Mini-Degree is an excellent next step. This comprehensive collection of courses will guide you deep into the art of crafting cross-platform games with Godot’s latest iteration. The curriculum is meticulously designed to accommodate both novices and experienced developers, ensuring a solid path of progression from the essentials to more complex projects.

Whether you aim to master 2D and 3D assets, hone your skills in GDScript, or design intricate game systems across a variety of genres, the Mini-Degree is tailored to equip you with the practical know-how needed to bring your creative visions to life. The flexibility of our course structure means you can learn anytime, anywhere, with projects that fit your pace and quizzes to consolidate your learning.

Beyond the Mini-Degree, our extensive Godot course offerings can further enhance your game development prowess. We invite you to explore our array of Godot courses that cater to all skill levels, ensuring that regardless of where you are in your learning journey, Zenva can help propel you to professional heights.

Remember, the key to growth in game development is consistent practice and a desire to learn. With Zenva’s courses, you’ll not only gain valuable knowledge but also be able to apply it in crafting your own remarkable games. We look forward to being a part of your growth in this exciting field.


As we wrap up this insightful exploration of the Godot 4 PortableCompressedTexture2D, remember that this is just a mere glimpse into the expansive universe of game development. With each new function you master and each line of code you write, you inch closer to transforming your creative ideas into tangible realities within your games.

Embrace the journey ahead with enthusiasm, and continue to harness the power of Godot 4 with our Godot courses at Zenva. Whether it’s refining your technical skills or delving into new territories in game design, we are here to support every step of your development adventure. Let’s keep pushing the boundaries of what’s possible together, crafting experiences that captivate and games that resonate long after the screen fades to black.

Python Blog Image

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