Case study
ADU Builder: from the drawing to the last coat
Five small backyard house plans, lifted off the page one construction stage at a time into a finished 3D model, with a materials list and a loan estimate. The numbers are an estimate, not a bid.

Why I built it
I kept looking at small backyard houses as drawings. A plan tells you the rooms. It does not tell you the order a crew builds the thing, and it does not tell you what the cottage in front of you might cost once the kitchen, the bath, and the utility runs stop shrinking with the square footage.
I wanted one page where I pick a plan, watch it come up off the paper, and read a number I can trace. Not a rendering someone emailed me, and not a cost-per-foot average with the math hidden.
What it does
There are five schematic plans: Twin Porch 288, Porch Cottage 646, Two Story 592, Module Five 640, and Carriage Loft 384. No lot address and no coordinates. They are drawings, not a survey.
The Porch Cottage is the one I keep opening. It is 646 square feet. Choose, floor plan, build, finished, and cost and loans are the same spec. The floor plan is the drawing the 3D model is built from, not a picture placed next to it.
Build plays the stages: site and footings, foundation, under-slab plumbing, slab, floor framing, wall framing, roof framing, sheathing, windows and doors, roofing, rough electrical, rough plumbing, HVAC, insulation, drywall, siding, interior finishes, and the last coat. Finished is the full model. Cost and loans is the takeoff.
What the numbers are
The cost file is a snapshot dated October 8, 2026. For the Porch Cottage the line-item total runs from a low of $77,240 through a mid of $180,304 to a high of $297,957. The low is every sourced line at its low, with no general-contractor markup. The high is every line at the top of a national range, which is a worst case, not a plan.
The number I use for planning is tighter. A local Eugene benchmark (Red Umbrella, about $210 to $350 per square foot, and a typical detached project that does not fall below about $130,000 because the kitchen, bath, and utility runs do not shrink) overlaps my line-item low-to-mid range at $135,660 to $180,304. That is the most likely range on the page. The mid estimate inside it is $180,304.
On that mid estimate, a 30-year construction loan at 6.50% is $1,139.64 a month. The rate is the Oregon State Credit Union one-time-close example stored in the financing file (6.50% rate, 6.54% APR in their example). The payment is principal and interest only. The page also shows a HELOC and a home-equity loan on the same principal, so the construction loan is not the only shape. Estimate, not a bid.
The sources behind the lines are in the data files: HomeGuide installed-cost ranges, a University of Oregon ADU cost note, Red Umbrella's Eugene band, Freddie Mac's weekly mortgage survey for the other rates, and the credit-union examples above. I did not type a single round number in and call it done.
How it's built
The app is a static site. Vite 8 builds it. The scene is three.js 0.186.1. I use WebGPURenderer and write the materials in TSL, three's node system, so the same graph compiles to WGSL on WebGPU and to GLSL on the WebGL2 fallback. WebGPURenderer does that fallback by itself. Custom GLSL patched in with onBeforeCompile does not run on the WebGPU renderer, which is why I did not start from a WebGL post stack and hope.
I picked that path after reading what actually ships in r186. GTAO, TRAA, and SMAA are TSL nodes in three's own addons. The older EffectComposer stacks are WebGL only. Textures are CC0 PBR from Poly Haven and ambientCG, packed as KTX2 and transcoded in the browser. The light is an HDRI studio environment. On machines where WebGPU comes up, a path tracer can keep sampling, and an OIDN denoiser (oidn-web, weights in the dist) cleans the raw trace. Where WebGPU does not come up, the raster path with GTAO still draws the house. Headless checks on a machine without a GPU fall down that WebGL2 path, which is the point of the fallback.
The first frames compile every material. The viewer exposes a warmed flag and does that pass before the stage scrubber is worth watching. If you skip it, the first second of the build animation is the driver compiling shaders instead of the house going up.
The wall bug
Plan space is a drawing: x to the right, y up the page. three.js is Y up in the world, so the plan's y has to become negative Z or the house mirrors. The helper that places a point does that flip. The helper that aims a wall has to do the same flip on both axes of the basis, the direction along the wall and the direction across it.
The first version flipped the point and forgot the across axis. Sheathing, siding, and the gable studs then faced the wrong way. Local Z of the wall pointed into the room, so the outside layers landed inside the framing, and the roof plane did not meet the plates. The fix is one quaternion: local X along the wall, local Y up, local Z toward the across vector after the same Y-to-minus-Z flip. Outward layers (sheathing, siding) also take a sign so the extrusion grows away from the studs instead of into them. Roof rafters and the gable infill use that same basis, which is what made the ridge sit on the plates instead of mirrored across the plan.
I checked it the slow way. Set the stage, dump which meshes are visible, and look. A framing stage with the sheathing on the inside is obvious once you stop admiring the lighting.
What I learned
A small building is a bad place to use a big building's cost per foot. The kitchen does not get cheaper because the bedroom got shorter. The most likely range is an overlap of two imperfect sources, and it is labeled that way.
Writing the materials as TSL nodes felt slower than a shader string, right up until the same scene had to run on WebGL2. The fallback is not a second app. And a quaternion bug in a wall basis does not show up in the console. It shows up as a house built inside out, which is a worse kind of quiet.
The code is not public. It stays off GitHub until I decide it is ready to publish.
Tech stack
- Vite 8
- three.js 0.186.1
- WebGPURenderer with TSL node materials, and an automatic WebGL2 fallback
- GTAO through three's TSL post stack, with TRAA or SMAA by device tier
- KTX2 (Basis) CC0 textures from Poly Haven and ambientCG
- An HDRI studio environment
- OIDN denoiser (oidn-web) on the WebGPU path tracer
- Line-item costs and loan math in local JSON, snapshot dated Oct 8, 2026
Common questions
Is the cost a bid?
No. The page says estimate, not a bid. The Porch Cottage most likely range is $135,660 to $180,304, from a line-item takeoff overlapped with a local Eugene benchmark. Get local bids before anyone digs.
What is the monthly payment?
On the mid estimate of $180,304, a 30-year construction loan at 6.50% is $1,139.64 a month. That is principal and interest only. Taxes and insurance are not in it. The 6.50% figure is an Oregon State Credit Union one-time-close example in the financing file, not a rate I was offered.
Is the code public?
No. The code for this one is not public.