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
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;
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
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;
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
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.
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:
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);
You can find the LRNZ SNGLRT at Pouet.net and JS1k where it ranked #10. Suggestions and comments are welcome.
Other recent projects
There are many experiments and projects like LRNZ SNGLRT to discover other here.
- MUSIC FOR TINY AIRPORTS AT WEB AUDIO CONFERENCE The Web Audio Conference 2018, held in September 19-21 in Berlin was a great mix of researchers, web developers, artists and performers presenting their projects. I had the chance to provide a deep dive into music for tiny airports, explaining how to generate hours and hours of music in a handful of bytes.
- 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
- MUSIC SOFTSYNTH This is the brain child of 140byt.es and Experimental music from very short C programs.
- SUDOKU SOLVER Solves a Sudoku grid using magic, recursion, and 140bytes of brute force.
- OOMA The winning bootsector of Outline 2005, featuring two images zooming with experimental music in a valid 480bytes Atari bootsector.
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.