A variable-length buffer that compute can push to and pop from, like a JavaScript array.
This is only available in WebGPU mode.
Note: createStorageList() is the recommended way to create an instance of this class.
Examples
Syntax
p5.StorageList()
Parameters
Methods
Replaces the contents of the list with new data from JavaScript, updating the element count to match.
For a list of numbers, update takes in an array of numbers (or a Float32Array.) For a list of objects, pass an array of plain objects with the same properties present as when you created the list.
Appends one element to the list. This can be called from your sketch's JavaScript or from within a compute shader. Use this to seed a list before any compute shaders run. Calling push() after a GPU compute pass that has already modified the list will produce undefined ordering.
For a float list, pass a number. For a struct list, pass a plain object whose properties match the schema.
let positions;
let drawShader;
const COUNT = 5;
async function setup() {
await createCanvas(200, 200, WEBGPU);
positions = createStorageList(COUNT, { pos: createVector(0, 0) });
for (let i = 0; i < COUNT; i++) {
positions.push({
pos: createVector(
random(-1, 1) * width / 2,
random(-1, 1) * height / 2
)
});
}
drawShader = buildMaterialShader(() => {
let data = uniformStorage(positions);
worldInputs.begin();
worldInputs.position.xy += data[instanceIndex].pos;
worldInputs.end();
});
describe('Five circles placed at random positions.');
}
function draw() {
background(220);
noStroke();
shader(drawShader);
instances(positions).circle(0, 0, 20);
}You can also use push() from compute shaders. This approach can often be faster as no data needs to transfer from the CPU to the GPU.
let particles, nextParticles;
let removeOld, emitNew;
let drawParticles;
const MAX_PARTICLES = 300;
async function setup() {
await createCanvas(200, 200, WEBGPU);
const schema = { position: createVector(0, 0), velocity: createVector(0, 0), life: 0 };
particles = createStorageList(MAX_PARTICLES, schema);
nextParticles = createStorageList(MAX_PARTICLES, schema);
// Seed an initial burst from JavaScript so something is visible on frame 1.
for (let i = 0; i < 20; i++) {
let angle = random(TWO_PI);
particles.push({
position: createVector(0, 0),
velocity: createVector(cos(angle) * 2, sin(angle) * 2 - 2.5),
life: random(0.5, 1.0)
});
}
removeOld = buildComputeShader(() => {
let src = uniformStorage(() => particles);
let dst = uniformStorage(() => nextParticles);
if (index.x < src.length) {
let p = src[index.x];
p.velocity.y += 0.08;
p.position += p.velocity;
p.life -= 0.02;
if (p.life > 0) {
dst.push(p);
}
}
});
emitNew = buildComputeShader(() => {
let dst = uniformStorage(() => nextParticles);
let angle = random() * TWO_PI;
dst.push({
position: [mouseX, mouseY] - [width, height] / 2,
velocity: [cos(angle), sin(angle) - 2.5],
life: 1.0
});
});
drawParticles = buildMaterialShader(() => {
let particleData = uniformStorage(() => particles);
let p = particleData[instanceIndex];
worldInputs.begin();
worldInputs.position.xy += p.position;
worldInputs.end();
finalColor.begin();
finalColor.set([1, p.life * 0.4, 0, p.life]);
finalColor.end();
});
describe('Orange particles emitting from the cursor, falling with gravity.');
}
function draw() {
background(0);
noStroke();
nextParticles.clear();
compute(removeOld, MAX_PARTICLES);
compute(emitNew, 5);
[particles, nextParticles] = [nextParticles, particles];
shader(drawParticles);
blendMode(ADD);
instances(particles).circle(0, 0, 4);
}Reads the current contents of the list back to JavaScript.
It returns a Float32Array for float lists, or an array of plain objects for struct lists.
Note: This is a GPU-to-CPU read. Calling it frequently can be slow.