Comparibly
Interactive 3D visualization tool for comparing real-world sizes of animals, dinosaurs, Pokemon, and mythical creatures — 122 entities with real GLTF models in a Blender-inspired interface.
Built an interactive 3D size comparison tool — select up to 10 entities from a database of 122 (animals, dinosaurs, Pokemon, mythical creatures, people) and see them rendered side-by-side with accurate proportional scaling. Features 107 real GLTF models, 9 immersive environments with weather and particles, physics-based animations, smart auto-layout, and a Blender-inspired dark UI.
The Concept
My 3-year-old is obsessed with animals and dinosaurs. He loves flipping through books about them, but the pictures never really answer his favorite question: "How big is it... like, compared to ME?" Size is hard to intuit from numbers alone — a Blue Whale is 30 meters long, but what does that actually look like next to a T-Rex? Or a Pikachu? Or a person? Existing comparison tools use flat 2D silhouettes or static images. I wanted to build him something he could actually explore — orbit around, zoom into, and feel the scale difference in 3D space.
This was a fun weekend project born from a dad moment. The core "aha" — the moment that made my son lose his mind — was placing a Pikachu (0.4m) next to a Blue Whale (4.5m tall, 30m long) next to a T-Rex (4m tall) in the same 3D scene, with a permanent 1.7m human figure for reference, and letting him orbit around all of them with the mouse. Watching him point at the screen yelling about how small the cat is next to the elephant made the whole thing worth it.
The Entity Database
122 entities across 5 categories, each with accurate real-world dimensions:
- Animals (54): From a Bumblebee to a Blue Whale — spanning orders of magnitude in scale
- Pokemon (26): Pikachu, Charizard, Snorlax, Wailord, Gyarados — using official Pokedex heights
- Mythical Creatures (20): European Dragon, Kraken, Phoenix, Griffin — with dimensions from folklore and mythology
- Dinosaurs (15): T-Rex, Brachiosaurus, Velociraptor, Spinosaurus — paleontologically accurate
- People (7): Average Human, NBA Player, Olympic Gymnast, Sumo Wrestler — showing human size variance
107 of the 122 entities use real GLTF/GLB 3D models sourced from Sketchfab. The remaining 15 use geometric shape fallbacks with category-appropriate colors.
Design Decisions
Blender-Inspired Interface
I wanted the UI to feel like a professional 3D tool, not a toy. The dark theme (#1f1f1f/#2b2b2b) with monospace accents, keyboard shortcut hints, and a collapsible sidebar is directly inspired by Blender's layout. The entity browser uses virtualized scrolling (via @tanstack/react-virtual) to handle 122+ items without jank.
Smart Auto-Layout Algorithm
Positioning variable-sized 3D entities in shared space without overlap was the hardest engineering problem. For 1-6 entities, a linear arrangement sorted by height works well. For 7-10 entities, a circular layout prevents depth occlusion. Spacing is proportional to entity bounding boxes, and the camera auto-fits to frame everything.
This took 5+ commits of iterative debugging to get right — the commit history tells the story of progressively solving edge cases in 3D positioning.
9 Immersive Environments
Each environment preset (sunset, dawn, night, forest, city, park, warehouse, studio, apartment) has its own fog configuration, ground material, spotlights, distant objects, particle systems, animated elements, and weather effects. A forest environment has drifting leaves and mist. The night scene has stars and moonlight. They transform the feel of the comparison from clinical to cinematic.
Physics-Based Animations
Entity entrance animations use spring physics via @react-spring/three — entities drop from above with a scale-up effect, then settle with natural deceleration. Exits shrink and sink. Position transitions between layout recalculations animate smoothly rather than snapping. Spring physics over duration-based easing makes every movement feel organic.
Architecture
The state layer uses 4 Zustand stores to avoid prop drilling through the 3D scene graph:
- Comparison Store — Selected entities (up to 10), animation states (entering/idle/exiting)
- UI Store — Sidebar state, category filter, search query, environment selection
- Camera Store — Target position/lookAt, focus-on-entity, reset, fit-all
- Settings Store — Performance mode, emoji toggle
The 3D scene is built with React Three Fiber, keeping the declarative React mental model while accessing Three.js's full rendering pipeline. Geometry and material factories cache shared resources across entities, and a 3-tier performance system (High/Balanced/Performance) dynamically adjusts DPR, shadow maps, particle counts, and weather effects.
What I Learned
Placing objects in 2D is trivial — you have x and y. In 3D with variable-sized entities, you need to account for bounding boxes in three dimensions, camera viewing angle, depth occlusion, ground plane contact, and the fact that models have different origin points. What seems like a simple layout problem becomes a spatial algorithm challenge.
The same size comparison feels completely different in a sunset environment vs. a warehouse vs. a night scene. Adding atmospheric effects (fog, particles, weather) was technically unnecessary — the entities are the same size regardless. But the emotional impact of seeing a dragon next to a human in a misty forest is dramatically more compelling than in a blank void.
With 107 GLTF models, 9 environments with particles and weather, and spring-physics animations running simultaneously, performance tuning was constant. The 3-tier quality system wasn't a nice-to-have — it was essential. Adaptive DPR, shadow map sizing, and conditional rendering of atmospheric effects kept the experience smooth across hardware tiers.