Skip to content

Releases: processing/p5.js

v2.3.0

28 May 17:20
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

2.3.0: New features from the growing p5.strands contributor community 🌱

Absract pixel image based on Conway's Game of Life with the text p5.js 2.3 on top

What's Changed 🎊

Work since 2.2.3 has focused on stabilization and workflow improvements; refactors to p5.Vector based on the recently-added Decorators API; and new beginner-friendly shader programming API features (p5.strands), as well as the experimental WebGPU renderer.

This release includes work from many contributors, stewards, and testers - including new contributors to p5.strands! welcome, and thanks for all your amazing diligence and creativity 🎉 🎉 🎉

Note

This release includes updates in p5.js vectors. Vectors are used in simulations, including many "Nature of Code sketches", like these Autonomous Agents examples. When creating empty vectors, always provide parameters: createVector()createVector(0,0) ✅ or createVector(0,0,0) ✅ . Although the empty constructor was common before p5.js v2, now p5.js supports vectors of different dimensions. Even when vectors are empty, giving 0, 0 parameters makes it clear if it is a 2D or 3D vector. Operations on vectors are only defined on same-dimension vectors: when adding or multiplying vectors together, for example, both should be 2D or both 3D.

Workflow Improvements

To support testing new contributions, there are now continuous releases on Pull Requests: look for this comment from p5js-bot on any Pull Request, and use the CDN link in test sketches to help with review:

GitHub commend with CDN link

Work is ongoing on distributing custom builds, thanks to @limzykenneth. Please do test the custom/modular builds tool (there is also OpenAPI JSON documentation available plus GUI API reference).

screenshot of a selector menu to include only some of the modules in p5.js

The goal is smaller import size by providing a custom build. Work is ongoing for more separation between modules, right now Including all modules makes it a bit larger but you can use custom build. For now, the above tool is for testing, rather than for using in your work directly - we welcome your input!

p5.strands updates: new features and experimental compute shader support 🎉

On graphics, we have continued to work on beginner-friendly shader programming API features (p5.strands), as well as the experimental WebGPU renderer.

The p5.strands code has been refactored and simplified, which will make maintenance and contribution easier in the future, thanks to @davepagurek and @LalitNarayanYadav. Additionally, p5.strands, used with the experimental WebGPU renderer, now supports compute shaders, thanks to @davepagurek and @aashu2006.

This minor release includes exciting p5.strands API additions by the growing p5.strands contributor community:

  • filter shaders are supported on 2D sketches, thanks to @LalitNarayanYadav
  • random() and randomSeed() is available in p5.strands code, thanks to @perminder-17
  • map() is available in p5.strands code, thanks to @Nixxx19
  • lerp() and instanceID() are more consistently supported, thanks to @aashu2006
  • more helpful error messages, thanks to @kushal1061
  • corrected TypeScript typing, thanks to @Kathrina-dev
  • simple shader materials can be written much easier, using only finalColor hook thanks to @YuktiNandwana

Here is an example p5.js sketch using p5.strands, with the noise-based texture:

Cloudy cube against a pink background
let myShader;
function setup() {
  createCanvas(400, 400, WEBGL);
  myShader = buildMaterialShader(myShaderBuilder);
}
function myShaderBuilder(){
  finalColor.begin();
  let coord = finalColor.texCoord;
  finalColor.set(noise(coord.x, coord.y));
  finalColor.end();
}

function draw() {
  stroke(255);
  background("#f1678e");
  shader(myShader);
  orbitControl();
  box(100);
}

Finally, p5.strands, used with the experimental WebGPU renderer, now supports compute shaders. For example, below is code for a Game of Life simulation, written by @davepagurek. This uses compute shaders (compare the code to the non-shader example here.)

// noprotect
// Authored by Dave Pagurek to demonstrate an WebGPU compute shaders

let cells;
let nextCells;
let gameShader;
let displayShader;
let W = 0;
let H = 0;

async function setup() {
  W = 100;
  H = 100;
  await createCanvas(100, 100, WEBGPU);
  pixelDensity(1);

  let initial = new Float32Array(W * H);
  for (let i = 0; i < initial.length; i++) {
    initial[i] = random() > 0.7 ? 1 : 0;
  }
  cells = createStorage(initial);
  nextCells = createStorage(W * H);

  gameShader = buildComputeShader(simulate);
  displayShader = buildFilterShader(display);
}

function simulate() {
  let current = uniformStorage(() => cells);
  let next = uniformStorage(() => nextCells);
  let w = uniformInt(() => W);
  let h = uniformInt(() => H);
  let x = index.x;
  let y = index.y;

  let n = 0;
  for (let dy = -1; dy <= 1; dy++) {
    for (let dx = -1; dx <= 1; dx++) {
      if (dx != 0 || dy != 0) {
        let nx = (x + dx + w) % w;
        let ny = (y + dy + h) % h;
        n += current[ny * w + nx];
      }
    }
  }

  let alive = current[y * w + x];
  let nextOutput = 0;
  if (alive == 1) {
    if (n == 2 || n == 3) {
      nextOutput = 1;
    }
  } else {
    if (n == 3) {
      nextOutput = 1;
    }
  }
  next[y * w + x] = nextOutput;
}

