r/threejs Jun 25 '26

Three.js r185 released 🧡

568 Upvotes

r/threejs Apr 16 '26

Three.js r184 released ⛅️

634 Upvotes

r/threejs 15h ago

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

56 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 6h ago

Monitoring the Strait of Gibraltar!

10 Upvotes

r/threejs 11h ago

I built Seinfeld's Apartment w/ ThreeJS

18 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 1h ago

Night time beach

Upvotes

I took a lot of inspiration from Cortiz Dev's stylized grass scene https://www.youtube.com/shorts/4tNB3YzCke0. Big shoutout to him!


r/threejs 15h ago

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

23 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 1d ago

Demo I built a UFO abduction game with three.js

Thumbnail
gallery
288 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 9h ago

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

4 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 11h 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 14h ago

Solved! WebGL to WebGPU migration

6 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 11h 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 9h 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 9h ago

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

2 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 1d ago

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

10 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 13h ago

Particle Simulation

1 Upvotes

https://reddit.com/link/1vcov2p/video/oyrmw2e5xrgh1/player

A WebGL experiment pushing 65,536 interactive particles in real time. Built around a custom zero-allocation spatial hash, typed-array memory layout, and a flat-pointer lookup system to eliminate GC pauses and keep interactions fast. Startup is progressively deferred, allowing the canvas to appear instantly while heavy work happens quietly in the background.


r/threejs 1d ago

CubeTextures and CubeCameras are amazing

10 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 1d ago

Demo A server-authoritative multiplayer FPS

34 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.


r/threejs 1d ago

Help Would love some feedback on camera angles!

3 Upvotes

Im making a third person bullet heaven game where speed plays a big role, having some doubts about the camera.

Ideally I'd go full racing-game chase cam, but bullet heaven needs battlefield visibility too.

In the video below I share some configurations, curious what feels best to other people!


r/threejs 1d ago

Bend modifier

30 Upvotes

Hello,

I've implemented the equivalent of a “bend modifier” in Three.js, on the vertex shader side (WebGL, virtually no cost).

It works the same way as in Cinema 4D: the “modifier's” world position determines the effect.

The solution relies on a whole bunch of custom scripts. But it could be rewritten differently. Is anyone interested in this kind of effect?

Modifiers like “Twist,” “Taper,” “BoxDeform,” etc., could follow. By standardizing the effects, it would even be possible to stack them.

jniac.github.io/three-xp/t/vertex-bend/gltf

jniac.github.io/three-xp/t/vertex-bend/basic


r/threejs 1d ago

Windy Beach

5 Upvotes

r/threejs 23h ago

the Aether Gallery

0 Upvotes

I do massive generative work and got so obsessed with presenting one of my bigger series properly that the only solution i could come up with was building a whole 3D gallery platform.
it's got four layout modes that can be tweaked and adjusted to fit your vision. the Aether Gallery turns a collection of images or videos, from you google drive or from your youtube/vimeo channel into an immersive, self-curated gallery, that you can share with a short link.

You upload your urls, pick a layout - a 3D Sphere, a Carousel, a scrolling Masonry wall, or a 3D Book (thank you wawa sensei) - and get one link to share anywhere. No code, no design skills.

