Procedural furniture generator for Autodesk 3ds Max.
Generate render-ready sofas, beds, chairs, tables, storage and decor — or an entire furnished room — from a single panel. Every result is reproducible from its seed.
Getting started · User guide · Architecture · Extending · Русская документация
| Scandinavian | Luxury |
|---|---|
![]() |
![]() |
| Brutalism | Mid-century |
![]() |
![]() |
The images above are generated output already used by the project documentation site. They show the same furniture category under different style presets, so silhouette, proportions, leg geometry, materials and palette change together rather than only recolouring one model.
FurnGen builds furniture the way a modeller would: a frame, a filling that pushes against its cover, folds where fabric sags, and a seam that catches the light. It does this procedurally, so no two generated pieces are identical — but the same seed always rebuilds the same piece, down to the tilt of each cushion.
| 28 furniture types | across six categories, all at real-world scale in centimetres |
| 8 style presets | each driving proportions, armrest shape, leg type and palette |
| 5 upholstery fabrics | bouclé, velvet, linen, cotton, leather — each with its own bump and sheen |
| 2 room sets | a living room and a bedroom, coordinated in one click |
| Renderer-agnostic | Corona when it is active, PhysicalMaterial everywhere else |
| Built-in QA | every item is validated for scale, materials, geometry and naming |
Requirements: 3ds Max 2020 or newer. Corona Renderer is optional.
-
Download the latest archive from Releases, or build it yourself:
node tools/package-release.mjs # -> dist/FurnGen-1.0.0.zip -
Unzip anywhere on disk. Keep the folder intact —
FurnGen.mslocates its modules relative to its own path. -
In 3ds Max: Scripting → Run Script…, select
FurnGen.ms, press Open. -
Optional, for a permanent toolbar button — run this once in the Listener:
FurnGenRegisterMacro()
Then Customize → Customize User Interface → Toolbars, category FurnGen, and drag FurnGen Panel onto a toolbar.
Set your units. FurnGen authors everything in centimetres. Use Customize → Units Setup → System Unit Scale = Centimeters. The QA check warns you when the scene disagrees.
Press GENERATE. That is the whole workflow.
To explore, press Randomize a few times at Draft quality, note the seed of a result you like, then switch to Production and regenerate it. Same seed, same furniture, more polygons.
-- Or drive it from script, bypassing the panel entirely:
local cfg = FurnGenConfig()
cfg = fgApplyStyle cfg #japandi
cfg.fabric = #linen
cfg.seed = 481207
cfg.quality = 2
local bed = fgBuildItem cfg #bed #bedKing| Category | Types |
|---|---|
| Sofas | straight · corner · modular · loveseat · chaise longue · armchair optional styling: a throw draped over the armrest, two tilted accent pillows |
| Beds | single · double · king · four-poster upholstered frame, mattress, headboard, draped duvet, pillows |
| Chairs | dining · bar · lounge · stool rear legs continue into the backrest; the bar stool gets a foot ring |
| Tables | dining · coffee · side · desk · nightstand aprons, drawer units, brass hardware |
| Storage | wardrobe · dresser rail handles, three-drawer fronts, brass knobs |
| Decor | pouf · rug · floor lamp · bookshelf · TV console · plant · mirror the bookshelf stacks randomised books; the plant grows unique stems |
| Room sets | Living room — sofa, rug, coffee table, lounge chair, pouf, floor lamp, side table, bookshelf, plant Bedroom — bed, two nightstands, dresser, wardrobe, rug, bench, mirror, plant |
| Style | Character |
|---|---|
#modern |
Squared arms, block legs, cool greys |
#minimal |
No legs, no piping, off-white palette |
#scandinavian |
Rounded arms, tapered light-oak legs |
#japandi |
Low profile, muted earth tones, dark wood |
#luxury |
Velvet, brass, deep jewel colours |
#classic |
Wide rolled arms, piping, warm browns |
#brutalism |
Floor-sitting, firm cushions, concrete greys |
#midcentury |
Bolster arms, splayed walnut legs, ochre and teal |
Every soft part runs through the same four-stage pipeline:
ChamferBox base shape with a generous fillet
↓ Push inflates along normals — the filling pressing outward
↓ Noise fractal folds; a second finer pass adds wrinkles
↓ TurboSmooth subdivision for a soft silhouette
Uniqueness comes from seeded jitter applied to positions, dimensions, tilts and to the seed of every Noise modifier. Piping is a renderable spline traced around the cushion perimeter, so the seam is real geometry rather than a texture.
Read more in Architecture.
FurnGen never leaves a part grey. Material creation is a three-tier fallback:
- CoronaPhysicalMtl — only when Corona is installed and is the active renderer. Corona materials render black or grey under other engines, so this is checked, not assumed.
- PhysicalMaterial — for Scanline, Arnold and ART.
- StandardMaterial — last resort, when no colour property accepted a write.
After every colour assignment the value is read back and verified. If the
write silently failed — which happens when Autodesk or Chaos renames a property
between versions — the material is downgraded and a FurnGen MTL WARN line is
printed to the Listener. Node wirecolor is driven from the material too, so
colour reads correctly even in Object Color viewport mode.
node tools/lint-maxscript.mjs # lint all MAXScript sources
node tools/package-release.mjs # build dist/FurnGen-<version>.zip
pnpm dev # run the documentation siteThe linter is dependency-free and checks what actually breaks MAXScript:
unbalanced parentheses and brackets, local declared outside a scope, unknown
fg* helper calls resolved against the real module load order, missing
FurnGenConfig fields, unclamped ChamferBox fillets, and non-ASCII drift.
See CONTRIBUTING.md for the workflow and docs/en/extending.md for adding a furniture type.
src/
FurnGen.ms entry point — resolves and loads modules in order
modules/
core.ms config struct, seeded RNG, style presets
geometry.ms soft blocks, cushions, armrests, legs, piping
materials.ms verified PBR material factory
sofa.ms sofa assembly
furniture.ms beds, chairs, tables, storage, decor, room sets
qa.ms post-build validation
ui.ms the panel
tools/
lint-maxscript.mjs static analysis for .ms sources
package-release.mjs dependency-free zip builder
docs/en, docs/ru documentation
app/, components/ documentation site (Next.js)
Procedural generation gets you convincing furniture, not simulated cloth. Folds are noise-driven, so a duvet will not settle around a pillow the way a real cloth solve would. For hero close-ups, generate at Close-up quality and finish the drape with Cloth or Marvelous Designer.






