How to exchange data with shaders efficiently?

Godot Version

^4.2

Question

I used to create an Image for an ImageTexture to display a pixel grid onto a Sprite2D. However, it is certainly not as efficient as the shader, due to the large switch (format) statement of the Image.set_pixel method (and other reasons). I thought it would be easy, but the uniform does not support any “vector” stuff.

The uniform supports arrays. For instance: uniform float[1000] array_data;

That is a statically defined (or compile-time) data block, just like arrays in C and C++. I don’t want to have a super wasting uniform float[100000] data, I’m looking for an approach to define dynamic buffers.

I thought you could put any data type, including vec2, 3, and 4 as a uniform?

The “vector” I refer to is a dynamically-sized array named in C++, semantically equivalent to the Godot class Array.

Clarification on Arrays

In languages with low-level APIs like C/C++, an array is essentially a static memory block, like any int and float. To create a dynamic array or list like in Python, we need a way to get a memory block of a size given by a variable. This is where the heap comes into play, allowing for dynamic memory allocation, like malloc() in C and new in C++.

In modern languages like C# and Python, their array/list does the heap allocation of the same one as C/C++ under the hood. In other words, the concept of arrays in C#/Python is different from that in C/C++. Arrays in C/C++ are static, and heap-allocated memory is equivalent to the concept of lists in Python.

Language Approach Type
C/C++ int a[123]; Static
C int * a = malloc(sizeof(int) * 123); Dynamic
C++ int * a = new int[123]; Dynamic
C# int[] a = new int[123]; Dynamic
Python a = [] or a = list() Dynamic

When I first learned C++, I thought, “What?! Can C++ only create arrays of a fixed size? That stinks!” Then I realized that the list [] of Python, is being implemented through heap memory allocation.