2023 >
I’ve made a lot of use of the HTML5 canvas drawing API in recent iterations of the games on here, so I thought it worth taking a look at drawing using the more performant WebGL technology. My games didn’t really need this speed-up, but I could see this becoming an issue in the future and wanted to get ahead.
The WebGL requirements are much lower-level than that of the canvas API. No longer can you simply write “draw a line from here to here”. Instead, you are directly manipulating shaders that will eventually be used in a computer’s GPU, and that requires writing shaders, often from scratch. I quickly realised that this wasn’t really what I wanted to do, and so began looking for a light library to do this sort of thing for me. What I really wanted was an API that looked identical to the canvas API, but would do so in WebGL. If such a thing exists, I did not find it. What I did find, however, was threejs
, a rendering library that gives sufficiently high-level control over objects that it then handles the shaders for. I’d been a bit snobbish about this sort of library in the past, as it abstracts a lot of other things that I was happy to do away, but in the absence of alternatives, I conceded to use it.
With this new tech in hand, the next stage was to pick a project. I opted for trying to build a solar system, since there’s sufficient complexity that I’d need to handle outside threejs
that I’d feel like it was worthwhile. threejs
has a decent set of tutorials that get you set up, and although their property names are sometimes a bit unweildly shorthand, it’s not too hard to get to grips with. It also works off a decent class system that fits quite well into the game paradigm.
The first thing that struck me was how simple the lighting was to set up. Calculating things like shadows and reflections is no small feat, and yet the library abstracts this away so all you have to do is create a light source and pick a material that ‘accepts’ shadows for your object. For a solar system, this makes things a tad confusing, since a sun must both be an object and a light source imposed over one another. What’s more, working out if a sun should accept shadows or not was a bit mind-bending (Turns out, no, they shouldn’t).
Without too much technical effort (although a significant degree of calculation for the physics) The solar system was up and running (or spinning, as celestial bodies are wont to do). In particular, making a solar system that is actually aesthetically pleasing requires some severe tweaking of gravity, otherwise planets tended to either just fly off into the far flung reaches of space or instantly drop perilously into the sun.
(Gif of a planet falling into the sun)
With my set of circles happily rotating round each other, I thought I’d add some more detail to my new miniature universe by having bodies exchange mass, so that larger stars would effectively cannibalise smaller ones that got too close. It was at this point that I realised that I’d need more than just the built-in shapes that threejs
provides. And to do that, I’d probably need to delve into 3D modelling.
And so the solar system orbits slowly on. It feels like I’ll need to pick this up after I’ve acquired some more skills, and historically means that I won’t ever work on it again. So here it is, in all it’s glory.
(Image of the complete solar system)
You can play around with it yourself (here)[/solarsystem]. Marvel at the weird texture issues around the poles that I have no idea how to fix, and the occasional heart-stopping moment as you see 2 planets on a collision course, only for them to phase harmlessly through each other.