Vectors are useful in PB land

Thanks in large part to @zranger1 I’ve been spending a lot of time with shaders, Shadertoy, signed distance functions/fields, and so on.

Vectors are really variables of multiple dimensions. So a vec2 might have an x and y component, and vec3 would have an x,y,z, and a vec4 would have x,y,z,w.

Not that you’d have to have them represent spacial references. For example, an RGB color is a vec3, and instead of xyz, would be rgb.

I believe we can emulate a lot but not all of the vector stuff in PB, by using arrays. But we also lack array math. For example, you can add two vec2s,

sum = vec2(1,1) + vec2 (1.1,1.3)

Or
A = vec2(1,1)
B = vec2(1,0)
C = A+B

and you’ll get the Xs added together and Ys added together. But we can’t trivially write this in PB (yet). We probably will have to write a function like vadd() and do this:

A = vec2(1,1)
B = vec2(1,0)
C = vadd(A,B)

I’m imagining vec2 as a function returning a array, and then vadd as taking two arrays and adding them.

So far this seems like it’ll work.

Pulling out vector components is usually written
Like this:

A= vec2(1,0)
B = A.x // Would be equal to 1

So I’m fine with having to fake it like so:

var x = 0 //global indexing, x is always 0

A= vec2(1,0)
B = A[x]// Would be equal to 1

I’m gonna flesh this out more. One more step towards PB as an led shader.

A few notes:

Many languages lack the ability to overload basic operators and apply them to arbitrary types. Most have more than one number type (JS is an exception, everything is a float), and support the operators on a fixed set of primitive types. Some languages like GLSL have vector type primitives and support these operators. As a JS-like language, the language PB uses would probably not head in the direction of supporting vector primitives or operator overloading.

I really like the concept and clean code that it allows for though, and makes parallelizing this kind of math across vector processors / SIMD packing easier.

Assume we’re headed towards the JS way of things, even there you don’t want to allocate memory for every call. Also you could detect dimensionality dynamically, but that also has overhead. The APIs would assume pre-allocated arrays and you get something like this:

vec2Add(dest, A, B)

This also matches pretty closely with a vector + matrix library I picked up to do the coordinate transformation stuff. Take a look there for inspiration, I don’t know that I want to pull over every API, but perhaps we can get a decent base.

1 Like

Perfect, I’ll use that library as a guide, its really clean, and build it as a userspace library, and whatever you move into official firmware only helps.

I noticed when I port stuff from GLSL or "normal"JS, I basically end up doing more work around vectors, object oriented code (properties) and so on. Reducing that redundant work means porting cool stuff faster. In this case, so many shaders use a pile of “standard” things, and the project that @zranger1 and I are doing would benefit from having a good base library to avoid too much of this rewriting. Find a cool shape/effect/pattern and porting it with minimal changes is the goal.

1 Like