PXLjs WebGL Engine first version


I've been working away on a pet project for some time now and it's hit the point where I feel I can say that a version of it, is there and more or less working. I call it PXL.js and yes, it's yet another annoyingly named javascript library. I sort of don't mind if people don't really use it, if I'm honest. This was more of a project born out of frustration with existing libraries and a need to see if I could do something better. It's been a challenge, trying to stick to one project and keep at it, but I'm glad I have.


PXL.js is a WebGL engine that does a few simple things such as loading OBJ files, dealing with textures, setting up cameras, generating curves and many other functions you may want to do. I started working on it about 4 years ago probably, under the name CoffeeGL, as I use coffeescript to write my code. I first remember seeing coffeescript when I was working at CASA, over at UCL and I liked the look of it very much. I decided to learn it and use it to make a library for WebGL. It seemed to cut out a lot of the nasty gotchas that javascript occasionally throws up (the double vs triple equals to mention but one). Soon after, I was working on WebGL projects quite a bit and it seemed that three.js was the library to use. For many things it seemed to work ok, but very soon, it became more limiting than empowering. I'd tried a few other libraries that were much worse, and made me want to tear my hair out. That said I ended up with a fair bit of knowledge about how JS work was done, and what WebGL could do.

I started with the user making their own shaders with some helper libraries, but it became clear that using materials and an ubershader might be the best way to go. You find yourself repeating a lot of shader-code for no good reason if you don't have some kind of lexer that builds your shader text from snippet of shader code. Using materials makes sense; it's a good way to think about shader effects, but its not the only way. I wanted to keep the door open for custom shaders as well as the times when you just want an ubershader to do the job. In the future, I'll be using ubershaders in other code too. It seems like the best way to go.


I use a scenegraph to keep hold of all the matrices and hierarchy you might need, taking the path through the nodes to draw things to the screen. This seems to work quite well but it could be made a lot more efficient using caching or perhaps someway of reducing the number of shader calls but on the whole, it makes sense to me at least and it seems to follow the way a lot of 3D programs seem to work, such as Blender. I'm quite proud of the maths library (even though it could be made better with some vectorisation) and learning the maths about curves was a lot of fun.

This project was mostly a learning exercise in how to write a coherent library for other people to use, including API documents, tests, full build system and plenty of examples. I've not really done that before, on my own at any-rate. I had to re-learn things like skeletal animation on the GPU, Shaowmapping, the Phong equation and all that good stuff. Given that there are loads of engines and libraries out there that do this, why would you bother? Well, it's mostly because I enjoy it, and the learning experience has been really useful. There's a lot going on in javascript land but I believe that the real good stuff is learning about concepts. Things like "how exactly do closures work?" and "what is the right way to present these functions to the user?" rather than worrying about using the right flavour of the month npm lib for your promises. My library doesn't actually depend on any others for it to work. Sure, you need to install browserify and a few other things to build the library, but the whole thing is written by me. This means I know it's foibles and can write better WebGL for anyone who wants it, and indeed I did when I did the equatorie. I get a bit defensive about it because I know that the way to go seems to be modular re-use and that I'm deliberately going against the grain but I think thats fine and healthy once in a while.


This library isn't done. I don't think any library really is but I'm glad I kept on with it, to the point where all the key bits are in place. Most of the code I've written has been small scale and I suppose this too but trying to get all the different mpoving parts into one coherent library for a larger audience is definitely a skill worth learning, even if other libraries exist. I deliberately didn't look too closely at the other WebGL engines as I figured working it out would be more worthwhile. It's very likely I'll move on to Vulkan and back to C++ land for a bit where the real graphics lives. I say real, you do get access to all the latest features on the various GPUs which is nice and indeed, the up-to-date shader languages, OpenGL specs and such. I'm at the point where I can just use this lib to make things and that feels nice. If you use it and like it (or even don't like it) do get in touch :)