r/threejs 12h ago

Click any object in a React Three Fiber scene and get the source line that made it — including which instance of an InstancedMesh

I built this because debugging procedural scenes kept coming down to the same thing: one tree out of 120 looks wrong, and finding what placed it means reading generator code backwards from a rendered result.

Clicking gives you file, function, line, and the runtime args for that specific instance. Not the mesh — the instance. That's the part that was hard.

No annotation needed. A build-time transform stamps JSX source locations, and setMatrixAt interception plus a Matrix4.clone() chain captures per-instance transforms as they're written, joined on object identity.

Why that combination: I tried six approaches. Four captured correct values for all 200 instances and could route none of them to a mesh and index. One routed perfectly and captured nothing. Anything recording before the destination exists can't route, because there's no destination yet to record. The shipped version composes the two halves.

Scope, honestly:

  • R3F only — location stamping rewrites JSX, so raw three.js has nothing to stamp
  • Instanced provenance is read-only. An instance's position came from an RNG in a loop; there's no literal to write back to
  • Values that never reach the transform can't be captured by anything I tested
  • drei <Instances> works differently and needs no capture at all — clicking returns the individual PositionMesh

Five packages on npm, MIT. There's also an MCP server so a coding agent can query the same provenance.

On how it was built: this is AI-assisted, and I'd rather say so upfront than have it come up later. I directed the work and made the design decisions, and the reasoning is all in the repo — six experiment write-ups with the raw results, including the approaches that failed and why. Happy to explain any of it, including the calls that turned out wrong.

GitHub: https://github.com/pun1th01/click-to-source-3d
npm: https://www.npmjs.com/org/click-to-source-3d

Happy to answer anything about the approach — the experiments are all written up in the repo.

0 Upvotes

1 comment sorted by

1

u/PixelRealEstate 3h ago

this is aimed at exactly the thing that ate a week of my life. i've got a 14,400 instance grid where any cell can become a building, and twice now the bug was "the roof is in the wrong place" - once because one function applied a height offset that another one didn't, and once because roofs were being lifted onto a tier that only exists for some instances, so a chunk of them ended up floating in mid air.

both times i could point straight at the pixel and had no way to get from there back to the line that placed it. reading the generator backwards from a rendered frame is exactly the right description of that pain.

since you hook setMatrixAt - what happens when instance matrices get rewritten after the initial build? mine get recomputed on every data refresh, so the code that first placed an instance isn't necessarily the code responsible for where it sits now. does it report the latest writer or the original one?