Data Schemas
Writing a GPU program usually involves sharing data between the host (CPU) and the device (GPU), in this case between JavaScript and WGSL. Any misalignments or misinterpretations of data can lead to bugs that are hard to debug (No console.log
on the GPU, I am afraid). While data is strongly typed in WGSL shaders, we give up that type safety completely when writing and reading data in JavaScript/TypeScript. This is precisely what TypeGPU data types help with.
Examples
Let’s look at some examples of defining custom data types using the typegpu/data
module. If you’re familiar with Zod, then this style of schema definitions may already seem familiar.
By defining the Circle
struct in TypeScript via TypeGPU, in a similar way to how we would in WGSL, we gain access to its TypeScript type definition, which we can use to validate our data values. When reading from or writing data to the GPU, the type of the JavaScript value is inferred automatically, and it’s enforced by TypeScript. Thanks to that, whenever we mistakenly set or assume a wrong value for an object, we get a type error, avoiding unnecessary debugging afterwards. That’s a big improvement to the development process.
Defined data structures automatically measure and hold information about their memory layout parameters, which is useful for writing to and reading data from the GPU.
TypeGPU data types are essential for the library’s automated data marshalling capabilities. You can read more about it in the chapter dedicated to tgpu.write
.
Built-in primitive data types
Schema | JavaScript | WGSL |
---|---|---|
number | f32 | |
number | i32 | |
number | u32 | |
boolean | bool |
Vector and matrix types
Schema | Value constructors | WGSL equivalents |
---|---|---|
vec2u |
| vec2u, vec2<u32> |
vec2f |
| vec2f, vec2<f32> |
vec2i |
| vec2i, vec2<i32> |
vec3u |
| vec3u, vec3<u32> |
vec3f |
| vec3f, vec3<f32> |
vec3i |
| vec3i, vec3<i32> |
vec4u |
| vec4u, vec4<u32> |
vec4f |
| vec4f, vec4<f32> |
vec4i |
| vec4i, vec4<i32> |
mat2x2f |
| mat2x2f, mat2x2<f32> |
mat3x3f |
| mat3x3f, mat3x3<f32> |
mat4x4f |
| mat4x4f, mat4x4<f32> |
Complex data structures
struct
Each struct has its byteAlignment
equal to the biggest byteAlignment of its properties. It is also possible to override default byte alignment and size for particular fields via the align
and size
functions.
arrayOf
To define arrays of known constant length, use the arrayOf
function. It accepts as arguments the array’s elements data type constructor and the length of the array.