My portfolio as a small 3D room at night, where every object is a project.
three.js · Blender · TypeScript · Vite · custom shaders · a mini game
About this repository. The site's source code is private. This page explains the idea, what a visitor can do and how it is built.
Most portfolios are a hero, a project grid and a contact form. Mine asks one question that runs through all of my projects:
Where is a model allowed to decide, and where do the rules decide?
Every project on the site answers it: which steps an AI model handles and which steps are tested, deterministic code.
- Explore the room. A room modelled in Blender: desk, two monitors with live screens (a terminal that types out a security digest, a bot chat), a homelab under the window, a bookshelf, a neon sign. Every object is a hotspot that leads to a project. A plain list sits right next to it.
- Watch 10,000 particles morph. Each project chapter reshapes a cloud of 10,000 WebGL points into its own symbol (a house, a price tag, a shield, a speaker...). Each chapter shows the route through the project, step by step, marked "model" or "rule".
- See your own browser fingerprint. A section reads ten traits of your browser (OS, time zone, screen, GPU, canvas hash...) entirely on your device, sends nothing anywhere, and places you in a crowd of 10,000 browsers. Then it answers the same ten questions about me.
- Play "Bots at the door". A 60-second 3D game: defend an SSH server from waves of login bots, charge a fail2ban shockwave, and don't zap the legitimate users. It ends with a five-line security digest, like my tool LogKompass writes.
Captured from the live site.
![]() | ![]() |
![]() | ![]() |
- One content file as the source of truth. All text is rendered into the HTML at build time by a custom Vite plugin, so the site is readable without JavaScript and by crawlers.
- Blender as a data tool. Besides modelling, a sampler script inside Blender produces the particle shapes (9 shapes × 10,000 points, weighted so fine details get more points). Object and material names in Blender act as the API between the models and the code.
- Small assets. The room and game models are meshopt-compressed to roughly 230 KB and 160 KB.
- Graceful fallbacks. No WebGL: a Cycles render replaces the room and everything else still
works.
prefers-reduced-motion: no morphing, no camera drift, slower bots, no screen shake. - Privacy. No cookies, no analytics, nothing stored.
- Tested in a headless browser. A Puppeteer script takes screenshots of every section, including no-WebGL and reduced-motion modes.
- Strict TypeScript and automated build-and-deploy with GitHub Actions on every push.
| Area | Tools |
|---|---|
| Language | TypeScript (strict) |
| 3D | three.js, custom GLSL shaders, Blender (modelling, Cycles, Python sampling script), gltf-transform |
| Build | Vite with a custom HTML-injection plugin |
| Testing | Puppeteer screenshot script |
| Fonts | IBM Plex Sans, IBM Plex Mono, Barlow Condensed |
| Deploy | GitHub Actions to a static web server |
| Development | Claude Code (AI-assisted development) |
Built by Danylo Prokhorenko, Vienna · danyaprokhorenko@gmail.com






