RDVertexAttribute in Godot – Complete Guide

Welcome to our deep dive into the world of Godot 4, where we’ll dissect and explore the RDVertexAttribute class. If you’ve ever been intrigued by game development or simply want to broaden your coding skillset, this tutorial is tailored for you. The RDVertexAttribute class is a fundamental component of the Godot Engine, enabling the creation of visually rich and interactive experiences. So, join us on this adventure as we unravel the mysteries of vertex attributes and step confidently into the realm of game development.

What is RDVertexAttribute?


is a class within the powerful Godot 4 game engine that is used for defining the properties of vertex attributes. These attributes help to dictate how vertex data is organized and processed within the graphics pipeline.

What is it for?

In 3D rendering, vertices form the smallest elements of your graphics, composing the structure of your 3D models. The RDVertexAttribute works behind the scenes to specify the details of each vertex, such as its position, color, normals, and more. This meticulous definition allows for fine control over rendering, enabling a developer to create detailed and optimized visual representations within a game.

Why should I learn it?

Understanding RDVertexAttribute is crucial for any aspiring game developer or anyone looking to manipulate graphics at a low level. This knowledge enables you to:

– Enhance game performance by efficiently defining vertex data.
– Gain finer control over graphical rendering and shading processes.
– Expand your expertise in Godot 4, one of the leading game development engines.

By mastering RDVertexAttribute, you will have taken one more step towards creating stunning visual effects and high-performance games. Whether you’re a beginner or an experienced coder, learning the intricacies of this class will be immensely beneficial to your journey in game development.

CTA Small Image

Creating Vertex Attributes in Godot 4

To start utilizing RDVertexAttribute, you must first create it and define its properties. Here’s an example of how to define a simple vertex attribute for a position:

var position_attribute = RDVertexAttribute()
position_attribute.format = RDFORMAT_FLOAT_32_VECTOR3
position_attribute.offset = 0
position_attribute.stride = 12
position_attribute.type = RDVERTEX_ATTRIBUTE_TYPE_FLOAT
position_attribute.usage = RDVERTEX_ATTRIBUTE_USAGE_POSITION

Now, let’s add a color attribute to give our vertices some life:

var color_attribute = RDVertexAttribute()
color_attribute.format = RDFORMAT_FLOAT_32_VECTOR4
color_attribute.offset = 12
color_attribute.stride = 16
color_attribute.type = RDVERTEX_ATTRIBUTE_TYPE_FLOAT
color_attribute.usage = RDVERTEX_ATTRIBUTE_USAGE_COLOR

Once we have our attributes defined, we can bundle them into an array to create a vertex format:

var vertex_format = [position_attribute, color_attribute]

With a defined vertex format, we can now set up the vertex buffer:

var vertex_buffer = RDRendererStorage.buffer_create()
RDRendererStorage.buffer_set_data(vertex_buffer, your_vertex_data)

After setting up the vertex buffer, we specify how to interpret the data:

var vertex_array = RDRendererStorage.vertex_array_create()
RDRendererStorage.vertex_array_add_attribute(vertex_array, vertex_buffer, position_attribute)
RDRendererStorage.vertex_array_add_attribute(vertex_array, vertex_buffer, color_attribute)

Interacting with Vertex Attributes

Interacting with vertex attributes typically involves altering their properties to modify how vertices are rendered. Here’s an example of how you might change the color attribute for an animation:

color_attribute.offset = new_offset
RDRendererStorage.vertex_array_set_attribute(vertex_array, 1, color_attribute)

Accessing vertex attribute values, such as for debugging purposes, is similarly straightforward:

var current_color_attribute = RDRendererStorage.vertex_array_get_attribute(vertex_array, 1)
print("Current Color Attribute Offset: " + str(current_color_attribute.offset))

Combining and interpolating multiple vertex attributes can lead to more complex effects. Below is an example of interpolating two color attributes to blend vertices smoothly:

var color_attribute_a = RDRendererStorage.vertex_array_get_attribute(vertex_array, 1)
var color_attribute_b = RDRendererStorage.vertex_array_get_attribute(vertex_array, 2)
var interpolated_attribute = color_attribute_a.interpolate_with(color_attribute_b)

When removing an attribute from the vertex array. This may be necessary when changing the format entirely:

RDRendererStorage.vertex_array_remove_attribute(vertex_array, color_attribute)

Remember, the graphics pipeline is a complex system, and each attribute you define or modify has a direct impact on the rendering outcome. Take the time to experiment with these examples, see how they affect your project, and you will develop a more intuitive understanding of how RDVertexAttribute shapes your game world.

