Lusion,
reverse engineered
A recreation of lusion.co, the Awwwards 2023 site of the year by the renowned Lusion creative production studio.
3D assets, threejs rendering code, HTML/CSS, shaders made my me
One learns by doing the thing; for though you think you know it, you have no certainty until you try.- Sophocles
Project link and source code
Rationale
I'm a curious being. When I see amazing work I can't help but wonder, how did they do that?
And so I set myself a challenge: to recreate the lusion.co website, a website that seemingly defies what's possible with a browser.
What I love about the site is how it seemlessly transitions from 2D to 3D. You begin feeling like it's a regular website and then additional layers reveal that you're getting yourself in to something much more.
Wait, so it's 3D?
If you scroll, you'll notice that we have what seem like regular HTML blocks with some 3D content embedded. But then some 3D elements can move and animate between different boxes.
To achieve this, I have a full screen <canvas>
behind our HTML, as demonstrated in the video.
Mapping HTML to 3D positions
Positions are defined using HTML flex/grid layout (it's much nicer than doing it in a 3d engine!). I then calculate a screen-position-to-world coordinate, thus enabling pixel perfect positioning of 3D objects in a responsive manner.
Interactive physics
First, I create some interesting lights, model some spheres and apply a glossy material on it.
I use Rapier.js for physics track a collider to the mouse position.
An attractive force is applied, giving the balls a gravitional pull to the center.
The results were lacklustre to begin with, but with some custom code to add an additional impulse force, thereby making the relatively small mouse movements much larger and more powerful. With that, we have a rather fun ball smasher.
Finally a procedurally generated mesh with rounded corners is rendered before the balls, which writes to the stencil buffer.
The balls do a stencil test, thus enabling me to mask off an area, giving the impression of a window in to the ball pit world.
You can view the source code here: physicsSandbox.js
Animation, mathematically
Now this effect, had me really stumped. It took me approximately 7 attempts to mimic this seemingly simple animation of a mesh dancing and becoming a larger version of itself.
I tried mesh deformations, animating it in Blender, applying springs to the bones and numerous others techniques. In the end, I coded the animation entirely mathematically, using a custom vertex shader.
In the vertex shader, I drive the entire animation using a single value that goes from 0 to 1. Let's call this animateProgress
.
I then determine areas of the mesh that I'd like to affect using its uv
coordinates
and the
animateProgress
value.
You can think of these areas like masks that grow and shrink. I use these masks to determine which areas to affect by rotation, translation and scale.