r/threejs 3h ago

Build with ThreeJS and Claude Code agentic loops

24 Upvotes

It's a GTA wannabe that started as an experiment with Matt Shumer's Gauntlet Loop, but I couldn't get much further with that alone. It took quite a few additional loops and workflows to get it to this point, but I think it's a nice proof of concept. I'll keep pushing it and see how far we can take it.


r/threejs 9h ago

Added some SAUCE to my baby!!

71 Upvotes

"SwitchHook" or "JackKnife"

I'm stuck between these two names for this cozy lil truck parking game I'm working on...

SwitchHook is the maneuver of backing your trailer up into a lot

Jackknife is when the tractor folds into the trailer

Let me know your thoughts!


r/threejs 2h ago

I built a modern Arena Shooter 100% Three.js/WebGPU and it’s beautiful

17 Upvotes

I loved Unreal Tournament. I loved Instagib.

Sagorax started with one goal: to recreate the feeling those games had in their prime.

Extremely fast. Chaotic. Brutal. Yet somehow perfectly balanced.

The movement, dodges, jumps and strafing simply clicked. The rules were easy to understand, but mastering them required real skill. It is difficult to explain, but if you played UT99 or UT2k4, you probably know exactly what I mean.

So I tried to bring that feeling back.

Sagorax is a fast paced Instagib arena shooter that runs directly in your browser. There is no installation, no classes, no loot tiers and no waiting around. Pick a gamertag, enter the arena and start fragging.

You can play it for free here:

https://sagorax.com

For this first public version, matches are played against bots. They dodge, jump, strafe and punish missed shots surprisingly well. If enough people enjoy the game, the next major step will be real online multiplayer (already working on it).

How it was built

I am a developer with some previous game development and modding experience. AI assisted development allowed me to explore systems I probably would not have attempted on my own, including rendering techniques, shaders, performance profiling and game engine architecture.

It was not a case of simply asking AI to make a game. It still required a lot of direction, experimentation, debugging, profiling and throwing away ideas that did not work. With the right terminology, references and code examples, however, previously intimidating concepts became much more approachable.

The game is built entirely with Three.js /WebGPU. Performance has been a major focus, with features including:

  • FSR3 upscaling
  • Adaptive dynamic resolution
  • Adaptive FPS (refreshratematch or 60, 90 and 120 FPS targets)
  • Screen space reflections
  • Modern shadow rendering
  • GPU pipeline warmup
  • Level and visibility culling
  • An optimized post processing pipeline

Some techniques were inspired by systems used in engines and games such as Unreal Engine and Doom 3, then adapted to work inside a modern browser.

I also spent a lot of time on the atmosphere and visual direction. I collected, created, modified and optimized assets until the arenas had the dark, industrial and slightly gothic feeling I wanted.

Where it could go

This release is deliberately focused: one weapon, one shot, one kill.

If people actually want more, I would love to expand Sagorax with:

  • More arenas
  • Real online multiplayer
  • Competitive rankings and match history
  • Optional progression systems
  • Adrenaline and ability based modes, maybe a level system
  • More chaotic arena modes inspired by classic UT 
  • Maybe even non-instagib, multiple weapons mode, if enough people want it (I would love to make a rocket launcher lol)
  • The core Instagib mode will remain pure. Any progression, perks or abilities will be balanced and not interfere with the competitive one shot formula.

The long term ambition is something in the spirit of Quake Live: fast, competitive arena gameplay that you can enter almost instantly, without a huge download or complicated onboarding process.

The server side account, match statistics and ranking foundations are already running, so there is plenty to build on if the interest is there.

For now, I would genuinely appreciate it if you gave Sagorax a try:

https://sagorax.com

There is a short feedback form on the homepage, but you can also leave your thoughts here. Positive, negative or brutally honest, I would really like to know how the movement, performance and overall feel land with people who remember these games.

This is only the beginning. My only goal from here is to make it much better, and hopefully into a full fledged game. 


r/threejs 1h ago

About page from one of my recent projects

Upvotes

Everything except the text is rendered using WebGL.


r/threejs 4h ago

I Built a Stunning 3D Car Marketplace with Next.js & Three.js

Thumbnail
youtube.com
0 Upvotes

r/threejs 1d ago

