A restaurant in 3D
Real three-dimensional models, with rendering cost controlled scene by scene.
Web and interface · JavaScript · In production

The problem
Putting 3D on a website is easy to get wrong: the usual result is heavy, crawls on mobile and ends up looking like a template. The technical challenge is integrating real models without the page dragging: here it is solved by stopping each scene from rendering off-screen and capping pixel density.
What it does
- Integrates real GLB models with React Three Fiber.
- Scroll animations and micro-interactions with GSAP ScrollTrigger.
- A complete journey: hero, story, three-dimensional menu and contact.
- Deployed in production.
What was decided while building it
- Each scene clones the model
- The model loader caches a single instance and shares it. Using the same model in two places without cloning left one card empty and the other with a tiny piece, because the two overwrote each other's scale. Each scene now works on its own copy.
- Size is normalised by measuring the model's box
- Every model arrives at a different scale and some bring extra geometry: a plate, a base, a side dish. Its bounding box is measured, centred and scaled to a target size, or one card shows an enormous piece and the next one a tiny one.
- The render loop stops off-screen
- With four scenes on one page, animating them all at once punishes the battery and on a modest machine can leave models unpainted. Each canvas stops when it leaves the visible area and starts again shortly before entering. This saves rendering, not downloading: the models are already on the device.
- A sway, not a full turn
- The models sway gently around their original orientation instead of spinning. A full turn ends up showing the untextured base or the hollow inside of the piece, which is the exact moment it becomes obvious it was a model and not food.
How far it goes
- The three models add up to about seventeen megabytes uncompressed. There is no geometry compression and no lazy loading: what is optimised is the cost of rendering, not of downloading. On a slow connection it shows.
- It is a demonstration site: the menu, the prices and the venue's figures are invented, and one of the models is AI-generated.
- There are no bookings, no cart and no form that sends anything. The order button is not wired to any system.
- Each three-dimensional scene consumes one of the browser's drawing contexts, which are limited: multiplying the scenes on this page does not scale without changing the approach.
Built with
- React
- Three.js
- GSAP