function display() {
  let data = uniformStorage(() => cells);
  let w = uniformInt(() => W);
  let h = uniformInt(() => H);

  filterColor.begin();
  let x = floor(filterColor.texCoord.x * w);
  let y = floor(filterColor.texCoord.y * h);
  let alive = data[y * w + x];
  filterColor.set([alive, alive, alive, 1]);
  filterColor.end();
}

function draw() {
  compute(gameShader, W, H);
  [nextCells, cells] = [cells, nextCells];
  filter(displayShader);
}

p5.strands and WebGPU

Read more

v2.3.0-rc.6

26 May 15:00
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

v2.3.0-rc.6 Pre-release
Pre-release

Testers Wanted 💚

This is a release candidate (RC), which means it is not yet live on the p5.js Editor. Please help us to improve the stability of the newest version of p5.js by trying out this release candidate, and reporting bugs.

To help with testing, you can use this starter sketch!

Or load both p5.js and WebGPU mode by adding these two script tags to your sketch:

<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.webgpu.js"></script>

Then load WebGPU mode in createCanvas - note the async/await, this is needed for WebGPU but not WebGL:

async function setup() {
  await createCanvas(400, 400, WEBGPU);
}

What's Changed 🎊

Work since 2.2.3 has focused on graphics and stabilization, including on version p5.Vector. In version 1, it was common to use createVector() which would create a three-dimensional vector at (0, 0, 0). In version 2, empty vectors should be made with createVector(0, 0) or createVector(0, 0, 0), to make clear when it is two or three dimensional. This is because version 2 supports vectors of different dimensions, although usages are still related to graphics and require 3D vectors.

On graphics, we have continued to work on beginner-friendly shader programming API features (p5.strands), as well as the experimental WebGPU renderer.

This minor release includes exciting additions by the growing p5.strands contributor community:

  • filter shaders are supported on 2D sketches, thanks to @LalitNarayanYadav
  • random() and randomSeed() is available in p5.strands code, thanks to @perminder-17
  • map() is available in p5.strands code, thanks to @Nixxx19
  • lerp() and instanceID() are more consistently supported, thanks to @aashu2006
  • more helpful error messages, thanks to @kushal1061
  • corrected TypeScript typing, thanks to @Kathrina-dev
  • simple shader materials can be written much easier, using only finalColor hook thanks to @YuktiNandwana

Here is an example p5.js sketch using p5.strands, with the noise-based texture:

let myShader;
function setup() {
  createCanvas(400, 400, WEBGL);
  myShader = buildMaterialShader(myShaderBuilder);
}
function myShaderBuilder(){
  finalColor.begin();
  let coord = finalColor.texCoord;
  finalColor.set(noise(coord.x, coord.y));
  finalColor.end();
}

function draw() {
  stroke(255);
  background("#f1678e");
  shader(myShader);
  orbitControl();
  box(100);
}
Cloudy cube against a pink background