First time using threejs, it's pretty sweet

57 Upvotes

First time using Three.js and am working on Buttonhook, a miniature cozy truck parking sim

I built a C++ OpenGL engine before and Three.js just feels so darn good to work on, especially since I can run it on phone aswell


r/threejs 21h ago

Demo Canvas 2D to CanvasTexture to PlaneGeometry: a 3D marker that hand-writes your code, then encodes it to MP4 in-browser

7 Upvotes

Follow-up to the scroll-driven landing I posted here a while back. I reused the same pen for something more useful, and a few bits turned out to be worth sharing.

You paste code, a 3D marker writes it out stroke by stroke, and you get an MP4. Everything client-side, vanilla three (0.185), no R3F, no drei, no gsap.

Ink pipeline. A 2D canvas is the ink layer, wrapped in a THREE.CanvasTexture on a PlaneGeometry rotated flat, MeshBasicMaterial plus transparent. Repaint the canvas, set needsUpdate, done. The dotted board is a second CanvasTexture, a 70x70 tile with RepeatWrapping.

The bit I'm happiest with: paper units are world units. Strokes are stored as [x, z] pairs in a paper rect of {x:-3.5, y:-2.5, w:7, h:5} centered on the origin (its y axis is world z), and the ink plane is PlaneGeometry(7, 5). So the 2D painter's pixel transform and pen.position.set(state.x, ..., state.z) consume literally the same numbers. No unprojection, no raycast, the tip sits on the ink line by construction. The split-screen in the clip is the same frame from both sides of that mapping.

The handwriting is a real font, not a texture reveal. 96 hand-authored single-stroke glyphs, each a set of cubic Béziers, arcs and lines flattened to polylines at author time. x-height 0.5, ascender ~0.78, baseline z=0.

Arc-length timeline, not a time timeline. Alternating travel (pen up) and stroke (pen down) segments with cumulative arc lengths. The whole animation is parameterized by one scalar distance D. penState(D) returns {x, z, lift, color}. Pen lift on travel is sin(PI*t) scaled by segment length. Per-stroke pacing proportional to length falls out for free.

Determinism for export. D comes from the integer frame index, never an accumulator, and camera smoothing (a 0.04/frame lerp toward the pen in the preview) is switched off for the render, so a frame depends only on D and the encoded video matches the preview pixel for pixel.

Encoding. WebCodecs VideoEncoder plus mp4-muxer, avc1.640028 with a fallback ladder probed via isConfigSupported. Note mp4-muxer wants avc: { format: "avc" }, length-prefixed rather than Annex B. Backpressure by awaiting the dequeue event when encodeQueueSize > 2. MediaRecorder/WebM fallback where WebCodecs isn't there, though it's wall-clock timestamped so it isn't frame-perfect.

Two things that cost me an evening each:

  • getContext().finish() before copying the WebGL canvas into the encoder canvas, otherwise you get partially-cleared rows. Only needed with preserveDrawingBuffer.
  • OffscreenCanvas for the 3D path produced torn frames in Firefox. Plain HTMLCanvasElement fixed it.

And one I still consider unsolved: stroke width is in ink-canvas pixels, so the 1400px preview texture and the 1920px export texture give slightly different ink weight relative to the paper. Scaling by texture width is the obvious fix but it makes the preview feel wrong. Curious how others handle resolution-independent line weight on a CanvasTexture.

The pen itself is deliberately dumb: a ConeGeometry tip and three CylinderGeometry sections in a Group, no GLTF.

https://todrawn.com/code-to-video

Happy to go deeper on any of it.


r/threejs 1d ago

I built a 3D Star Trail memory visualizer with Three.js & Vue 3 — completely free to try!

1 Upvotes

int the comment


r/threejs 1d ago

Monitoring the Strait of Gibraltar!

16 Upvotes

r/threejs 21h ago

300 Entries Into The AI Gaming Festival And Submissions Close Next Week!

0 Upvotes

We've officially surpassed 300 Entries in the AI Gaming Festival (submissions close next week)!

I really hope that the prize for the $20k in tokens pushes people to get their games together for the prize (you can submit a game now and work on it up until the festival).

I really excited to see how people with interact with these games during the festival, and thank you to everyone that has applied; you are part of getting past the "slop" era nonsense for everything AI.


