Cutting each card from real glass
Our portfolio is a spiral of glass cards, each one refracting light like a real material. Here is how it works in one WebGL canvas, with no libraries.
- Project
- Interactive portfolio concept
- Year
- 2026
- What we did
- Concept, interaction design, development
- Built with
- WebGL2, GLSL, plain JavaScript

Our portfolio is a dark optical bench where every project is a card of glass, arranged in a spiral you can scroll, drag and fly into. It is a concept piece: apart from the Kanya card, the cards hold generative studies rather than client work, so we could push the medium without a brief holding it back.
The idea is not ours alone. The spiral is strongly inspired by Pacôme Pertant's portfolio, designed by Louis Bocquet and developed by Colin Demouge, and the glass material is adapted from the Infinite Liquid Glass technique. What we added was the question of what would happen if every card were cut from a real, measurable material.
One canvas, no libraries
We had a long list of candidates: WebGPU, Three.js, an animation library for the scrolling, another for smooth wheels, and a ready-made liquid glass effect. The site uses none of them. All the glass is drawn by one hand-written WebGL2 canvas behind the page, with no libraries and no build step.
The fastest-feeling design is not always the one with the smallest library, but here, owning every line meant we could make the canvas and the page agree exactly. The canvas measures in CSS pixels, so any card can sit on the spiral or follow the position of an element on the page, and blend between the two. That's how a card flies out of the spiral and becomes the hero of a project page, or grows from the showreel thumbnail into a full frame.
Every card is a real material
Each card has the refractive index and Abbe number of a real optical material. The index sets how strongly the card bends what's behind its bevel, and the Abbe number sets how much it splits light into colours.
| Card | Material | Index | Abbe number |
|---|---|---|---|
| Prism | Dense flint (SF11) | 1.785 | 25.8 |
| Dune | Polycarbonate | 1.586 | 30.0 |
| Contour | N-BK7 optical glass | 1.517 | 64.2 |
| Quicksilver | Fused silica | 1.458 | 67.8 |
| Kanya | Sapphire | 1.768 | 72.2 |
| Halo | Diamond | 2.417 | 55.3 |
Refraction follows the index minus one, and colour splitting follows one over the Abbe number. So flint and polycarbonate fringe visibly at their edges, while fused silica and sapphire stay clean. The specs on each project page quote the real values.
The material, in one pass
Every card is drawn in a single pass:
- The shape of a rounded rectangle is turned into a bevel.
- The bevel's slope refracts the card's own artwork, separately for red, green and blue, which is what makes the colour fringes.
- A reflection of the surroundings, a Fresnel edge, a highlight and a thin spectral rim finish the surface.
The cards refract their own artwork rather than the whole scene behind them. Real transmission through the background would take extra passes for every card, and we kept that in reserve for a few moments that would earn it.
Keeping it light
Glass is expensive to draw, so the budget was set before the effect. Only the cards in focus are re-rendered, and depth of field comes from reading blurrier versions of a texture for distant cards, so it costs no extra passes.

When the glass isn't there
A portfolio like this has to work without its effects:
- Without WebGL2, the site switches to the list view, with CSS gradients as previews. Every project and link still works.
- With reduced motion turned on, nothing drifts, the artwork holds still and the About text appears fully lit.
- The spiral works with the arrow keys and Enter, the menu traps focus, and Escape closes it.
The menu itself became our favourite rule. It's a milky, nearly opaque glass panel, because glass is allowed to be nearly opaque wherever reading matters more than refraction.