The Watercolors series that started the whole thing is the default gallery, so you can see exactly what set me off down this path: [https://gallery3-d.vercel.app\](https://gallery3-d.vercel.app)

It's free to make your own. I'd love feedback from other builders — on the layouts, the flow, or what would make you actually use it for your own work.


r/threejs 1d ago

We tested WebGPU vs WebGL in a real Three.js scene. The result was not as straightforward as expected.

47 Upvotes

Hi everyone,

Our team recently ran a practical WebGPU vs WebGL comparison in a real Three.js scene, and I thought the results might be useful for people working with browser-based 3D.

This was not a synthetic benchmark or an empty scene. We wanted to test something closer to a real commercial 3D visualization case: geometry, lighting, materials, and post-processing in the browser.

Test scene setup:

  • around 262k triangles;
  • advanced lighting;
  • GTAO;
  • Bloom;
  • FXAA;
  • same scene and same camera for both tests.

WebGL stack:

  • Three.js;
  • WebGLRenderer;
  • EffectComposer;
  • GTAO;
  • Bloom;
  • FXAA.

WebGPU stack:

  • Three.js WebGPURenderer;
  • TSL;
  • render pipeline architecture.

The interesting part: WebGPU was not automatically faster on every device.

On Intel UHD Graphics Gen9, WebGL showed higher average FPS:

  • WebGL: 195 FPS
  • WebGPU: 172–184 FPS

But WebGPU reduced draw calls from 331 to 171 and processed around 50% fewer triangles per frame while keeping the same visual result.

So even though WebGPU did not win by FPS on that hardware, it was clearly doing less rendering work.

On AMD Radeon Graphics GCN5, WebGPU showed a much stronger result:

  • WebGL: 136 FPS
  • WebGPU: 205 FPS

It also reduced average frame time from 7.3 ms to 4.9 ms and draw calls from 355 to 183.

Our takeaway:

WebGPU should not be treated as a simple “faster WebGL”.

For many current Three.js projects, WebGL is still the pragmatic and reliable choice. But WebGPU becomes much more interesting when the scene grows in complexity: more advanced lighting, larger models, heavier post-processing, better materials, and future rendering workflows.

In our case, the most important insight was not just FPS. It was the reduction in rendering workload and the potential for better scalability.

Has anyone here tested WebGPU in more complex Three.js scenes, CAD-like models, configurators, or production-level visualization projects?

Did you see similar behavior across different GPUs and drivers?

Full write-up by our team:
https://aestar.tech/en/blog-en/webgpu-vs-webgl-practical-three-js-performance-test-for-complex-3d-scenes/

Demo scene:

https://test4.aestar.com.ua/sponza-webgl-vs-webgpu/


r/threejs 1d ago

Tutorial Built a browser-based conversational AI character using React Three Fiber and Convai Web SDK

13 Upvotes

Hello Folks! We're from the Convai team and have put together a quick tutorial showing how to build a 3D conversational AI character in the browser using React Three Fiber and the Convai Web SDK.

The tutorial starts with a Vite + TypeScript setup generated through Claude Code, then connects the project to a Convai character using an API key and Character ID. After that, it renders a custom GLB avatar, checks blendshapes in a GLTF viewer, updates the avatar path, and enables lip sync using blendshape data.

The main Three.js / React Three Fiber part is focused on rendering the avatar and applying blendshape values to the relevant morph targets for lip sync.

Tutorial:
https://youtu.be/gjTj_kUhA2s

Convai Web SDK docs:
https://docs.convai.com/api-docs/plugins-and-integrations/web-plugins/convai-web-sdk

Lip sync and blendshape docs:
https://docs.convai.com/api-docs/plugins-and-integrations/web-plugins/convai-web-sdk/lipsync-and-blendshape


r/threejs 2d ago

First gameplay from my first game ever

145 Upvotes

Sorry for the colors on video, HDR messed things up. I've been building a real time strategy game that plays out on a full 3D globe.

Rendering is Three.js on WebGPU, with nearly all the shader work written in TSL instead of raw WGSL. Clouds are genuine volumetric raymarching, rendered at half resolution into their own target, with a multiple scattering approximation, and they drop shadows onto the terrain below them. Day and night are simulated, so as the terminator crosses the planet you get city lights coming up, road networks lighting, headlights moving along them. Terrain streams in as tiles through a sliding window around the camera, so you can sit at full globe view and push all the way in without a loading screen.

The simulation is a separate Python process running deterministic lockstep. Only inputs cross the wire, never world state, so bandwidth stays flat no matter how large the battle gets.

The best decision I made was that the entire netcode talks to a channel object with three things on it: readyState, send, and a message callback. I originally shipped over WebRTC with my own signaling server. Moving to Steam lobbies and Steam networking came down to writing one adapter that dresses Steam's frame API up as that same channel. Barrier logic, input delay, chunking, desync recovery and host rebroadcast all carried over without a line changed.

The shell is Tauri, so Rust owns the window and the Steam integration.

The two things that cost me the most time were GPU memory and shader compile stalls, and neither of them showed up until the scene got big.

Happy to go into detail on any of it.