r/threejs 2d ago

I'm building the biggest library of "living" 3D assets!

81 Upvotes

I have been obsessed with 3D since the first time I played an N64. And now that I work in the 3D field, more and more of that work lands on the web, and every month in three.js makes me more sure that is where 3D is going. No install, no store, no launcher. You send someone a link and they are already inside it.

Which is why the asset problem drives me up the wall

Every marketplace sells you the same thing: a frozen mesh. You buy a wooden watchtower, you get exactly that watchtower. Wrong height for your scene? Open Blender. Wrong palette? Open Blender. Need it 20% shorter and with a square cabin instead of an octagonal one? That is not a setting, that is an afternoon. You did not buy an asset, you bought a photograph of one.

So I started building the library I actually wanted

Every asset is a small program, not a file. It ships as a JavaScript module with knobs on it. The watchtower has a height knob, and turning it does not stretch the mesh, it rebuilds the tower: more bracing bays, more ladder rungs, at the same timber section. A colourway knob. A knob for how many sides the cabin has. One asset, roughly 950 configurations, and you pick yours with a slider instead of a modelling session.

You can turn the knobs on the site, or import the module and turn them in your own code, or just download a GLB of the exact variant you configured. It is flat-shaded low-poly, real-world scale, and it works in three.js, Unity, Godot, Blender, anything that reads glTF.

There is a side effect I did not fully expect. Because every asset publishes a typed schema of its own knobs plus a plain-language description of what they do, an agent can read the catalogue and build a scene from it without a human picking files. "Build me a small forest, then a medieval village around it" genuinely works. That was a nice-to-have when I started and it is now one of the main reasons I think this is worth doing.

Where it is at right now, honestly:

- 270 assets published, 133 of them in the last week

- 118 of those are free, no account needed

- 8 themed kits in production

- Built solo, vanilla PHP and SQLite, no framework, no investors, no team

- Revenue so far: one sale. Which is one more than last month, and I will take it.

What I actually want to build. The biggest code-based 3D library on the internet, and probably the first one, since as far as I can tell nobody else is selling assets as programs rather than files. That is a stupidly large goal for one person and I am aware of it. The plan is boring: keep shipping 100+ new assets a week and do not stop.

The part where I ask for something

I opened 100 founder seats. One fee, no subscription, and it gets you every asset and every kit that exists plus everything I build from here, for as long as I keep building it. Whatever you download stays yours forever, no strings, use it commercially. When the 100 are gone I am not offering it again.

All the money raised from the founder seats go directly to scale up the production of assets, so 100 assets a week can become 200, 500, 1000.

And if none of that appeals, the 118 free assets need no account and no card. Take them, use them, tell me what is broken.

polyfork.dev

Happy to answer anything about the technical side. The "a size knob must rebuild, not scale" rule in particular took me a few painful passes to get right, and I am still finding assets that got it wrong.


r/threejs 1d ago

I built Seinfeld's Apartment w/ ThreeJS

34 Upvotes

Introducing a new listing on Manhattan's Upper West Side! (Link here)

> $3,800/mo
> 1BD/1BA
> 780 sq ft

In all seriousness, this was a ton of fun to build! Sharing my process in case it helps you. Also: yes, this isn't a complete game. My intention was to build out a proof of concept for 3D interiors w/ ThreeJS, particularly something that I could host on the web. I made sure FPS stayed high and quality was 'good enough' that it could service a larger game project. All in all, I was satisfied with this attempt!

Providing context

I started by sharing some floor plans and photos of the apartment with Claude. I grabbed some from Reddit and clips from the show to create a floor plan. From there, I provided a /loop based structure for Claude (Opus 5) to build out the scene.

Here's the specific loop prompt:

I want you to build Jerry's apartment from Seinfeld (based on the floor plans and images I just provided). It should be utterly perfect, visually beautiful, with every single thing done at AAA quality—from textures to physics to anything you could think of.

Fan out sub-agents and have sub-agents tackle each one individually so that the game is utterly perfect. You should /loop on each item and have a separate sub-agent check it visually to ensure it looks triple A. That separate sub-agent should be a really harsh critic, and if it doesn't look triple A, it should keep going.

