LRNZ SNGLRT is a minimalist and energetic entry for JS1k 2016 showing twisted Lorenz attractors with ambient occlusion, soft shadows, ... a strong beat & clean design.
After a long judging period, LRNZ SGNLRT ranked #10 at JS1k.
JS1k 2016: Let's get EleMental
As usual JS1k had an evasive theme to guide the participants. This year it was _Let's get EleMental_ which encompassed all things physics, and psychic.
This theme was spot on: Few days earlier the sound of gravitational waves broke the news. Also I wanted to play with Lorenz attractors, or coupled attractors, and better lighting since a while.
Unlike demoscene competitions, JS1k does not impose a maximum duration for the entries. This leaves two options: interactive or looping entries.
My first idea was to play with particles collapsing into a singularity, and again, using a Lorenz attractor as base shape. Hence the name: LRNZ SNGLRT
Lorenz Attractor
The attractor itself is a straight forward implementation of the formula:
dx = A * (y - x);
dy = x * (B - z) - y;
dz = x * y - C * z;
x += dx / dt;
y += dy / dt;
z += dz / dt;
Where A
, B
and C
are the coefficients making the shape. This is so fast for 1024 particles that the attractor can be generated for each frame and rendered at 60fps. The rendering is by far most expensive operation.
The particles and the LRNZ SNGLRT title are placed in 3D, with the particles spinning around the y
axis.
cos = Math.cos(angle);
sin = Math.sin(angle);
xNew = x * cos - z * sin;
yNew = y; // no change since we rotate around this axis
zNew = x * sin + z * cos;
Lorenz Attractor with a twist
Unfortunately Lorenz attractors have a very distinct shape that ressemble a butterfly and can feel a bit cliché. To make the shape more interesting, I added a simple twist to unravel the "wings of the butterfly" by adding
cos = Math.cos(angle + particleIndex * B);
sin = Math.sin(angle + particleIndex * B);
xNew = x * cos - z * sin;
yNew = y; // no change since we rotate around this axis
zNew = x * sin + z * cos;
Simple. Efficient.
Ambient occlusion, lighting and soft shadows
For the ambient occlusion and lighting, we jitter the position of the particles, accumulate them into a low resolution 3D texture, and spread them at increasingly lower opacity away from the global source of illumination. The render loop looks up in this 3D texture to occlude each particle.
Additionaly the particles are drawn in two halves, upper and lower, lit using the ambient occlusion 3D texture and the velocity of the particle, the dx
, dy
and dz
values in the formula of the attractor, which map to the normal of the shape and give it more volume.
The soft shadow is done by projecting the particle to a fixed y
coordinate and drawing a low opacity quad. The accumulation and movement complete the illusion.
Audio
The sound uses the Audio element and the ByteBeat technique to create a looping sound.
for(t=0,d="RIFFdataWAVEfmt "+atob("EAAAAAEAAQAAgAAAAIAAAAEACAA")+"data";t<32;t+=2/65536)
d+=String.fromCharCode(128
+ Math.random()/(t%1+.01)
- (8*t&1333*t&15)
+ (8&t)*(8*t&655*t&7)/8);
C=new Audio("data:Audio/WAV;base64,"+btoa(d)),C.play(C.loop=F)
This creates a WAVE PCM sound file that is loaded as a data: URI encoded in base64.
The snare is especially nifty and powerfull:
Math.random()/(t%1+.01)
The other "instruments" are regular ByteBeat and provide a hint of melody
- (8*t&1333*t&15)
+ (8&t)*(8*t&655*t&7)/8);
Feedback ?
You can find the LRNZ SNGLRT at Pouet.net and JS1k where it ranked #10. Suggestions and comments are welcome.
Other recent experiments
There are many experiments and projects like LRNZ SNGLRT to discover other here.
- FRONTFEST MOSCOW It was an honour to be invited to Fronfest Moscow 2017 with the little family to give my first workshop; implementing a Twin-stick shooter using ES6 and Canvas, and to continue my CODE🎙ART series of talks + live coding aiming to inspire new web developer artists. on November 18th, 2017
- VOLTRA VOLTRA: Grinding the Universe, a gritty JavaScript demo, winner of the 1024 bytes demo competition at the Assembly 2017. on August 6th, 2017
- BREATHING EARTH Another take on Nadieh Bremer mesmerizing Breathing Earth visualisation, running at 60fps on a 2D Canvas without libraries or frameworks. on June 26th, 2017
- ASTRA ASTRA is a JavaScript odyssey in 1002 bytes for Assembly 2016 on August 6th, 2016
- DEMO REEL AND TINY JAVASCRIPT AT FRONT TRENDS I had the pleasure to speak about creating bite sized audio-visual demos, and LIVE code one at Front Trends 2016 in Warsaw, Poland. on May 19th, 2016
- TINY AUDIO-VISUAL DEMOS AT JSCONF ASIA I had the honor to open the second day of JSConf Asia 2015 in Singapore with a talk and LIVE programming session about Tiny Audio-Visual Demos on November 20th, 2015
- TILT SHIFT A very fast & simple tilt-shift effect in Canvas. on January 10th, 2009
- ASAHIKAWA Flyby the city of Asahikawa in 64 bytes. on January 21st, 2007
Let's talk
Don't be shy; get in touch by mail, twitter, github, linkedin or pouet if you have any questions, feedback, speaking, workshop or performance opportunity.