I’ve remembered there’s another performance trick to handle p5js Uint8ClampedArray pixels[]:
Create a 32-bit array view for it, like Int32Array or Uint32Array, like this sketch I did a long time ago:
So for your example below:
Rather than assigning to 4 RGBa separate indices [i], [i+1], [i+2] and [i+3].
We instead create 1 32-bit aBGR color and assign it to just the index [i]:
"use strict";
/**
* 32-bit Look-Up Table (LUT) for all 256 opaque gray colors
*/
const GRAY_LUT = Int32Array.from({ length: 256 },
(_, gray) => 0xFF000000 | gray << 0o20 | gray << 0o10 | gray
);
/**
* 32-bit array view for the p5js Uint8ClampedArray pixels[]
* @type {Int32Array}
*/
var pix32View;
/**
* Cached p5js gray color
*/
var bg;
function setup() {
createCanvas(1024, 640);
pixelDensity(1).loadPixels();
frameRate(60).textSize(20).fill("yellow");
pix32View = new Int32Array(pixels.buffer);
bg = color(200);
}
function draw() {
background(bg);
var timer = millis();
const { width, height } = this;
for (var y = 0; y < height; ++y) {
const yw = y * width;
for (var x = 0; x < width; ++x) {
const idx = yw + x, gray = idx % GRAY_LUT.length;
pix32View[idx] = GRAY_LUT[gray];
}
}
updatePixels();
timer = millis() - timer;
const hud = timer.toFixed(2) + '\t' + (1000 / timer).toFixed(2);
text(hud, 5, height - 5);
}
The example above caches all 256 opaque shades of gray as Int32Array GRAY_LUT.
But for a regular p5.Color, you can use this callback w/ method reduce() over the { levels } = color(r, g, b) array:
function RGBa_Arr_to_aBGR_32bit_Val(acc, val, idx) { // .reduce() callback
return val << idx * 0o10 | acc;
}
const { levels } = color(200, 100, 50);
const abgrValue = levels.reduce(RGBa_Arr_to_aBGR_32bit_Val, 0);