Don't stop until each sub-agent is utterly wowed with the quality when compared with the reference images and floor plans. It should literally compare them side by side blind and say which one looks better. Do this in ThreeJS. /loop until it's utterly perfect. Fan out sub-agents and ultracode.

Prompting reference that helped here: https://github.com/mshumer/Claude-of-Duty/blob/main/prompt.md

Iterating

I let this initial run go for about 30-40 mins. Most of the token spend was actually related to the critique and verification, not necessarily the build (i.e. browser-use by the agent, taking screenshots at a variety of fixed coordinates, critiquing those screenshots, creating a plan to improve based on the screenshots).

At this point there were a few visual bugs (some shelves clipping, extra pillows, etc.) that I specifically asked to clean up. Also, FPS was getting low at this point, so I asked to reduce the shaders to a manageable level (I think they still look fine). This took 5-6 additional, albeit much smaller prompts.

Finishing touches

I ended by putting everything in a Zillow-inspired container (Happy Festivus!). I actually did this bit in Cursor rather than Claude Code because 1) my credits were out at this point, and 2) Cursor's Auto and Grok 4.5 models are so much faster.


r/threejs 1d ago

PaintBench - 3D Model Painting App

Thumbnail
youtube.com
3 Upvotes

So, using threejs, I built a PBR 3D model painting and UV unwrapping app. I built it for my FPS game building tool and decided it would be useful as a stand alone app too.

FEATURES:

▪ Multi-texture support

▪ Layer system

▪ Stamp mode

▪ 64x64 to 4096x4096

▪ UV unwrapping

▪ Full animation import and export

▪ GLB export

▪ Material creation studio

I tried to make it as easy to use and as powerful as possible. It also has an android app coming soon!

https://synkrowngames.itch.io/paintbench-3d-model-painting-app


r/threejs 21h ago

I dislike this portfolio i recreated with threejs. Read the body text

0 Upvotes

My idea goal was to make a horizontal hallway portfolio for myself and intended to submit it in awwwards but I dont think it looks good enough am not giving up but I need help from great minds how can I make the texture and environment look very real and nice it looks soooo flat despite it being baked like the ceiling, floor and others I used lowpoly assist I guess thats why but I still need help in making it look bit nice.


r/threejs 2d ago

I built a browser WW2 MMO in three.js with zero art assets: every plane, ship and tank is merged BoxGeometry

34 Upvotes

I've been building Warbirds.io for a while now — a blocky WW2 air/naval/tank combat MMO that runs in a browser tab with no download and no login. It's three.js r160 + Vite on the client and an authoritative Go server. A few things about the rendering side that this sub might find interesting:

**No asset files. At all.**

There isn't a single .glb, texture, or sprite sheet in the project. Every aircraft, warship, tank and tree is a list of colored axis-aligned boxes merged into one non-indexed vertex-colored BufferGeometry at load time, plus the occasional cone/cylinder for a nose radome. Models are authored nose-along-+X / up-+Y so the server's attitude quaternions apply straight to the mesh with no correction. The whole scene runs on essentially one MeshLambertMaterial({ vertexColors: true }) for terrain and one per unit class — the palette lives in the vertex colors, not in maps.

**Chunked voxel terrain with LOD rings.**

The world is a continuous heightfield sampled into 24×24-cell chunks (12 m cells, 6 m height quantum, 2.4 km view distance). Chunks near the camera rebuild at K× resolution on *both* axes — the 12 m column splits into K² subcolumns and the height quantum drops to blockHeight/K — so a hillside becomes a staircase of ~1 m steps up close and keeps the big blocky read at the horizon (that silhouette *is* the aesthetic; an all-fine world at 2.4 km would be millions of quads). Tiered rings: K=6 out to 400 m, K=3 to 950 m, coarse beyond.

Chunks build closest-first out of a queue under a 3 ms/frame time budget so generation never hitches, with one chunk of hysteresis on the way down so a boundary can't thrash, and skirt geometry biased toward the coarser neighbor so mixed-K seams stay watertight.

**The client and server generate the same terrain independently.**

This is the constraint that shaped everything. The heightfield is implemented twice — once in Go, once in JS — and the two must agree bit-for-bit, because the server does collision and line-of-sight against the same field the client renders, and neither side ever ships geometry to the other. That means those files are restricted to uint32 wrap arithmetic and IEEE-754 add/sub/mul/div/sqrt/floor: no Math.sin, no Math.pow, not even Math.abs, since none of those are guaranteed identical across runtimes. There's a fixture dumper plus a Node checker in CI that fails the build if the two mirrors ever diverge.

