2.3.0: New features from the growing p5.strands contributor community π±
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:
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).
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()andrandomSeed()is available in p5.strands code, thanks to @perminder-17map()is available in p5.strands code, thanks to @Nixxx19lerp()andinstanceID()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
finalColorhook 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);
}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
- Fix: restore lerp alias to GLSL mix in p5.strands by @aashu2006 in #8681
- Ternary support for p5.strands by @davepagurek in #8638
- Make instanceID() work in both vertex and fragment shaders by @aashu2006 in #8695
- Make sure we don't transpile uniform callbacks by @davepagurek in #8709
- Auto-spread large WebGPU compute dispatches by @aashu2006 in #8696
- WebGPU compute shaders by @davepagurek in #8531
- Fix: Add filterColor alias support for 2D filter shaders by @LalitNarayanYadav in #8699
- Fix swizzle assignment for array element properties in compute shaders by @davepagurek in #8724
- Minor WebGL->WebGPU fixes by @davepagurek in #8731
- Fix TypeScript typing for filterColor shader hook by @Kathrina-dev in #8644
- Refactor: Deduplicate BinaryExpression and LogicalExpression transformation logic by @LalitNarayanYadav in #8741
- feat(webgpu): add read() to p5.StorageBuffer with tests by @aashu2006 in #8726
- Refactor: Move getNoiseShaderSnippet to strands backend by @LalitNarayanYadav in #8705
- implementing random function for strands by @perminder-17 in #8730
- added productive error when loop protection breaks in p5.strands by @kushal1061 in #8725
- Add StorageBuffer.set(index, value) for single-element GPU updates by @aashu2006 in #8772
- support map() inside p5.strands shaders by @Nixxx19 in #8753
- Refactor: Extract shared addCopyingAndReturn helper for control flow transformations by @LalitNarayanYadav in #8754
- Refactor: Extract replaceIdentifierReferences and remove reliance on
thisin ASTCallbacks by @LalitNarayanYadav in #8728 - feat(webgl): add texCoord parameter to getFinalColor hook by @YuktiNandwana in #8706
- Fix/feedback by @davepagurek in #8704
- 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
- Handle null tint in Renderer3D by @davepagurek in #8815
- Make line shader hooks use unmultiplied alpha by @davepagurek in #8787
- Fix #8756: Allow computed array indexing on non-storage vectors by @SOUMITRO-SAHA in #8768
- Fix p5.strands hook params clashing with user uniform names by @davepagurek in #8793
- Add shader examples to noise random and millis functions by @SOUMITRO-SAHA in #8803
Workflow and Stabilization
- Continuous release with pkg.pr.new and esm.sh by @limzykenneth in #8603
- harden github actions by @perminder-17 in #8650
- Resolves #8278 by @dhowe in #8328
- Revise p5.js 2.0 Beta Bug Report template by @ksen0 in #8693
- Add ShapePrimitive support for arcs and ellipses by @VANSH3104 in #8617
- fix: allow setup() to return Promise for async workflows by @LalitNarayanYadav in #8700
- fix: gracefully handle mixed-material OBJ models instead of crashing by @Nixxx19 in #8666
- Use more circular rounding for WebGL rect corners by @davepagurek in #8743
- Save + restore 2D text canvas context when font is applied in WebGL mode by @davepagurek in #8747
- Remove canvas style attribute update when changing font weight by @davepagurek in #8733
- fix: prevent browser freeze when tessellating >50k vertices (dev-2.0) by @Nixxx19 in #8729
- Fixes for server side usage by @limzykenneth in #8357
- Make default sketch canvas ID autoincrement by @limzykenneth in #7836
- Don't use push(...arr) in GeometryBuilder for long vertex arrays by @davepagurek in #8789
- Fixes for filters on p5.Graphics by @davepagurek in #8792
Documentation and Friendly Errors
- Docs: Add pipeline overview for transpileStrandsToJS by @LalitNarayanYadav in #8755
- Reference example typo fix by @limzykenneth in #8680
- docs: fix typos and grammar in contributor docs by @Xavrir in #8654
- lf use min() and max() with Infinity or -Infinity, it throws friendly error by @menacingly-coded in #8389
- Update vector docs to indicate recommended usage by @ksen0 in #8783
- remove unused
@requiresfrom all jsdoc by @nbogie in #8713 - Update RendererGL comments to reflect current state of pixel functions by @davepagurek in #8738
- docs: remove broken beginGeometry/endGeometry links from buildGeometry reference by @mitre88 in #8739
- Fix JSDoc typos: widhts β widths, coordniates β coordinates, coordianβ¦ by @harshiltewari2004 in #8757
- Fix: restrict setHeading() to 2D vectors and add friendly error for others by @reshma045 in #8255
- States tests and rename by @harshiltewari2004 in #8778
- Match workflows, top level docs, and stewards to main by @ksen0 in #8760
- Fixing the refernece for p5.js-website by @perminder-17 in #8816
- add initial guide working_with_contributor_documents.md by @nbogie in #8627
- docs: add iframe accessible name guidance to style guide by @Xavrir in #8653
- docs: add documentation for mix() method in p5.strands by @Anshumancanrock in #8463
- adding-missing-doubleClicked-handler by @perminder-17 in #8799
Vectors Refactor and Documentation Updates
- Refactor p5.Vector to prioritize smaller dimension in binary operations on mismatched-size vectors by @ksen0 in #8676
- Correct set() documentation by @ksen0 in #8838
- Restore FES warnings in createVector via this.constructor._friendlyError by @perminder-17 in #8829
- Vector mismatch dimension prints warning message by @limzykenneth in #8821
- p5.Vector perf updates by @davepagurek in #8809
New Contributors
- @Xavrir made their first contribution in #8654
- @YuktiNandwana made their first contribution in #8706
- @Kathrina-dev made their first contribution in #8644
- @mitre88 made their first contribution in #8739
- @kushal1061 made their first contribution in #8725
- @SOUMITRO-SAHA made their first contribution in #8768
Thanks to all contributors and stewards who made this release possible!
Full Changelog: v2.2.3...v2.3.0
