How 3D Money Visualization Works
A technical look behind the scenes at Money Visualiser — from central bank specifications to instanced mesh rendering and real-time exchange rate APIs.
How We Turn Numbers Into 3D Cash Stacks
When I first started building this tool, I thought money was just money. But if you want to render a million euros next to a million dollars, you have to know exactly how thick a €50 note is compared to a $100 bill. I ended up digging through official specs from the Federal Reserve, the ECB, and the Bank of Japan just to get the millimeter measurements right.
The hard part wasn't the math. It was getting the browser to render hundreds of individual bills at 60 frames per second without melting someone's phone. To pull it off, I wired up Three.js and React Three Fiber, then spent weeks optimizing the draw calls.
Here is exactly how the pipeline works, from scraping central bank PDFs to pushing pixels to your screen. It's a bit nerdy, but if you care about WebGL performance or data visualization, you might find some of the hacks useful.
Scraping Central Bank Specs
American money is boring to render. Every single US bill is exactly 156.1 by 66.3 millimeters, and exactly 0.1 millimeters thick. The Euro is a nightmare. They have seven different denominations, and every single one is a completely different size. It forces the physics engine to calculate completely jagged, uneven stacks.
I actually track when countries change their money. When Japan rolled out their massive 2024 redesign, I had to hunt down the new dimension specs almost immediately. If a country shaves two millimeters off a banknote to save plastic, it literally changes the height of a billionaire's net worth in the app.
For the colors, I just pull high-res scans of the actual bills and sample the dominant hues. I map those directly into the 3D materials. It sounds simple, but sitting a stack of green hundreds next to a pile of harsh blue twenties makes the visualization instantly readable.
Faking It With Instanced Meshes
If you try to tell a GPU to draw 300 separate boxes, it will choke. I learned this the hard way. Instead, I use WebGL instanced meshes. You basically upload the 3D geometry of a bill exactly once, and then tell the graphics card to stamp out copies of it, only changing the x, y, z coordinates for each one.
I capped the engine at 300 visible bills. I tested higher numbers, but old iPhones would start dropping frames, and I wanted the camera to always feel buttery smooth. To make it work, I just calculate a massive transformation matrix that mathematically sorts every bill into a neat stack.
Geometry
Instances
Performance
Of course, if you type in a million dollars, I'm not rendering 10,000 loose bills. That would crash your browser instantly. Instead, I swap the geometry to render solid 'bricks' or 'pallets' of cash. The physical volume on screen is 100% accurate, but the computer only has to draw a fraction of the polygons.
Stealing the Bank's Math
I didn't invent how the money stacks. I just copied the American Bankers Association (ABA). Banks don't count loose bills—they strap them in packs of 100, shrink-wrap ten straps into a 'brick', and stack ten bricks into a 'bundle'. I wrote a sorting algorithm that forces the 3D engine to group the money exactly like a paranoid vault manager.
If you enter a massive number, the engine doesn't just build a skyscraper of paper. It calculates how many bundles fit on a standard industrial shipping pallet. Once a pallet is full, it just spawns another one next to it, exactly how the Federal Reserve actually moves cash on trucks.
It took me a weirdly long time to get the ATM logic right. If you type in $2,345, the engine aggressively breaks it down using the largest possible bills first before handing out twenties and fives, making the physical pile as compact as possible.
A Paranoid Exchange Rate API
Financial APIs break constantly. To keep the site from going down every time a server somewhere hiccups, I built a deeply paranoid five-tier fallback system. It tries to grab clean rates from the European Central Bank first. If that fails, it falls back to raw XML feeds, and then to a secondary open API.
The ECB doesn't track everything, so for about 50 of the weirder currencies, I pay for Twelve Data's API. And if somehow the entire internet catches fire and all live sources go dark? The code just quietly falls back to a hardcoded spreadsheet of rates I update every week. The site fundamentally refuses to break.
I cache the rates heavily at the edge. The numbers you see are never more than five minutes old during market hours. It's fast enough that if a central bank suddenly hikes interest rates, you'll literally see the physical size of your money shift on screen a few minutes later.
The Tech Stack
The whole thing runs on Next.js 16. The 3D is all Three.js wrapped in React Three Fiber. Loading a massive 3D engine on a webpage usually destroys your Lighthouse score, so I aggressively lazy-load the canvas. The page renders instantly, and the 3D stuff pops in a fraction of a second later.
I didn't bother with Redux or heavy state managers. Almost everything just lives in the URL. If you change a currency, the URL updates. It's totally stateless, which means if you send a link to a friend, they see the exact same pile of money you're looking at.
I also had to build in a hardware degrade. If you open this on a fast gaming PC, the engine turns on soft shadows and ambient occlusion. If you open it on a five-year-old Android phone, it quietly kills the shadows and flat-shades the lighting so it doesn't nuke your battery.
Making It Run on Old Phones
Most people use this site on their phones, which means prioritizing WebGL performance is non-negotiable. When the page loads, the app does a quick hardware check. If you have a massive gaming PC, you get crisp shadows and nice lighting. If you're on a budget Android, the engine silently kills the heavy shaders so the frame rate stays high.
I also had to completely rethink the camera controls. Pinch-to-zoom and two-finger panning feel totally natural on a touchscreen, but a lot of 3D libraries default to terrible mouse-based orbital controls. I spent days just tuning the touch friction.
The goal is progressive enhancement. The math and the physical dimensions are perfectly accurate for everyone, but the cosmetic polish scales up only if your device can actually handle it.
Stop Guessing, Start Measuring
I don't guess a single data point here. The exchange rates are pulled directly from the ECB. The bill dimensions are straight from central bank PDFs. None of it is a rough estimation.
I actually set up a script to monitor when countries announce new money. When the Bank of England finally killed all their paper money for polymer plastic, the app was updated to reflect the slightly thinner plastic bills basically overnight.
You can check the math yourself. If the app says a million dollars is 43 inches tall, you can literally just multiply 10,000 bills by the Fed's 0.1-millimeter spec. The math is brutal and undeniable.
Wrangling 82 Different Currencies
Adding the US dollar and the Euro took an hour. Adding the other 80 currencies took weeks. Every single country has its own weird sizing rules, and I had to locate the official specs for all of them.
The live rates are another headache. The core ECB feed only covers about 30 major pairs. For the rest of the emerging markets, I have to route requests through a secondary financial API that tracks the obscure stuff.
Whenever I add a new country, I have to manually build the data object: input the millimeter dimensions for every bill they print, find the hex codes for the colors, and wire up the specific exchange rate ticker. It's wildly tedious, but it's the only way to get the visualizer to feel real.
Reading Data Without Eyes
A purely visual 3D canvas is completely useless to a screen reader. So, behind the render engine, the app continually updates a clean, hidden DOM structure explaining exactly what is on screen.
If you can't see the massive stack of hundreds, the screen reader just tells you the exact bill count, weight, and height in text. The math is completely decoupled from the WebGL rendering.
I also made sure you can drive the camera with just a keyboard. A lot of 3D web apps break the second you unplug your mouse, and that just feels lazy to me.
Faking Paper and Plastic
Getting the materials right took a lot of trial and error. American money is a cotton-linen blend, so it has a very flat, matte roughness. But a lot of modern money, like the Canadian dollar, is made of polymer plastic, giving it a slight reflective sheen.
I rely on accumulative shadows to really sell the scale. Without shadows, the 3D scene just looks like flat clipping art floating in space. When the shadows bake underneath a massive pallet of cash, your brain finally accepts how big the object actually is.
The bill colors are pulled straight from actual photos, not guessed. The weird yellow-green of an American hundred next to the aggressive orange of a fifty-euro note creates instant visual contrast that makes the comparison click.
Looking at WebGPU
Right now, the app is running on WebGL, but I'm actively testing WebGPU support. WebGPU basically gives browser apps near-native access to the graphics card. Once that fully rolls out, I'm hoping to push the max bill limit from 300 up to several thousand without dropping frames.
I'm also playing with WebXR. The ultimate goal is to let you hit a single button on your phone and use augmented reality to drop a full-scale pile of one billion dollars directly onto your living room floor. Seeing it on a screen is one thing; trying to walk around it in real life will be terrifying.
Frequently Asked Questions
See It Actually Run
Drop a massive number into the converter and watch the physics engine try to stack it.