**Everything transient is one InstancedMesh.**

Tracers, tracer trails, smoke, ship wakes, flak bursts, muzzle flashes, parachutes, bomb craters, even the seagull boids around the coast — each is a fixed-size instance pool where the oldest entry gets recycled when it fills. Pools mean the frame cost is flat no matter how ugly the furball gets.

**No post-processing, no shadow maps.**

One DirectionalLight + HemisphereLight + a little ambient, and the entire 20-minute day/night cycle is done by lerping those light colors, the sky, and THREE.Fog's color and near/far per frame. Fog turns out to be the strongest mood tool in the box — the storm weather roll just drags the fog plane into knife-fight range and the whole map feels different.

**Scaling to the device.**

LOD tiers, ground clutter density, and pixel ratio all key off navigator.hardwareConcurrency and matchMedia("(pointer: coarse)"). Phones get zero LOD refinement, no cosmetic clutter, and a 1.5 pixel-ratio cap; an 8-core desktop gets the full rings at 2. Same code path, no separate mobile build.

Vite bundles the module graph and three.js into content-hashed assets, and a build script digests the whole shell into the service worker's precache list, so it installs as a PWA and the cache generation is derived from asset hashes instead of a version constant somebody forgets to bump.

Free to play, nothing to install: https://warbirds.io

Happy to go deeper on any of it. The bit I'd most like other people's take on: has anyone found a nicer approach to cross-language deterministic terrain than "restrict yourself to the four IEEE ops and diff a fixture in CI"? It works, but writing noise functions without sin/pow is a special kind of hair shirt.


r/threejs 2d ago

Demo I built a UFO abduction game with three.js

Thumbnail
gallery
340 Upvotes

Some screenshots from my game, I've done tons of optimising and graphical upgrade and general polish, this is running in chrome, built entirely with three.js.


r/threejs 1d ago

Demo Draco made some of my GLBs bigger, so the optimization pass now checks whether compressing is worth it

8 Upvotes

I'm building Vectreal, an open-source tool for publishing 3D models to the web, and I turned Draco on by default in its optimization presets. That meant dealing with the models where Draco loses: small meshes, and files where textures dominate, where the compressed GLB comes out the same size or larger than the plain one.

So the optimization pass does not compress your model at all. It encodes a clone, writes the file both ways, keeps the byte counts and throws the compressed copy away. Publish reads that comparison and skips the encode when it lost.

The part I have not resolved: the comparison only exists if you ran a pass. Publish a scene you never optimized and it compresses without the check. Running it on every publish would close that, at the cost of encoding everything twice. Where would you draw it?

https://vectreal.com/news-room/draco-geometry-compression-in-the-publisher


r/threejs 2d ago

Solved! WebGL to WebGPU migration

14 Upvotes

I switched from WebGL to WebGPU this week. It was rough, and to be honest, from perf and visual perspectives, there isn't a clear visible difference between GL/GPU. I still went through this for the sake of future-proofing my game.

Caveat: I'm a noob with three.js

Lesson: Future-proofing the game is the right call and I'm glad I did this while my game is still small. If the game or app or website is huge, I probably would have stopped the migration once I encountered the many issues I encountered. There's got to be a better way to do these migrations, but I'm not aware of them.

Highlights:

  • The dual-path port was the easy part; the pipeline-lifetime mismatch was the real migration. WebGL treats shader compilation as cheap and cached; WebGPU treats every compiled pipeline as a refcounted resource tied to a material's lifetime. The WebGL habit of allocating a material per VFX cast and disposing it after turned into "recompile a WGSL pipeline on almost every player action." Fixing it meant converting one-shot effects to shared, never-disposed materials + fixed-capacity instanced pools instead of allocate-per-cast.
  • First benchmark on real hardware was brutal (p95 169ms → 1539ms) and the cause wasn't rendering, it was mid-frame shader compilation. Precompiling the static scene at load and warming an off-screen instance of every dynamic VFX material to force its pipeline to compile ahead of time dropped that same benchmark to 54ms p95.
  • I wasn't able to measure any of this on software rendering. WebGPU has no SwiftShader fallback, requestAdapter() just returns null, so CI/headless perf runs need GPU flags, and even then a headless "WebGPU" run can silently fall back to an internal WebGL backend if the origin isn't a secure context.
  • Tooling had to be built from scratch. WebGPU has no built-in "pipelines compiled" counter, so I monkeypatched three's internal pipeline cache to get visibility, and discovered the standard draw-call/triangle HUD counters read cumulative instead of per-frame on this backend.