As we progress further into the intricacies of RDVertexAttribute, it’s essential to delve into how we can maximize the potential of our vertices. This will involve a more detailed look at creating advanced custom vertex attributes and managing them in Godot 4.

Let’s begin by creating a custom attribute for texture coordinates, often used for applying textures to our 3D models:

var uv_attribute = RDVertexAttribute()
uv_attribute.format = RDFORMAT_FLOAT_32_VECTOR2
uv_attribute.offset = compute_attribute_offset()
uv_attribute.stride = 8

Here’s how you could compute the offset dynamically:

func compute_attribute_offset() -> int:
    return position_attribute.stride + color_attribute.stride

After setting up individual attributes, you might want to create multiple sets of UV coordinates for more advanced texturing methods:

var uv2_attribute = RDVertexAttribute()
uv2_attribute.format = RDFORMAT_FLOAT_32_VECTOR2
uv2_attribute.offset = compute_attribute_offset()
uv2_attribute.stride = 8
uv2_attribute.usage = RDVERTEX_ATTRIBUTE_USAGE_TEX_UV2

For our next example, let’s look at normals, which are essential for lighting calculations in 3D environments:

var normal_attribute = RDVertexAttribute()
normal_attribute.format = RDFORMAT_FLOAT_32_VECTOR3
normal_attribute.offset = compute_attribute_offset()
normal_attribute.stride = 12
normal_attribute.type = RDVERTEX_ATTRIBUTE_TYPE_FLOAT
normal_attribute.usage = RDVERTEX_ATTRIBUTE_USAGE_NORMAL

Managing these attributes requires being mindful of their order and the size of the strides. When attributes are added to a vertex array, they need to be in the correct order and stride size as the data in your buffer. Adjustments may be needed based on your buffer layout:

RDRendererStorage.vertex_array_add_attribute(vertex_array, vertex_buffer, position_attribute)
RDRendererStorage.vertex_array_add_attribute(vertex_array, vertex_buffer, normal_attribute)
RDRendererStorage.vertex_array_add_attribute(vertex_array, vertex_buffer, uv_attribute)
RDRendererStorage.vertex_array_add_attribute(vertex_array, vertex_buffer, uv2_attribute)

If you want to update an attribute’s data dynamically, you would change the buffer’s content. This is common for animation and morphing effects:

var new_vertex_data = get_dynamic_vertex_data()
RDRendererStorage.buffer_set_data(vertex_buffer, new_vertex_data)

Finally, when it’s time to clean up, ensure to remove and free up created RDRendererStorage resources to prevent leaks:


These code snippets showcase the flexibility and control RDVertexAttribute offers in the rendering process within Godot 4. By adequately managing these attributes, developers can truly bring their digital worlds to life with precise geometric and textural details. Experiment with combining different attributes and learn how each one contributes to the final rendered scene, pushing the boundaries of what you can visualize and achieve in your games.

We will now go beyond the basics and leverage the power of RDVertexAttribute to create advanced effects. Let’s explore skinning which involves animating characters using a skeleton structure. We will add attributes for bone indices and weights:

var bone_index_attribute = RDVertexAttribute()
bone_index_attribute.format = RDFORMAT_INT_16_VECTOR4
bone_index_attribute.offset = compute_attribute_offset()
bone_index_attribute.stride = 8
bone_index_attribute.type = RDVERTEX_ATTRIBUTE_TYPE_INT
bone_index_attribute.usage = RDVERTEX_ATTRIBUTE_USAGE_BONE_INDEX

var bone_weight_attribute = RDVertexAttribute()
bone_weight_attribute.format = RDFORMAT_FLOAT_32_VECTOR4
bone_weight_attribute.offset = compute_attribute_offset()
bone_weight_attribute.stride = 16
bone_weight_attribute.type = RDVERTEX_ATTRIBUTE_TYPE_FLOAT
bone_weight_attribute.usage = RDVERTEX_ATTRIBUTE_USAGE_BONE_WEIGHT

To apply these new attributes, you would adjust their offset accordingly and add them to the vertex array:

RDRendererStorage.vertex_array_add_attribute(vertex_array, vertex_buffer, bone_index_attribute)
RDRendererStorage.vertex_array_add_attribute(vertex_array, vertex_buffer, bone_weight_attribute)

Custom shaders can also benefit from explicit vertex attributes. You might create an attribute for a shader that works with custom lighting calculations:

var custom_light_attribute = RDVertexAttribute()
custom_light_attribute.format = RDFORMAT_FLOAT_32
custom_light_attribute.offset = compute_attribute_offset()
custom_light_attribute.stride = 4
custom_light_attribute.type = RDVERTEX_ATTRIBUTE_TYPE_FLOAT
custom_light_attribute.usage = RDVERTEX_ATTRIBUTE_USAGE_CUSTOM

