Behind the Scenes: How We Built a Zero-Download 3D Tactical Shooter with WebGL and Three.js
When we first pitched the concept of Zentaris—a competitive, zero-compromise 3D tactical shooter playable in any standard web browser without a single download—many industry veterans were skeptical.
"WebGL can't handle high-density geometry."
"Garbage collection spikes in JavaScript will cause micro-stutters during gunfights."
"Browser pointer lock has too much input lag."
Today, Zentaris runs at over 120 FPS on standard hardware with sub-frame input responsiveness. Here is a look behind the curtain at the engineering choices, rendering pipelines, and asset optimization techniques that made it possible.
1. The Technology Stack Architecture
Building a browser-native shooter required selecting tools that bridge high-level web interactivity with low-level GPU acceleration:
- Next.js & React 19: Manages the surrounding web platform, user profiles, real-time leaderboard querying, and dynamic page routing.
- Three.js & React Three Fiber (R3F): Powers the core 3D scene graph, camera frustum calculations, and WebGL rendering context.
- Drizzle ORM & PostgreSQL / Supabase: Powers the high-concurrency match record storage, player XP tracking, and telemetry database.
- Draco & KTX2 Texture Compression: Compresses multi-megabyte 3D weapon meshes into featherweight streaming assets.
2. Compressing 3D Assets: The 137KB MDR Model
One of the biggest hurdles for web gaming is asset delivery. A standard desktop FPS weapon model might carry 25MB of uncompressed 4K textures and 80,000 polygons. If a browser had to download that before every match, loading screens would take minutes.
For the MDR Bullpup rifle in Zentaris:
1. We reduced geometry to a highly efficient 14,500 polygons, baking fine mechanical bevels and receiver grooves into high-resolution normal maps.
2. We applied Draco geometry compression, compressing vertex coordinates, normals, and UV layouts.
3. The resulting asset—MDR-optimized.glb in our /public directory—weighs in at an astounding 137 KB.
[Standard Desktop Weapon Mesh: ~25.0 MB]
|
(Retopology + Normal Baking)
|
(Draco GLTF Compression)
v
[Zentaris In-Game Asset: 137 KB] ===> 99.4% Reduction!This model streams and parses in less than 40 milliseconds, even on modest 4G mobile connections.
3. Eliminating Garbage Collection Stutter
In high-speed shooters, a single 16-millisecond garbage collection (GC) stall causes a dropped frame, often causing a player to miss an angle or lose a duel.
To achieve a flat, zero-stutter frame time graph:
- Object Pooling: We never create new
Vector3,Quaternion, or particle instances during render loops. Bullet tracer instances and impact decals are pre-allocated in static pools and recycled indefinitely. - TypedArrays for Telemetry: All network packet payloads use binary
Float32Arraybuffers, avoiding string parsing and heap memory allocations during gunplay ticks.
We are constantly pushing the envelope of what browser gaming can achieve. Stay tuned as we introduce custom WebGPU compute shaders in upcoming updates.