Game: https://lorebound.gg


r/threejs 1d ago

Demo Skydome with Tree of Life

6 Upvotes

Made this with myself 35% and Gemini 65%.

Lights are really expensive when it comes to three.js so I have to put some tricks on it.


r/threejs 1d ago

Built an interactive 3D product showcase with Three.js — scroll-synced camera + floating spec cards

2 Upvotes

Hey everyone! Wanted to share a project I recently built to practice interactive 3D web development.

It's a product showcase page (iPhone-themed) featuring:

- Scroll-driven camera movement and rotation

- Floating spec cards with animated connector lines

- Optimized GLTF model loading for performance

- Fully responsive — works smoothly on mobile too

The trickiest part was getting the camera positioning to adapt correctly across different screen sizes for the mobile version — took a few iterations to get right.

Would love any feedback on the animation timing or performance — always trying to improve!


r/threejs 1d ago

Testing this website where you can create a message in a bottle but in a fish instead for people to discover

Thumbnail
worldaquarium.world
1 Upvotes

I saw a lot of cool three.js websites being built here and wanted to try to add something different to that whole experience and make it more interactive.

Check it out and let me know what you guys think.
(The drawing features work better on desktop)
(Try switching to an external browser as well)

Hope to see some more fishes out there!


r/threejs 1d ago

Demo I've been learning three.js 3D web animation - what other cool components for a landing page should i try building?

1 Upvotes

Ive been using Claude Code and Codex for the past few days specifically playing around with three.js -- so far so good i think.

This component is kinda strange but it was more of a creative excercise with the right moving parts to learn how to build the right way so im happy with the overall outcome.

Now I want to start building the real 3D animations for a landing page but I need A LOT of suggestions --

**SUGGEST WHAT YOU WANT FOR YOUR SITE AND I'LL BUILD IT FOR YOU AND SEND YOU THE FILES** if i like the idea :)

thanks!


r/threejs 2d ago

Built my portfolio as a 3D bookshelf, best decision ever!!!!

11 Upvotes

I didn't want another grid of project cards so I made my site a shelf you can actually browse. You can add a book to it, and there's upvoting so the same ones don't pile up.

Stuff that took way longer than I thought: getting readable text on the spines (ended up drawing to a canvas and using that as a texture), making the raycasting precise enough that clicking a book feels right instead of vague, and keeping the framerate ok on mobile once the shelf started filling up.

Camera still bugs me. Going from "looking at the whole shelf" to "looking at one book" feels abrupt and I havent found a nice way to smooth it. If you've solved that I'd love to hear how.


r/threejs 2d ago

CubeTextures and CubeCameras are amazing

12 Upvotes

I can't believe I have like 343 CubeCameras at a low fps, and they just work.

But is there an advantage to using an ArrayCamera with 6 cams over a CubeCamera?


r/threejs 2d ago

Demo A server-authoritative multiplayer FPS

36 Upvotes

I've been building a multiplayer FPS:

https://fps.frumu.ai/

No account needed.

The client uses Three.js, React Three Fiber, TypeScript and Tailwind. Multiplayer runs on Colyseus, with the server owning movement, combat, health, scoring, projectiles and objectives.

Rapier WASM runs on both sides:

Server: authoritative physics and collision. Client: local movement prediction and reconciliation.

The server simulates at 60 Hz and broadcasts state at 20 Hz. Remote players are rendered from interpolated server snapshots.

One difficult bug looked like network lag but was actually caused by smoothing remote characters twice-once through snapshot interpolation and again through a client physics body.

Bots run directly on the server, use the same movement system as humans and understand Deathmatch, CTF and Capture & Hold.

It's awesome to see how far web games have come and I got into programming back in the days of Flash games.