I 3D printed a “saturn-like” planet totem and it turned out great!
Here’s a video: https://www.youtube.com/watch?v=XR7h_hy_Yc8
Most of the classic patterns like honeycomb run at ~40 fps, which is perfectly fine IMO.
However, when I get fancy and start adding color palettes with @jeff 's fancy shimmer transitions, the fps drops down to around ~19 fps.
Here’s a rundown on my project:
- Single Pixelblaze pico v3 (v3.51)
- 719 pebble style leds: 5V WS2811 15mm pitch leds on aliexpress
- It’s using a custom 3D map I created in blender
I’m looking for suggestions on increasing the frame rate.
- Would a standard pixelblaze give better results than the pico?
Here’s an example I setup:
Wavy Bands (without palettes): 31 fps
Wavy Bands with palettes: 19 fps
Here’s @zranger1 's Wavy Bands pattern with my added palette code:
// Wavy Bands
//
// Requires a correctly configured 2D map
//
// MIT License - use this code to make more cool things!
//
// 6/22/2023 ZRanger1
// Added color palettes and some more controls
// 1/19/2024 dylan.conlin
// Global variables
var timebase = 0; // Time accumulator for animation control
export var nColumns = 4; // Number of displayed columns
// Speed variables with default values
export var xSpeed = 3.25; // Speed of x-axis wave movement
export var ySpeed = 5.18; // Speed of y-axis width variation
var tx, ty
// toggling this to true will enable the slider for column count
var adaptiveColumnCount = false;
// Parameter names that correspond to Pixelblaze UI controls
var shimmer = true;
export var transition = 0.15;
var secondsPerPalette = 8;
// Internal state variables
var paletteIndex;
var lastPaletteIndex = -1;
export function sliderColumns(v) {
nColumns = mapRange(v, 1, 10);
}
export function sliderXSpeed(v) {
xSpeed = mapRange(v, 1, 10);
}
export function sliderYSpeed(v) {
ySpeed = mapRange(v, 1, 10);
}
export function sliderTransitionTime(v) {
transition = mapRange(v, 0.10, 3.0);
}
// enable/disable column count based on palette
export function toggleAdaptiveColumnCount(v) {
adaptiveColumnCount = v;
}
export function toggleShimmer(v) {
shimmer = v;
}
export function inputNumberSecondsPerPalette(v) {
secondsPerPalette = v;
}
export function showNumberPalette() {
return paletteIndex;
}
function mapRange(value, min, max) {
return min + (max - min) * value;
}
// Functions to handle transitions between color palettes
function handlePaletteTransitions() {
paletteIndex = time(secondsPerPalette / 65.536 * palettes.length) * palettes.length;
applyShimmerEffect();
updatePaletteIfChanged();
}
function applyShimmerEffect() {
if (frac(paletteIndex) > (1 - transition)) {
var transitionFactor = (frac(paletteIndex) - (1 - transition)) / transition;
if (shimmer && wave(transitionFactor / 2 - 0.25) > random(1)) {
paletteIndex = mod(paletteIndex + 1, palettes.length);
}
}
}
function updatePaletteIfChanged() {
var floorPaletteIndex = floor(paletteIndex);
if (floorPaletteIndex !== lastPaletteIndex) {
setPalette(palettes[floorPaletteIndex]);
if (adaptiveColumnCount) {
nColumns = palettes[floorPaletteIndex].length / 4;
}
lastPaletteIndex = floorPaletteIndex;
}
}
// Function called before each frame render. Calculates time-based variables
// for animation.
export function beforeRender(delta) {
// Accumulate time with loop around 3600 seconds for continuous animation
timebase = (timebase + delta / 1000) % 3600;
// Calculate speeds for x and y axis movements based on slider inputs
tx = -timebase / xSpeed; // Speed of x-axis movement, negative for reverse direction
ty = timebase / ySpeed; // Speed of y-axis movement
}
// Render function for 2D LED matrices. Creates wavy column patterns.
export function render2D(index, x, y) {
handlePaletteTransitions(); // Manage transitions between color palettes
// Apply transformations to x and y coordinates for wave effects
y -= 0.3 * perlin(x * 2, y * 2, ty, 1.618);
x += 0.1752 * sin(4 * (tx + y));
// Quantize x-coordinate into columns and determine brightness
var column = floor(x * nColumns);
var brightness = (x * nColumns - 0.5);
brightness = 1 - (2 * abs(brightness - column));
brightness = pow(brightness, 1.25); // Apply gamma correction for brightness
var hue = column / nColumns; // Determine hue based on column position
paint(hue, brightness); // Paint the pixel with calculated hue and brightness
}
// Function to project 2D pattern into 3D space.
export function render3D(index, x, y, z) {
var x1 = (x - cos(z / 4 * PI2)) / 2;
var y1 = (y - sin(z / 4 * PI2)) / 2;
render2D(index, x1, y1);
}
var lava = [0.0, 68/255, 1/255, 84/255, 0.18, 0.071, 0.0, 0.0, 0.376, 0.443, 0.0, 0.0, 0.424, 0.557, 0.012, 0.004, 0.467, 0.686, 0.067, 0.004, 0.573, 0.835, 0.173, 0.008, 0.682, 1.0, 0.322, 0.016, 0.737, 1.0, 0.451, 0.016, 0.792, 1.0, 0.612, 0.016, 0.855, 1.0, 0.796, 0.016, 0.918, 1.0, 1.0, 0.016, 0.957, 1.0, 1.0, 0.278, 1.0, 1.0, 1.0, 1.0,];
var ib_jul01 = [0.0, 0.761, 0.004, 0.004, 0.369, 0.004, 0.114, 0.071, 0.518, 0.224, 0.514, 0.11, 1.0, 0.443, 0.004, 0.004,];
var palettes = [
lava,
ib_jul01,
]