From f566d3bac6496cde0f39d4bcc2d7fb0dbf0cfd46 Mon Sep 17 00:00:00 2001 From: Rui Fonseca <804752+ruifonseca@users.noreply.github.com> Date: Sat, 20 Dec 2025 18:26:18 +0000 Subject: [PATCH 1/7] actor fills a color array and sends it back --- examples/aurora.psh | 56 ++++++++++++++++----------------------------- 1 file changed, 20 insertions(+), 36 deletions(-) diff --git a/examples/aurora.psh b/examples/aurora.psh index 2f889c9..6b5d5f9 100644 --- a/examples/aurora.psh +++ b/examples/aurora.psh @@ -1,4 +1,4 @@ -// Mandelbrot Set Explorer +// Mandelbrot Set Explorer II // This example builds on mandelbrot.psh. // Differences: @@ -22,21 +22,6 @@ let IM_END = 1.125; let MAX_ITER = 60; let NTHREADS = 16; -// Distribute rows to hand to actors -fun calc_boundaries() { - let chunk_size = HEIGHT _/ NTHREADS; - let rem = HEIGHT % NTHREADS; - let var limit = 0; - - let boundaries = []; - for (let var i=0; i> 32; - frame_buffer.set_u32(idx, color); } // print render time From 0fa37a35e1e78781f88d3bd0e9c813828df1b029 Mon Sep 17 00:00:00 2001 From: Rui Fonseca <804752+ruifonseca@users.noreply.github.com> Date: Sat, 20 Dec 2025 18:29:02 +0000 Subject: [PATCH 2/7] format expression --- examples/aurora.psh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/aurora.psh b/examples/aurora.psh index 6b5d5f9..5f0ec61 100644 --- a/examples/aurora.psh +++ b/examples/aurora.psh @@ -93,7 +93,7 @@ loop { let colors = msg[1]; let from = actor_boundaries[actor_id]; - frame_buffer.memcpy(from*WIDTH*4, colors, 0, colors.len); + frame_buffer.memcpy(from * WIDTH * 4, colors, 0, colors.len); if (++completed == NTHREADS) { break; } From 271417967cbbf80ffa57ce45e7723327de258944 Mon Sep 17 00:00:00 2001 From: Rui Fonseca <804752+ruifonseca@users.noreply.github.com> Date: Mon, 22 Dec 2025 20:02:58 +0000 Subject: [PATCH 3/7] purple experiment --- examples/aurora.psh | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/examples/aurora.psh b/examples/aurora.psh index 5f0ec61..ee210f5 100644 --- a/examples/aurora.psh +++ b/examples/aurora.psh @@ -27,11 +27,17 @@ fun rgb32(r, g, b) { return 0xFF_00_00_00 | (r << 16) | (g << 8) | b; } -// Create a simple green aurora borealis color palette. -// Go from rgb(21, 53, 72) to rgb(153, 233, 180) in 7 steps. +// Create an aurora borealis color palette. +// Interpolate from (1, 239, 172) to (95, 42, 132), +// but not for every iteration. A fifth of MAX_ITER +// is purely empirical - let palette = []; -for (let var i = 0; i < 7; ++i) { - palette.push(rgb32(21+i*22, 53+i*30, 72+i*18)); +for (let var i = 0; i < MAX_ITER _/ 5; ++i) { + let t = i / ( MAX_ITER _/ 5); + let r = ( 1 + ( 95 - 1) * t).floor(); + let g = (239 + ( 42 - 239) * t).floor(); + let b = (172 + (132 - 172) * t).floor(); + palette.push(rgb32(r, g, b)); } // Check if a point is in the Mandelbrot set in max_iter steps @@ -62,7 +68,7 @@ fun colorizer(from, to) { let iter = fugue(c_re, c_im, MAX_ITER); // Set the pixel color based on the number of iterations - let color = (iter == MAX_ITER) ? rgb32(0, 0, 0) : palette[iter % 7]; + let color = (iter == MAX_ITER) ? rgb32(5, 15, 50) : palette[iter % (MAX_ITER _/ 5)]; color_array.set_u32(idx, color); ++idx; } @@ -83,6 +89,7 @@ for (let var i=0; i Date: Mon, 22 Dec 2025 20:04:22 +0000 Subject: [PATCH 4/7] purple experiment II --- examples/aurora.psh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/aurora.psh b/examples/aurora.psh index ee210f5..b04250a 100644 --- a/examples/aurora.psh +++ b/examples/aurora.psh @@ -34,9 +34,9 @@ fun rgb32(r, g, b) { let palette = []; for (let var i = 0; i < MAX_ITER _/ 5; ++i) { let t = i / ( MAX_ITER _/ 5); - let r = ( 1 + ( 95 - 1) * t).floor(); - let g = (239 + ( 42 - 239) * t).floor(); - let b = (172 + (132 - 172) * t).floor(); + let r = (163 + (162 - 162) * t).floor(); + let g = (220 + ( 69 - 220) * t).floor(); + let b = (111 + (222 - 111) * t).floor(); palette.push(rgb32(r, g, b)); } From 0db85591cfb2814c0199412fd45fe9fd975272f7 Mon Sep 17 00:00:00 2001 From: Rui Fonseca <804752+ruifonseca@users.noreply.github.com> Date: Mon, 22 Dec 2025 20:12:53 +0000 Subject: [PATCH 5/7] mix initial color experiment with #iters --- examples/aurora.psh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/aurora.psh b/examples/aurora.psh index b04250a..368f2a5 100644 --- a/examples/aurora.psh +++ b/examples/aurora.psh @@ -32,11 +32,11 @@ fun rgb32(r, g, b) { // but not for every iteration. A fifth of MAX_ITER // is purely empirical - let palette = []; -for (let var i = 0; i < MAX_ITER _/ 5; ++i) { - let t = i / ( MAX_ITER _/ 5); - let r = (163 + (162 - 162) * t).floor(); - let g = (220 + ( 69 - 220) * t).floor(); - let b = (111 + (222 - 111) * t).floor(); +for (let var i = 0; i < MAX_ITER _/ 10; ++i) { + let t = i / ( MAX_ITER _/ 10); + let r = ( 1 + ( 95 - 1) * t).floor(); + let g = (239 + ( 42 - 239) * t).floor(); + let b = (172 + (132 - 172) * t).floor(); palette.push(rgb32(r, g, b)); } @@ -68,7 +68,7 @@ fun colorizer(from, to) { let iter = fugue(c_re, c_im, MAX_ITER); // Set the pixel color based on the number of iterations - let color = (iter == MAX_ITER) ? rgb32(5, 15, 50) : palette[iter % (MAX_ITER _/ 5)]; + let color = (iter == MAX_ITER) ? rgb32(5, 15, 50) : palette[iter % (MAX_ITER _/ 10)]; color_array.set_u32(idx, color); ++idx; } From 640bbcaae656a69eda5d404a09189aa51e3969f4 Mon Sep 17 00:00:00 2001 From: Rui Fonseca <804752+ruifonseca@users.noreply.github.com> Date: Mon, 22 Dec 2025 21:51:57 +0000 Subject: [PATCH 6/7] add some random stars... --- examples/aurora.psh | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/examples/aurora.psh b/examples/aurora.psh index 368f2a5..969d264 100644 --- a/examples/aurora.psh +++ b/examples/aurora.psh @@ -56,8 +56,24 @@ fun fugue(c_re, c_im, max_iter) { return iter; } +// --- Pseudo-Random Number Generator (LCG) --- +let var lcg_seed = 1; +fun rand_init(seed) { + lcg_seed = seed & 0x7FFFFFFF; +} + +fun rand_int(max_val) { + lcg_seed = (lcg_seed * 1103515245 + 12345) & 0x7FFFFFFF; + return lcg_seed % max_val; +} + +fun rand_star(color) { + return rand_int(809) == 0 ? rgb32(255, 255, 255) : color; +} + // Colorize buffer points from..to fun colorizer(from, to) { + rand_init($actor_id() + $time_current_ms()); let color_array = ByteArray.with_size(WIDTH*4*(to-from)); let var idx = 0; for (let var y = from; y < to; ++y) { @@ -69,7 +85,7 @@ fun colorizer(from, to) { // Set the pixel color based on the number of iterations let color = (iter == MAX_ITER) ? rgb32(5, 15, 50) : palette[iter % (MAX_ITER _/ 10)]; - color_array.set_u32(idx, color); + color_array.set_u32(idx, rand_star(color)); ++idx; } } From 0e31216b2c4d483b76c18b7ec6b5eb2ca5be9ab0 Mon Sep 17 00:00:00 2001 From: Rui Fonseca <804752+ruifonseca@users.noreply.github.com> Date: Mon, 22 Dec 2025 22:47:59 +0000 Subject: [PATCH 7/7] review coments, syntax --- examples/aurora.psh | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/examples/aurora.psh b/examples/aurora.psh index 969d264..41aaf48 100644 --- a/examples/aurora.psh +++ b/examples/aurora.psh @@ -2,13 +2,13 @@ // This example builds on mandelbrot.psh. // Differences: -// - Uses a different palette with green aurora borealis colors +// - Uses a different palette with aurora borealis colors // - Renders the set concurrently using actors // -// Each actor is given a (logical) portion of the image. -// For each pixel it calculates the color to render and -// sends a message to the main actor with the index and -// the color to paint, both packed in a single Integer. +// Each actor is given a set of rows and calculates the +// corresponding array of colors, sending it back to the +// main thread/actor where they are $memcpy'd onto the +// final image. let WIDTH = 640; let HEIGHT = 480; @@ -28,9 +28,8 @@ fun rgb32(r, g, b) { } // Create an aurora borealis color palette. -// Interpolate from (1, 239, 172) to (95, 42, 132), -// but not for every iteration. A fifth of MAX_ITER -// is purely empirical - +// Interpolate from (1, 239, 172) to (95, 42, 132) in +// only a few steps - MAX_ITER / 10 is empirical. let palette = []; for (let var i = 0; i < MAX_ITER _/ 10; ++i) { let t = i / ( MAX_ITER _/ 10); @@ -57,6 +56,7 @@ fun fugue(c_re, c_im, max_iter) { } // --- Pseudo-Random Number Generator (LCG) --- +// @see also: examples/random.psh let var lcg_seed = 1; fun rand_init(seed) { lcg_seed = seed & 0x7FFFFFFF; @@ -67,6 +67,7 @@ fun rand_int(max_val) { return lcg_seed % max_val; } +// Every once in a while, generate a white dot fun rand_star(color) { return rand_int(809) == 0 ? rgb32(255, 255, 255) : color; } @@ -98,7 +99,7 @@ let start_time = $time_current_ms(); // Distribute rows and hand them to actors let var to = 0; let actor_boundaries = {}; -for (let var i=0; i