Frequently when developers manage custom effects, they need to update these attributes using an animation loop, like this:

func update_custom_attribute_animation(delta):
    var updated_custom_light_value = get_custom_light_value()
    RDRendererStorage.vertex_array_set_attribute(vertex_array, custom_attribute_index, updated_custom_light_value)

Additionally, managing blend shapes for character expressions and morphing effects requires dynamic vertex updates:

var blend_shape_delta_attribute = RDVertexAttribute()
blend_shape_delta_attribute.format = RDFORMAT_FLOAT_32_VECTOR3
blend_shape_delta_attribute.offset = compute_attribute_offset()
blend_shape_delta_attribute.stride = 12
blend_shape_delta_attribute.type = RDVERTEX_ATTRIBUTE_TYPE_FLOAT
blend_shape_delta_attribute.usage = RDVERTEX_ATTRIBUTE_USAGE_CUSTOM

var new_blend_shape_data = get_blend_shape_vertex_data()
RDRendererStorage.buffer_update_data(vertex_buffer, blend_shape_delta_attribute.offset, new_blend_shape_data)

When building particle systems, using custom vertex attributes makes it possible to control individual particle properties like velocity, lifetime, or custom data:

var particle_velocity_attribute = RDVertexAttribute()
particle_velocity_attribute.format = RDFORMAT_FLOAT_32_VECTOR3
particle_velocity_attribute.offset = compute_attribute_offset()
particle_velocity_attribute.stride = 12
particle_velocity_attribute.type = RDVERTEX_ATTRIBUTE_TYPE_FLOAT
particle_velocity_attribute.usage = RDVERTEX_ATTRIBUTE_USAGE_CUSTOM

RDRendererStorage.vertex_array_add_attribute(vertex_array, vertex_buffer, particle_velocity_attribute)

Sometimes, we also need to adjust the attribute’s layout to accommodate different rendering scenarios or optimizations required for hardware constraints:

func adjust_attribute_layout():
    position_attribute.stride = new_stride
    normal_attribute.stride = new_stride
    uv_attribute.stride = new_stride
    RDRendererStorage.vertex_array_set_attribute(vertex_array, position_attribute_index, position_attribute)
    RDRendererStorage.vertex_array_set_attribute(vertex_array, normal_attribute_index, normal_attribute)
    RDRendererStorage.vertex_array_set_attribute(vertex_array, uv_attribute_index, uv_attribute)

These code examples showcase the potential and versatility of RDVertexAttributes within Godot 4. By thoughtfully structuring vertex data and using RDRendererStorage effectively, developers can create customizable and dynamic graphics within Godot’s robust rendering pipeline. Mastery of these concepts paves the way to creating anything from the simplest shapes to the most complex animated characters and effects.

Continuing Your Godot 4 Journey

Embarking on the path of game development can be exhilarating, and there’s always more to learn. If you’re eager to delve deeper and expand your skills in Godot 4, our comprehensive Godot Game Development Mini-Degree is the perfect next step. This program is designed to transform beginners into confident developers, covering a wide range of topics from the creation of 2D and 3D assets, to mastering GDScript and building intricate game mechanics. The project-based structure of our courses empowers you to learn by doing, ensuring you gain practical, hands-on experience.

Whether you are starting out or seeking to enhance your existing abilities, the Godot Game Development Mini-Degree caters to all experience levels. Our library of Godot courses will support your learning process, providing you with an extensive set of tools to create your own captivating games. The Godot 4 engine’s open-source nature underpins a strong foundation for your growth as a game developer, fostering a versatile and robust skill set that can open doors to myriad career opportunities.

Dive into our vast selection of Godot courses and continue on your path to becoming a professional game developer. With Zenva, you can go from beginner to proficient, crafting your own worlds and bringing your game ideas to life. We can’t wait to see what you create next!


Exploring the depths of RDVertexAttribute within Godot 4 is akin to unlocking a new level of creative potential in your game development journey. With these newfound skills, you’re well on your way to fine-tuning your games and transforming your innovative ideas into engaging, interactive experiences. Remember, the realm of game creation is limitless, and as you continue to learn and experiment, you’ll discover that each new feature mastered is a stepping stone towards your masterpiece.

Take pride in the knowledge you’ve accumulated and don’t hesitate to push further. Revisit our Godot Game Development Mini-Degree whenever you’re ready to expand your expertise even more. At Zenva, we’re dedicated to supporting your growth every pixel of the way. So, continue crafting, coding, and creating—the game development world eagerly awaits your next great adventure.

Python Blog Image

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