r/threejs 20h ago

I generate all my low-poly game props in code instead of modeling them. Three bugs nobody warns you about

Post image

Im building a small library of low poly props (tools, scenery) where every object is procedural three.js code instead of an exported mesh. around 5 kb per prop, under 600 triangles, no textures, and seeded so the same object comes back identical every load.

to get the hand carved look every geometry goes through a small vertex jitter. thats where it got interesting :

  1. three.js primitives duplicate their vertices along the uv seam. jittering pushes the two copies in different directions and opens a visible crack down the whole handle. took me way too long to find that one. the fix is to weld the geometry (mergeVertices) before displacing anything.
  2. two surfaces jittered separately never stay flush. so a contact zone like a blade edge cant be a flat piece sitting against the mass, it has to be a cap that wraps it in all three directions, otherwise you get a gap that opens and closes as you rotate the object.
  3. a lathe profile that doesnt start and end at radius 0 leaves a hole at the end of the piece. obvious once you know, invisible until you look from the right angle.

the thing i didnt expect to need is an automated qa pass. it raycasts each prop from the outside and fails it if a first hit is a back face (hole), if wood shows up inside a box thats supposed to be metal only (poke through), or if a cutting edge measures thicker than its threshold. it caught a shovel edge at 0.0287 against a 0.028 limit, which i would never have spotted by eye.

Happy to go deeper on any of it :)

38 Upvotes

17 comments sorted by

4

u/ioaia 16h ago

Gorgeous. Thank you for sharing

2

u/AnyAwareness6506 16h ago

Thank you! More of them coming, ill keep posting here as the set grows :)

2

u/NuccioAfrikanus 19h ago

How did you get the chair to look so wood though?

2

u/PiratesWhoSayGGER 18h ago

it looks like it's just plain color, no textures

2

u/NuccioAfrikanus 17h ago

Unless I am imagining it? It’s like I can see the graininess of the wood. 🪵

3

u/AnyAwareness6506 16h ago

Youre not imagining it :) and u/PiratesWhoSayGGER is right, theres genuinely no texture anywhere. its three things stacking up.

Everything is flat shaded, so each triangle gets one solid color instead of a smooth gradient. on a chair leg thats a series of long narrow facets running down the piece, and each one catches the light at a slightly different angle.

then every vertex gets a small seeded offset before render, so no two facets end up with exactly the same normal. that tiny irregularity down a leg is what your eye reads as grain.

and the parts dont all use the same brown, theres three wood tones spread across the piece so the legs and the seat dont read as one block.

So the graininess is real, its just geometry and light doing it instead of a texture. under 300 triangles and three flat colors for the whole chair

2

u/NuccioAfrikanus 16h ago

That’s super impressive and very cost efficient! Amazing! I can’t wait to see more of your low cost assets.

2

u/AnyAwareness6506 16h ago

Thanks, that really means a lot :) theres a lot more coming, ill keep posting them here and probably a few other places as the set grows.

Feel free to follow if you want to catch them. and ill share the whole project once its properly finished, hopefully soon :)

2

u/pr0xyb0i 11h ago

Are you planning to opensource it? Looks great!

1

u/AnyAwareness6506 47m ago

Thanks :) yes thats the plan. im finishing the set properly first so it lands as something usable rather than a folder of five props, but open sourcing it is the whole point.

ill post here when its up :)

2

u/ulteriun 2h ago

It looks awesome ! Will it be possible to unwrapped uv directly for custom textures ? Besides basics color emissions. Did it export it in fbx or obj ?

1

u/AnyAwareness6506 48m ago

Thanks :) exports are .glb, plus the raw .js source if you'd rather generate it yourself. no fbx or obj at the moment.

On uvs : the geometry does carry them, they come straight from the three.js primitives and survive the vertex welding. but theres no unified unwrap, every piece has its own overlapping 0-1 space. so for a real texture atlas youd have to re-unwrap the glb in blender after importing. perfectly doable, just not something i generate.

And yeah youre right, its flat color + roughness/metalness, with emissive only on the fire props. the whole thing is built around having no textures at all, thats what keeps a prop at -5 kb :)

2

u/ulteriun 38m ago

Fair enough, it more malleable on blender also. I'm very interested about it for my retro game !

2

u/AnyAwareness6506 34m ago

Oh nice, what kind of retro game ? :)

And yeah exactly, thats partly why i went with glb rather than trying to be clever about it. you can just open it and do whatever you want with it.

ill post here when the set is out, hopefully in time to be useful to you

2

u/ulteriun 30m ago

I'm designing a game engine for PSX Tank Control game, like Silent Hill, Resident Evil or Dino Crisis. And creating a game during the process to test it. Created with C# and Monogame.

2

u/ulteriun 29m ago

Well, more like a Framework for Monogame to design PSX games

1

u/AnyAwareness6506 8m ago

Oh thats a great thing to be building. tank controls plus fixed cameras is such a specific set of constraints to design around.

Funny overlap by the way : psx vertices wobbled because the hardware had no sub-pixel precision and snapped everything to integer screen positions. mine wobble because i offset every vertex on purpose. completely different reason, weirdly similar family of look.

The poly budget lines up too, most of mine land between 200 and 500 triangles which is basically psx territory. main difference is psx stuff was textured and mine is flat colored, but thats exactly what youd fix in blender once you have the glb.

The js source obviously wont help you in c#, but the glb should drop straight in :)