A slow week with the project, largely due to the performance obstacle that I’ve run into. After last week’s block placement test, I decided to try rendering more and more cubes to see how many cubes my computer could render before it starts lagging.
I created two tests – 10000 cubes and 90000 cubes. My computer could still handle 10000 cubes, but 90000 cubes took ages to load and it was very hard to move in the environment. This is a bit of a problem, because I expect the number of cubes that need to be rendered to possibly be in the several hundred thousands. I made another benchmarking test – it turns out that my computer will drop to a single digit frame rate at about 22500 cubes.
Of course, I haven’t done any optimisations yet. Everything is in a simple array, and every cube is rendered individually. But not being able to handle 90000 cubes even at this stage is a worry. Even though three.js abstracts away all the low-level WebGL, examples like this, this and this make me feel as though that there’s got to be a way around it.
There’s a lot of posts on the internet saying that using shaders can improve performance for WebGL, but there’s a bit of a problem for me – I still don’t get what shaders are. They don’t only “shade”, you see – not nowadays, anyway. Shaders confuse me.
On another note, 0fps has some great tips on building a voxel engine. I’m not sure how easy run-length encoding plus an interval tree would be to implement, but it’s an idea alright. I’m still trying to figure out a good way to store my cubes so that:
- They don’t take up much space (the world can get large)
- It’s easy to read/write from the data structure
- I can get the neighbour of a cube easily
I have to say, optimising performance is one hell of a problem.
… oh and I’ve also figured out how to get textures working.
Why the random colours? I was too lazy to do anything else.
My project has evolved to the state of “webtoy”!
Here’s the latest demo – it’s a block placement test. Nothing fancy so far, but at least I have some functionality going on.
I have a few notes though:
- The crosshair may be slightly offcentre. I have yet to figure out how to fix this one properly.
- Try to use Chrome. The site will load fine in Firefox, but there’s a few bugs and I haven’t actually bothered to try testing in Firefox yet.
If anyone’s interested in how the block detection was done… the magic phrase is “ray casting”. I didn’t implement the ray casting myself though – three.js has a RayCaster class inbuilt. Also, the intersect function that three.js has even detects which face of the cube is selected, so that saved me a lot of work.
The other thing I had to figure out was how to convert from Euler angles to a direction vector. Luckily, StackOverflow is very good at questions like these.
This week marks the start of a semester long project I’ll be doing as part of a university course. The plan is to *whispers incomprehensibly* requiring WebGL and *whispers incomprehensibly* will probably be familiar to those who play Minecraft.
For now I have a WebGL page up here – initially i was going to make everything using WebGL directly, but after confusing myself with buffers and shaders I resorted to using the three.js library instead. It’s making my life a lot easier.
Here is a summary of my triumphs and failures in this past week:
- Getting the Pointer Lock API to work in Chrome: Pointer locking is where your cursor is disabled. It allows you to do things like spin around and around without having to worry about your cursor hitting the edge of your window. It took me a while until I realised that Chrome only allows pointer locking after some sort of user input (e.g. mouse click).
- Getting something to actually work: This. So far it only works in Google Chrome though – and the only other browser I’m planning to support is Firefox. That’s because these two browsers are the only ones which support the Pointer Lock API so far. Firefox has this annoying thing where the pointer locking only kicks in for full screen mode though…
So huzzah. I’m off to (some sort of) start.