That looks neat but why would you need a react-style reconciler to render a webgl scene? It's immediate mode...every frame is rendered according to the latest state available. What is even being reconciled?
Three.js has an imperative/stateful API for constructing and updating objects, not dissimilar to the DOM. So if your state lives in a separate place, then just like the DOM, you'd have to imperatively patch the view state to keep it in sync. Adding a layer that does this syncing automatically makes a lot of sense to me.
Doing it through React seems a little bit odd... but I haven't looked closely enough to understand why/whether this coupling is actually necessary
That makes sense, but it seems like a case of building an abstraction to solve a problem caused by another abstraction. If a scene graph creates a new chore for me that necessitates yet another dependency, i think it'd be simpler to not fuss with these layers at all. That's a choice i don't have with the DOM.
> i think it'd be simpler to not fuss with these layers at all
You should check out some example code for react-three-fiber (e.g. https://codesandbox.io/embed/r3f-bones-3i7iu). If you have any experience with writing raw webgl, it will become abundantly clear that something is gained by going through three.js before returning to React's more declarative style.
Most of the savings in the example are coming from three.js itself (not r3f), which is maybe the key point: three.js offers much more than a scenegraph, which is why it's worthwhile (check out the official examples to get an idea: https://threejs.org/examples/). Webgl as an API doesn't even really talk about 3d objects for the most part; the language it provides is primarily about moving data around in buffers. The difference in possible time savings in three.js vs webgl is on the level of writing in C vs an assembly language.
And once you're building an application with a non-trivial amount of state mutation (on which the view depends)—you're faced with the same dilemma as traditional web dev and the DOM, hence the desirability of react-three-fiber.
That said, I think it would be super interesting to see a three.js alternative that was 'natively' reactive/declarative, because I'll readily admit the tower of abstractions involved in writing a react-three-fiber app has its downsides. (Then again, I consider three.js to be a rare gem, know of nothing comparable in terms of simplicity/quality for building 3d apps, and would be [pleasantly] surprised to see anything like the above anywhere in the near future.)
Because of react's popularity, it's attractive to make a project that applies react's style of development to threejs.
Similarly, around 2013 threeQuery (threejs + jquery) was becoming somewhat popular too (it had a jquery "chain" api like syntax). It's good to see people experiment and attempt to improve developer efficiency. Who knows what new tricks will be discovered and what kind of benefit and new approaches will be created! However, I mostly agree with you.
I find threejs to be one of the most enjoyable libraries to work with (and its codebase is simple and beautiful too). I also highly recommend to everybody that wants to go into 3d graphics to dedicate some effort and learn the actual fundamentals (eg webgl, opengl, metal, matrix math, quaternions, etc).
This way you gain domain specific knowledge that is applicable across platforms and across time. Abstractions are not future-proof, they are recycled and change according to the latest trends in development. Domain specific knowledge stays with you forever! If there is an intermediate ground on which people can meet (eg start with react-three or three.js and then dive deeper) that's a win too. Recently I have been advocating that web devs can start learning 3d graphic concepts by just playing with... CSS to familiarize with some of the concepts and then move from there. This way one can avoid all the overhead around the gl statemachines or various libs and focus on the basic concepts first
You don't really have the choice with graphics either. The GPU keeps mesh and texture data in memory between frames, and I would imagine something similar happens for lighting, etc at some layer in the pipeline. Reconstructing the entire scene every time would not be feasible.
You can still hold on to references to textures and meshes you uploaded to the GPU without using a full-blown scene graph. Some state is necessary no doubt, but this seems more like unnecessary state that could be replaced by something more direct. But i don't know, i'm not familiar with three.js; the click handlers seem useful.
Regardless: the reason for having a base API be imperative is usually because it's maximally flexible and performant. By your own admission, any reactive API for 3D rendering will at least have to hold on to references to GPU objects in-between iterations, which means it could never be a truly stateless API; it would always be an abstraction over something stateful.
So given that constraint, I think it's better for the base API not to hide that statefulness behind an abstraction, and to leave the abstracting to a higher-level API
it allows you to create self-contained components. that alone will eradicate so much boilerplate and complexity. it has a real pointer event system. it takes care of managing the scene reactively, it disposes of objects it does not need any longer.
you use this for the same reason you would use react for the dom. r3f is not a wrapper that duplicates the threejs export catalogue, it is a renderer/reconciler.
Describing WebGL as immediate mode is a little misleading. The rendering is immediate but the API is definitively not. There is a ton of state that needs to be allocated up front, mutated rather than re-created, and eventually torn down. Buffers, textures, shaders, and uniforms are all retained state. There's also the whole OpenGL state machine.
OpenGL used to have a true immediate mode where you called a function for each triangle vertex, and you didn't need shaders or buffers. That mode is not present in WebGL.
I believe React developers think in terms of Components now as we used to think of Object/modules in the past. I personally find it easier to encapsulate logic into a Component because it seems more tangible than a plain JS file/module. You can also nest React components to compose logic, for example: composing multiple shaders.
> That looks neat but why would you need a react-style reconciler to render a webgl scene? It's immediate mode...every frame is rendered according to the latest state available. What is even being reconciled?
You don't, it might be a case of VRML cargo-culting or something.
While the DOM has some issues which makes React handy, Three.js and its "display list" have none of these problems, but I guess shoving React somewhere will translate in a better conversion for the authors of that article...
Doing it through React seems a little bit odd... but I haven't looked closely enough to understand why/whether this coupling is actually necessary