The p5.strands code has also been refactored and simplified, which will make maintenance and contribution easier in the future, thanks to @davepagurek and @LalitNarayanYadav! Finally, p5.strands, used with the experimental WebGPU renderer, now supports compute shaders, thanks to work by @davepagurek, @aashu2006, and @SOUMITRO-SAHA. For example, below is code for a Game of Life simulation, written by @davepagurek. This uses compute shaders (compare the code to the [non-shader example here(https://beta.p5js.org/examples/math-and-physics-game-of-life/).)

// noprotect
// Authored by Dave Pagurek to demonstrate using WebGPU compute shaders

let cells;
let nextCells;
let gameShader;
let displayShader;
let W = 0;
let H = 0;

async function setup() {
  W = 100;
  H = 100;
  await createCanvas(100, 100, WEBGPU);
  pixelDensity(1);

  let initial = new Float32Array(W * H);
  for (let i = 0; i < initial.length; i++) {
    initial[i] = random() > 0.7 ? 1 : 0;
  }
  cells = createStorage(initial);
  nextCells = createStorage(W * H);

  gameShader = buildComputeShader(simulate);
  displayShader = buildFilterShader(display);
}

function simulate() {
  let current = uniformStorage(() => cells);
  let next = uniformStorage(() => nextCells);
  let w = uniformInt(() => W);
  let h = uniformInt(() => H);
  let x = index.x;
  let y = index.y;

  let n = 0;
  for (let dy = -1; dy <= 1; dy++) {
    for (let dx = -1; dx <= 1; dx++) {
      if (dx != 0 || dy != 0) {
        let nx = (x + dx + w) % w;
        let ny = (y + dy + h) % h;
        n += current[ny * w + nx];
      }
    }
  }

  let alive = current[y * w + x];
  let nextOutput = 0;
  if (alive == 1) {
    if (n == 2 || n == 3) {
      nextOutput = 1;
    }
  } else {
    if (n == 3) {
      nextOutput = 1;
    }
  }
  next[y * w + x] = nextOutput;
}

function display() {
  let data = uniformStorage(() => cells);
  let w = uniformInt(() => W);
  let h = uniformInt(() => H);

  filterColor.begin();
  let x = floor(filterColor.texCoord.x * w);
  let y = floor(filterColor.texCoord.y * h);
  let alive = data[y * w + x];
  filterColor.set([alive, alive, alive, 1]);
  filterColor.end();
}

function draw() {
  compute(gameShader, W, H);
  [nextCells, cells] = [cells, nextCells];
  filter(displayShader);
}

We've also introduced some workflow improvements to support testing new contributions, including the @p5js-bot - look for this comment on any Pull Request, and use the CDN link in test sketches to help with review:

GitHub commend with CDN link

Since RC.1

Since initial release candidate, some refactors and bugfixes have been made to p5.strands:

  • add initial guide working_with_contributor_documents.md by @nbogie in #8627
  • Vector mismatch dimension prints warning message by @limzykenneth in #8821

Find more detailed commits in previous RC release notes

Full Changelog: v2.2.3...v2.3.0-rc.6

v2.3.0-rc.5

21 May 21:11
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

v2.3.0-rc.5 Pre-release
Pre-release

Testers Wanted 💚

This is a release candidate (RC), which means it is not yet live on the p5.js Editor. Please help us to improve the stability of the newest version of p5.js by trying out this release candidate, and reporting bugs.

To help with testing, you can use this starter sketch!

Or load both p5.js and WebGPU mode by adding these two script tags to your sketch:

<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.webgpu.js"></script>

Then load WebGPU mode in createCanvas - note the async/await, this is needed for WebGPU but not WebGL:

async function setup() {
  await createCanvas(400, 400, WEBGPU);
}

What's Changed 🎊

Work since 2.2.3 has focused on graphics and stabilization, including on version p5.Vector. In version 1, it was common to use createVector() which would create a three-dimensional vector at (0, 0, 0). In version 2, empty vectors should be made with createVector(0, 0) or createVector(0, 0, 0), to make clear when it is two or three dimensional. This is because version 2 supports vectors of different dimensions, although usages are still related to graphics and require 3D vectors.

On graphics, we have continued to work on beginner-friendly shader programming API features (p5.strands), as well as the experimental WebGPU renderer.

This minor release includes exciting additions by the growing p5.strands contributor community:

  • filter shaders are supported on 2D sketches, thanks to @LalitNarayanYadav
  • random() and randomSeed() is available in p5.strands code, thanks to @perminder-17
  • map() is available in p5.strands code, thanks to @Nixxx19
  • lerp() and instanceID() are more consistently supported, thanks to @aashu2006
  • more helpful error messages, thanks to @kushal1061
  • corrected TypeScript typing, thanks to @Kathrina-dev
  • simple shader materials can be written much easier, using only finalColor hook thanks to @YuktiNandwana

Here is an example p5.js sketch using p5.strands, with the noise-based texture:

let myShader;
function setup() {
  createCanvas(400, 400, WEBGL);
  myShader = buildMaterialShader(myShaderBuilder);
}
function myShaderBuilder(){
  finalColor.begin();
  let coord = finalColor.texCoord;
  finalColor.set(noise(coord.x, coord.y));
  finalColor.end();
}

function draw() {
  stroke(255);
  background("#f1678e");
  shader(myShader);
  orbitControl();
  box(100);
}
Cloudy cube against a pink background

The p5.strands code has also been refactored and simplified, which will make maintenance and contribution easier in the future, thanks to @davepagurek and @LalitNarayanYadav! Finally, p5.strands, used with the experimental WebGPU renderer, now supports compute shaders, thanks to work by @davepagurek, @aashu2006, and @SOUMITRO-SAHA. For example, below is code for a Game of Life simulation, written by @davepagurek. This uses compute shaders (compare the code to the [non-shader example here(https://beta.p5js.org/examples/math-and-physics-game-of-life/).)

// noprotect
// Authored by Dave Pagurek to demonstrate using WebGPU compute shaders

let cells;
let nextCells;
let gameShader;
let displayShader;
let W = 0;
let H = 0;

async function setup() {
  W = 100;
  H = 100;
  await createCanvas(100, 100, WEBGPU);
  pixelDensity(1);

  let initial = new Float32Array(W * H);
  for (let i = 0; i < initial.length; i++) {
    initial[i] = random() > 0.7 ? 1 : 0;
  }
  cells = createStorage(initial);
  nextCells = createStorage(W * H);

  gameShader = buildComputeShader(simulate);
  displayShader = buildFilterShader(display);
}

function simulate() {
  let current = uniformStorage(() => cells);
  let next = uniformStorage(() => nextCells);
  let w = uniformInt(() => W);
  let h = uniformInt(() => H);
  let x = index.x;
  let y = index.y;

  let n = 0;
  for (let dy = -1; dy <= 1; dy++) {
    for (let dx = -1; dx <= 1; dx++) {
      if (dx != 0 || dy != 0) {
        let nx = (x + dx + w) % w;
        let ny = (y + dy + h) % h;
        n += current[ny * w + nx];
      }
    }
  }

  let alive = current[y * w + x];
  let nextOutput = 0;
  if (alive == 1) {
    if (n == 2 || n == 3) {
      nextOutput = 1;
    }
  } else {
    if (n == 3) {
      nextOutput = 1;
    }
  }
  next[y * w + x] = nextOutput;
}

function display() {
  let data = uniformStorage(() => cells);
  let w = uniformInt(() => W);
  let h = uniformInt(() => H);

  filterColor.begin();
  let x = floor(filterColor.texCoord.x * w);
  let y = floor(filterColor.texCoord.y * h);
  let alive = data[y * w + x];
  filterColor.set([alive, alive, alive, 1]);
  filterColor.end();
}

function draw() {
  compute(gameShader, W, H);
  [nextCells, cells] = [cells, nextCells];
  filter(displayShader);
}

We've also introduced some workflow improvements to support testing new contributions, including the @p5js-bot - look for this comment on any Pull Request, and use the CDN link in test sketches to help with review:

GitHub commend with CDN link

Since RC.1

Since initial release candidate, some refactors and bugfixes have been made to p5.strands:

Find more detailed commits in previous RC release notes

Full Changelog: v2.2.3...v2.3.0-rc.5

v2.3.0-rc.4

15 May 18:33
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

v2.3.0-rc.4 Pre-release
Pre-release

Testers Wanted 💚

This is a release candidate (RC), which means it is not yet live on the p5.js Editor. Please help us to improve the stability of the newest version of p5.js by trying out this release candidate, and reporting bugs.

To help with testing, you can use this starter sketch!

Or load both p5.js and WebGPU mode by adding these two script tags to your sketch:

<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.webgpu.js"></script>

Then load WebGPU mode in createCanvas - note the async/await, this is needed for WebGPU but not WebGL:

async function setup() {
  await createCanvas(400, 400, WEBGPU);
}

What's Changed 🎊

Work since 2.2.3 has focused on graphics and stabilization, including on version p5.Vector. In version 1, it was common to use createVector() which would create a three-dimensional vector at (0, 0, 0). In version 2, empty vectors should be made with createVector(0, 0) or createVector(0, 0, 0), to make clear when it is two or three dimensional. This is because version 2 supports vectors of different dimensions, although usages are still related to graphics and require 3D vectors.

We've also introduced some workflow improvements to support testing new contributions, including the @p5js-bot - look for this comment on any Pull Request, and use the CDN link in test sketches to help with review:

GitHub commend with CDN link

On graphics, we have continued to work on beginner-friendly shader programming API features (p5.strands), as well as the experimental WebGPU renderer.

This minor release includes exciting additions by the growing p5.strands contributor community:

  • filter shaders are supported on 2D sketches, thanks to @LalitNarayanYadav
  • random() and randomSeed() is available in p5.strands code, thanks to @perminder-17
  • map() is available in p5.strands code, thanks to @Nixxx19
  • lerp() and instanceID() are more consistently supported, thanks to @aashu2006
  • more helpful error messages, thanks to @kushal1061
  • corrected TypeScript typing, thanks to @Kathrina-dev
  • simple shader materials can be written much easier, using only finalColor hook thanks to @YuktiNandwana

Here is an example p5.js sketch using p5.strands, with the noise-based texture:

let myShader;
function setup() {
  createCanvas(400, 400, WEBGL);
  myShader = buildMaterialShader(myShaderBuilder);
}
function myShaderBuilder(){
  finalColor.begin();
  let coord = finalColor.texCoord;
  finalColor.set(noise(coord.x, coord.y));
  finalColor.end();
}

function draw() {
  stroke(255);
  background("#f1678e");
  shader(myShader);
  orbitControl();
  box(100);
}
Cloudy cube against a pink background

The p5.strands code has also been refactored and simplified, which will make maintenance and contribution easier in the future, thanks to @davepagurek and @LalitNarayanYadav! Finally, p5.strands, used with the experimental WebGPU renderer, now supports compute shaders, thanks to work by @davepagurek, @aashu2006, and @SOUMITRO-SAHA. For example, below is code for a Game of Life simulation, written by @davepagurek. This uses compute shaders (compare the code to the [non-shader example here(https://beta.p5js.org/examples/math-and-physics-game-of-life/).)

// noprotect
// Authored by Dave Pagurek to demonstrate using WebGPU compute shaders

let cells;
let nextCells;
let gameShader;
let displayShader;
let W = 0;
let H = 0;

async function setup() {
  W = 100;
  H = 100;
  await createCanvas(100, 100, WEBGPU);
  pixelDensity(1);

  let initial = new Float32Array(W * H);
  for (let i = 0; i < initial.length; i++) {
    initial[i] = random() > 0.7 ? 1 : 0;
  }
  cells = createStorage(initial);
  nextCells = createStorage(W * H);

  gameShader = buildComputeShader(simulate);
  displayShader = buildFilterShader(display);
}

function simulate() {
  let current = uniformStorage(() => cells);
  let next = uniformStorage(() => nextCells);
  let w = uniformInt(() => W);
  let h = uniformInt(() => H);
  let x = index.x;
  let y = index.y;

  let n = 0;
  for (let dy = -1; dy <= 1; dy++) {
    for (let dx = -1; dx <= 1; dx++) {
      if (dx != 0 || dy != 0) {
        let nx = (x + dx + w) % w;
        let ny = (y + dy + h) % h;
        n += current[ny * w + nx];
      }
    }
  }

  let alive = current[y * w + x];
  let nextOutput = 0;
  if (alive == 1) {
    if (n == 2 || n == 3) {
      nextOutput = 1;
    }
  } else {
    if (n == 3) {
      nextOutput = 1;
    }
  }
  next[y * w + x] = nextOutput;
}

function display() {
  let data = uniformStorage(() => cells);
  let w = uniformInt(() => W);
  let h = uniformInt(() => H);

  filterColor.begin();
  let x = floor(filterColor.texCoord.x * w);
  let y = floor(filterColor.texCoord.y * h);
  let alive = data[y * w + x];
  filterColor.set([alive, alive, alive, 1]);
  filterColor.end();
}

function draw() {
  compute(gameShader, W, H);
  [nextCells, cells] = [cells, nextCells];
  filter(displayShader);
}

Since RC.1

Since initial release candidate, some refactors and bugfixes have been made to p5.strands:

Find more detailed commits in previous RC release notes

Full Changelog: v2.3.0-rc.3...v2.3.0-rc.4

v2.3.0-rc.3

12 May 20:27
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

v2.3.0-rc.3 Pre-release
Pre-release

Testers Wanted 💚

This is a release candidate (RC), which means it is not yet live on the p5.js Editor. Please help us to improve the stability of the newest version of p5.js by trying out this release candidate, and reporting bugs.

To help with testing, you can use this starter sketch!

Or load both p5.js and WebGPU mode by adding these two script tags to your sketch:

<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.webgpu.js"></script>

Then load WebGPU mode in createCanvas - note the async/await, this is needed for WebGPU but not WebGL:

async function setup() {
  await createCanvas(400, 400, WEBGPU);
}

What's Changed 🎊

Work since 2.2.3 has focused on graphics and stabilization, including on version p5.Vector. In version 1, it was common to use createVector() which would create a three-dimensional vector at (0, 0, 0). In version 2, empty vectors should be made with createVector(0, 0) or createVector(0, 0, 0), to make clear when it is two or three dimensional. This is because version 2 supports vectors of different dimensions, although usages are still related to graphics and require 3D vectors.

We've also introduced some workflow improvements to support testing new contributions, including the @p5js-bot - look for this comment on any Pull Request, and use the CDN link in test sketches to help with review:

GitHub commend with CDN link

On graphics, we have continued to work on beginner-friendly shader programming API features (p5.strands), as well as the experimental WebGPU renderer.

This minor release includes exciting additions by the growing p5.strands contributor community:

  • filter shaders are supported on 2D sketches, thanks to @LalitNarayanYadav
  • random() and randomSeed() is available in p5.strands code, thanks to @perminder-17
  • map() is available in p5.strands code, thanks to @Nixxx19
  • lerp() and instanceID() are more consistently supported, thanks to @aashu2006
  • more helpful error messages, thanks to @kushal1061
  • corrected TypeScript typing, thanks to @Kathrina-dev
  • simple shader materials can be written much easier, using only finalColor hook thanks to @YuktiNandwana

Here is an example p5.js sketch using p5.strands, with the noise-based texture:

let myShader;
function setup() {
  createCanvas(400, 400, WEBGL);
  myShader = buildMaterialShader(myShaderBuilder);
}
function myShaderBuilder(){
  finalColor.begin();
  let coord = finalColor.texCoord;
  finalColor.set(noise(coord.x, coord.y));
  finalColor.end();
}

function draw() {
  stroke(255);
  background("#f1678e");
  shader(myShader);
  orbitControl();
  box(100);
}
Cloudy cube against a pink background

The p5.strands code has also been refactored and simplified, which will make maintenance and contribution easier in the future, thanks to @davepagurek and @LalitNarayanYadav! Finally, p5.strands, used with the experimental WebGPU renderer, now supports compute shaders, thanks to work by @davepagurek, @aashu2006, and @SOUMITRO-SAHA. For example, below is code for a Game of Life simulation, written by @davepagurek. This uses compute shaders (compare the code to the [non-shader example here(https://beta.p5js.org/examples/math-and-physics-game-of-life/).)

// noprotect
// Authored by Dave Pagurek to demonstrate using WebGPU compute shaders

let cells;
let nextCells;
let gameShader;
let displayShader;
let W = 0;
let H = 0;

async function setup() {
  W = 100;
  H = 100;
  await createCanvas(100, 100, WEBGPU);
  pixelDensity(1);

  let initial = new Float32Array(W * H);
  for (let i = 0; i < initial.length; i++) {
    initial[i] = random() > 0.7 ? 1 : 0;
  }
  cells = createStorage(initial);
  nextCells = createStorage(W * H);

  gameShader = buildComputeShader(simulate);
  displayShader = buildFilterShader(display);
}

function simulate() {
  let current = uniformStorage(() => cells);
  let next = uniformStorage(() => nextCells);
  let w = uniformInt(() => W);
  let h = uniformInt(() => H);
  let x = index.x;
  let y = index.y;

  let n = 0;
  for (let dy = -1; dy <= 1; dy++) {
    for (let dx = -1; dx <= 1; dx++) {
      if (dx != 0 || dy != 0) {
        let nx = (x + dx + w) % w;
        let ny = (y + dy + h) % h;
        n += current[ny * w + nx];
      }
    }
  }

  let alive = current[y * w + x];
  let nextOutput = 0;
  if (alive == 1) {
    if (n == 2 || n == 3) {
      nextOutput = 1;
    }
  } else {
    if (n == 3) {
      nextOutput = 1;
    }
  }
  next[y * w + x] = nextOutput;
}

function display() {
  let data = uniformStorage(() => cells);
  let w = uniformInt(() => W);
  let h = uniformInt(() => H);

  filterColor.begin();
  let x = floor(filterColor.texCoord.x * w);
  let y = floor(filterColor.texCoord.y * h);
  let alive = data[y * w + x];
  filterColor.set([alive, alive, alive, 1]);
  filterColor.end();
}

function draw() {
  compute(gameShader, W, H);
  [nextCells, cells] = [cells, nextCells];
  filter(displayShader);
}

Since RC.1

Since previous release candidate, some refactors and bugfixes have been made to p5.strands:

Find more detailed commits in previous RC release notes

New Contributors

Full Changelog: v2.3.0-rc.2...v2.3.0-rc.3

v2.3.0-rc.2

12 May 18:04
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

v2.3.0-rc.2 Pre-release
Pre-release

What's Changed

This is a release candidate (RC), which means it is not yet live on the p5.js Editor. Please help us to improve the stability of the newest version of p5.js by trying out this release candidate, and reporting bugs.

To help with testing, you can use this starter sketch!

Or load both p5.js and WebGPU mode by adding these two script tags to your sketch:

<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.webgpu.js"></script>

Then load WebGPU mode in createCanvas - note the async/await, this is needed for WebGPU but not WebGL:

async function setup() {
  await createCanvas(400, 400, WEBGPU);
}

What's Changed 🎊

Work since 2.2.3 has focused on graphics and stabilization, including on version p5.Vector. In version 1, it was common to use createVector() which would create a three-dimensional vector at (0, 0, 0). In version 2, empty vectors should be made with createVector(0, 0) or createVector(0, 0, 0), to make clear when it is two or three dimensional. This is because version 2 supports vectors of different dimensions, although usages are still related to graphics and require 3D vectors.

We've also introduced some workflow improvements to support testing new contributions, including the @p5js-bot - look for this comment on any Pull Request, and use the CDN link in test sketches to help with review:

GitHub commend with CDN link

On graphics, we have continued to work on beginner-friendly shader programming API features (p5.strands), as well as the experimental WebGPU renderer.

This minor release includes exciting additions by the growing p5.strands contributor community:

  • filter shaders are supported on 2D sketches, thanks to @LalitNarayanYadav
  • random() and randomSeed() is available in p5.strands code, thanks to @perminder-17
  • map() is available in p5.strands code, thanks to @Nixxx19
  • lerp() and instanceID() are more consistently supported, thanks to @aashu2006
  • more helpful error messages, thanks to @kushal1061
  • corrected TypeScript typing, thanks to @Kathrina-dev
  • simple shader materials can be written much easier, using only finalColor hook thanks to @YuktiNandwana

Here is an example p5.js sketch using p5.strands, with the noise-based texture:

let myShader;
function setup() {
  createCanvas(400, 400, WEBGL);
  myShader = buildMaterialShader(myShaderBuilder);
}
function myShaderBuilder(){
  finalColor.begin();
  let coord = finalColor.texCoord;
  finalColor.set(noise(coord.x, coord.y));
  finalColor.end();
}

function draw() {
  stroke(255);
  background("#f1678e");
  shader(myShader);
  orbitControl();
  box(100);
}
Cloudy cube against a pink background

The p5.strands code has also been refactored and simplified, which will make maintenance and contribution easier in the future, thanks to @davepagurek and @LalitNarayanYadav! Finally, p5.strands, used with the experimental WebGPU renderer, now supports compute shaders, thanks to @davepagurek and @aashu2006. For example, below is code for a Game of Life simulation, written by @davepagurek. This uses compute shaders (compare the code to the [non-shader example here(https://beta.p5js.org/examples/math-and-physics-game-of-life/).)

// noprotect
// Authored by Dave Pagurek to demonstrate an WebGPU compute shaders

let cells;
let nextCells;
let gameShader;
let displayShader;
let W = 0;
let H = 0;

async function setup() {
  W = 100;
  H = 100;
  await createCanvas(100, 100, WEBGPU);
  pixelDensity(1);

  let initial = new Float32Array(W * H);
  for (let i = 0; i < initial.length; i++) {
    initial[i] = random() > 0.7 ? 1 : 0;
  }
  cells = createStorage(initial);
  nextCells = createStorage(W * H);

  gameShader = buildComputeShader(simulate);
  displayShader = buildFilterShader(display);
}

function simulate() {
  let current = uniformStorage(() => cells);
  let next = uniformStorage(() => nextCells);
  let w = uniformInt(() => W);
  let h = uniformInt(() => H);
  let x = index.x;
  let y = index.y;

  let n = 0;
  for (let dy = -1; dy <= 1; dy++) {
    for (let dx = -1; dx <= 1; dx++) {
      if (dx != 0 || dy != 0) {
        let nx = (x + dx + w) % w;
        let ny = (y + dy + h) % h;
        n += current[ny * w + nx];
      }
    }
  }

  let alive = current[y * w + x];
  let nextOutput = 0;
  if (alive == 1) {
    if (n == 2 || n == 3) {
      nextOutput = 1;
    }
  } else {
    if (n == 3) {
      nextOutput = 1;
    }
  }
  next[y * w + x] = nextOutput;
}

function display() {
  let data = uniformStorage(() => cells);
  let w = uniformInt(() => W);
  let h = uniformInt(() => H);

  filterColor.begin();
  let x = floor(filterColor.texCoord.x * w);
  let y = floor(filterColor.texCoord.y * h);
  let alive = data[y * w + x];
  filterColor.set([alive, alive, alive, 1]);
  filterColor.end();
}

function draw() {
  compute(gameShader, W, H);
  [nextCells, cells] = [cells, nextCells];
  filter(displayShader);
}

Since RC.1

Since previous release candidate, some refactors and bugfixes have been made to p5.strands:

  • Refactor: Extract transpilation passes and callback generation from transpileStrandsToJS by @LalitNarayanYadav in #8782
  • Make sure all p5.strands math operators are converted to strands nodes by @davepagurek in #8785
  • Make line shader hooks use unmultiplied alpha by @davepagurek in #8787

Find more detailed commits in previous RC release notes

Full Changelog: v2.3.0-rc.1...v2.3.0-rc.2

v2.3.0-rc.1

11 May 16:01
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

v2.3.0-rc.1 Pre-release
Pre-release

Testers Wanted 💚

This is a release candidate (RC), which means it is not yet live on the p5.js Editor. Please help us to improve the stability of the newest version of p5.js by trying out this release candidate, and reporting bugs.

To help with testing, you can use this starter sketch!

Or load both p5.js and WebGPU mode by adding these two script tags to your sketch:

<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.webgpu.js"></script>

Then load WebGPU mode in createCanvas - note the async/await, this is needed for WebGPU but not WebGL:

async function setup() {
  await createCanvas(400, 400, WEBGPU);
}

What's Changed 🎊

Work since 2.2.3 has focused on graphics and stabilization, including on version p5.Vector. In version 1, it was common to use createVector() which would create a three-dimensional vector at (0, 0, 0). In version 2, empty vectors should be made with createVector(0, 0) or createVector(0, 0, 0), to make clear when it is two or three dimensional. This is because version 2 supports vectors of different dimensions, although usages are still related to graphics and require 3D vectors.

We've also introduced some workflow improvements to support testing new contributions, including the @p5js-bot - look for this comment on any Pull Request, and use the CDN link in test sketches to help with review:

GitHub commend with CDN link

On graphics, we have continued to work on beginner-friendly shader programming API features (p5.strands), as well as the experimental WebGPU renderer.

This minor release includes exciting additions by the growing p5.strands contributor community:

  • filter shaders are supported on 2D sketches, thanks to @LalitNarayanYadav
  • random() and randomSeed() is available in p5.strands code, thanks to @perminder-17
  • map() is available in p5.strands code, thanks to @Nixxx19
  • lerp() and instandceID() are more consistently supported, thanks to @aashu2006
  • more helpful error messages, thanks to @kushal1061
  • corrected TypeScript typing, thanks to @Kathrina-dev
  • simple shader materials can be written much easier, using only finalColor hook thanks to @YuktiNandwana

Here is an example p5.js sketch using p5.strands, with the noise-based texture:

let myShader;
function setup() {
  createCanvas(400, 400, WEBGL);
  myShader = buildMaterialShader(myShaderBuilder);
}
function myShaderBuilder(){
  finalColor.begin();
  let coord = finalColor.texCoord;
  finalColor.set(noise(coord.x, coord.y));
  finalColor.end();
}

function draw() {
  stroke(255);
  background("#f1678e");
  shader(myShader);
  orbitControl();
  box(100);
}
Cloudy cube against a pink background

The p5.strands code has also been refactored and simplified, which will make maintenance and contribution easier in the future, thanks to @davepagurek and @LalitNarayanYadav! Finally, p5.strands, used with the experimental WebGPU renderer, now supports compute shaders, thanks to @davepagurek and @aashu2006. For example, below is code for a Game of Life simulation, written by @davepagurek. This uses compute shaders (compare the code to the [non-shader example here(https://beta.p5js.org/examples/math-and-physics-game-of-life/).)

// noprotect
// Authored by Dave Pagurek to demonstrate an WebGPU compute shaders

let cells;
let nextCells;
let gameShader;
let displayShader;
let W = 0;
let H = 0;

async function setup() {
  W = 100;
  H = 100;
  await createCanvas(100, 100, WEBGPU);
  pixelDensity(1);

  let initial = new Float32Array(W * H);
  for (let i = 0; i < initial.length; i++) {
    initial[i] = random() > 0.7 ? 1 : 0;
  }
  cells = createStorage(initial);
  nextCells = createStorage(W * H);

  gameShader = buildComputeShader(simulate);
  displayShader = buildFilterShader(display);
}

function simulate() {
  let current = uniformStorage(() => cells);
  let next = uniformStorage(() => nextCells);
  let w = uniformInt(() => W);
  let h = uniformInt(() => H);
  let x = index.x;
  let y = index.y;

  let n = 0;
  for (let dy = -1; dy <= 1; dy++) {
    for (let dx = -1; dx <= 1; dx++) {
      if (dx != 0 || dy != 0) {
        let nx = (x + dx + w) % w;
        let ny = (y + dy + h) % h;
        n += current[ny * w + nx];
      }
    }
  }

  let alive = current[y * w + x];
  let nextOutput = 0;
  if (alive == 1) {
    if (n == 2 || n == 3) {
      nextOutput = 1;
    }
  } else {
    if (n == 3) {
      nextOutput = 1;
    }
  }
  next[y * w + x] = nextOutput;
}

function display() {
  let data = uniformStorage(() => cells);
  let w = uniformInt(() => W);
  let h = uniformInt(() => H);

  filterColor.begin();
  let x = floor(filterColor.texCoord.x * w);
  let y = floor(filterColor.texCoord.y * h);
  let alive = data[y * w + x];
  filterColor.set([alive, alive, alive, 1]);
  filterColor.end();
}

function draw() {
  compute(gameShader, W, H);
  [nextCells, cells] = [cells, nextCells];
  filter(displayShader);
}

p5.strands and WebGPU

Workflow and Stabilization

Documentation and Friendly Errors

  • Docs: Add pipeline overview for transpileS...
Read more

v1.11.14-rc.0

04 May 19:39
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

v1.11.14-rc.0 Pre-release
Pre-release

What's Changed

This is a release candidate (RC), which means it is not yet live on the p5.js Editor. Please help us to improve the stability of the newest version of p5.js by trying out this release candidate, and reporting bugs. To test this patch, you can use this starter sketch.

<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.js"></script>

Code updates

  • fix: prevent browser freeze when tessellating >50k vertices (#8219 ) by @Nixxx19 in #8555

Workflow updates

Documentation updates

New Contributors

Full Changelog: v1.11.13...v1.11.14-rc.0

v1.11.13

08 Apr 16:07

Choose a tag to compare

What's Changed

This patch addresses the recent regression in point positioning.

What's Changed 🎊

  • Update Node.js version from 20 to 22 in workflow by @ksen0 in #8686
  • Add kitlord to stewards.yml with p5.js-web-editor by @ksen0 in #8687
  • chore: update README table from stewards.yml by @p5js-bot in #8688
  • Revise p5.js 2.0 Bug Report template by @ksen0 in #8692
  • fix point() origin bug and stale per-vertex color leak by @perminder-17 in #8712

Full Changelog: v1.11.12...v1.11.13

v1.11.13-rc.0

08 Apr 12:49

Choose a tag to compare

v1.11.13-rc.0 Pre-release
Pre-release

What's Changed

This patch addresses the recent regression in point positioning.

What's Changed 🎊

  • Update Node.js version from 20 to 22 in workflow by @ksen0 in #8686
  • Add kitlord to stewards.yml with p5.js-web-editor by @ksen0 in #8687
  • chore: update README table from stewards.yml by @p5js-bot in #8688
  • Revise p5.js 2.0 Bug Report template by @ksen0 in #8692
  • fix point() origin bug and stale per-vertex color leak by @perminder-17 in #8712

Full Changelog: v1.11.12...v1.11.13-rc.0