• Register

ScrumbleShip is the most accurate space combat simulation devised to date. Gather resources, construct a capital ship out of individual blocks, then pilot it with AI or human help against other players.

Post news Report content RSS feed Shaders so sharp you'll cut yourself

We increased the number of polygons on screen by a factor of 10. Here's how.

Posted by dirkson on Sep 20th, 2013

The Difference

September 10th September 20th

Go ahead, click both of those images so they show up full size. Don't worry, they'll pop up in new tabs.

Ten days ago, my game looked like the image on the left. Today, it looks like the image on the right.

Wow! Looks a lot better, doesn't it? But every graphical improvement has a price... So how much slower does the game run now?

Well, all of these graphical improvements come at the cost of a huge performance improvement.

Wait, what?

But first, the news.

Before we start, let's stop for a moment and talk about voxels, just so everyone's on the same page.

No 3D object in ScrumbleShip is textured.

ScrumbleShip renders its world using voxels, which are the 3D equivalent of your monitor's 2D pixels. In ScrumbleShip, these are shown as small, untextured cubes. We also have "blocks", which are collections of voxels 16 long, 16 thick, and 16 tall. So every block we put on the screen is composed of 16*16*16, or 4096 tiny cubes. This allows for some cool tricks, one of which we'll talk about today.

Now on to the improvements!

Order and Chaos. Well, ordering. Lots of ordering.

The most obvious improvement between the two images is the view distance, which has at least quadrupled. Hundreds of blocks that used to be rendered as featureless blanks suddenly pop into full view.

The big thing that allowed me to do this was changing the order in which I hand voxels to the graphics card. Nearly every opengl tutorial I've seen makes at least passing mention of drawing the scene from front to back, but I had always discarded this as a potential minor optimization - Nice for some day, but not really vital for now.

I was very, very wrong.

It turns out that modern graphics cards are remarkably efficient when scenes are drawn front-to-back. For the average ScrumbleShip scene, they're over ten times as efficient. So where we used to struggle along at 20-30fps with 100,000 voxels, now we can see a million voxels at 30-40fps.

End result? Wonderful scenes like these, rendered at playable speeds:


VSync? More like VSunk.

When I originally re-ordered the voxels, I had some very interesting results. My render times instantly went "Non-linear". In other words, I could suddenly render 1 million voxels at the same frame rate as 100,000 voxels.... And that frame rate was 22 frames per second.

22FPS is... not awesome.

So what was going on? If I could render a million voxels slowly, why couldn't I render 100,000 voxels quickly?

The answer turned out to be in the vsync features of ScrumbleShip. Before the graphical update, more than 30fps was basically wasted effort, so I'd told one of our libraries to "sync" the image with every other frame your monitor displayed. Well, due to the particular sub-millisecond timings of these events, the best the engine could do was sync with a small handful of these events.

In short, turn off the vsync, and the framerate soars to 30-60fps.

Using a shader to shade things

Another large graphical improvement comes in the from of an absolutely tiny effect - I vary the color of each side of each voxel by 10%. This simulates some of the effects of diffuse lighting in the real world, and suddenly the 3D nature of objects "pops", and the tiny cubes actually look like tiny cubes.

Here's an example using some heavy damage on some factory blocks:

Voxel Damage Improved

I do use a little trickery here - I color the "top" of the voxel a little brighter than the "bottom". This poorly simulates the way light in space would work, but it correctly simulates our everyday experiences walking around with the sun overhead, so it ends up looking more natural to the human eye.

This process is done entirely in something called the "Fragment shader" of the graphics card. This fragment shader is designed to manipulate hundreds of megabytes of textures across the entire screen. Since ScrumbleShip doesn't deal with textures, we've been badly under-utilizing the fragment shader. It's basically like having Vincent Van Gogh paint your house.

Since this lightening/darkening process is done within an under-utilized portion of the graphics card, it cost us 0fps - A free improvement!

The wizard of LOD

Before EightCache EightCache

Another change I made is the introduction of a Level-Of-Detail system. Previously in ScrumbleShip, any individual block was either "High Resolution" (16x16x16 voxels), or "Block Resolution" (1 big voxel). This created a somewhat jarring effect when trying to look at things in the distance. Because, well, you couldn't.

The big breakthrough was when I realized that people couldn't really see 16x16x16 blocks in the distance. Stuff got all blurry and it looks more like a lower resolution block, like maybe 8x8x8... Hey. Why not average some of the voxels and *actually* display an 8x8x8 instead of the 16x16x16 block? And after that, maybe a 4x4x4 block!

You can see the results of this system in the link above. The two images contain the same blocks, but the one with level of detail is miles ahead of the one without. The level-of-detailed blocks just end up looking slightly blurry.

What's next?

Well, there are still optimizations to make, that's for sure. I doubt I'll find another 10x improvement... But then, if you'd told me I would find a 10x improvement two weeks ago, I would have laughed at you.

All these changes are in the latest "bleeding edge" release, and will be making their way into the full, released version in another week or two.

The most obvious improvement to make is to send less redundant data to the video card. Because of the amount and frequency of the voxel data we send, there's a tiny hiccup every 5 frames or so, causing that frame to show up on the screen for 1-2ms longer than it normally would. Not a huge difference, but it might be worth a few FPS to fix.

Other than that, I really think it's time to focus on features other than the graphics. With these changes, I've finally gotten the graphics to a point where they truly look and perform well. Maybe I should focus on combat? Atmospheric simulation? Ship stress simulation? Tell me your thoughts in the comments, please!


Post comment Comments
Guest Sep 21 2013 says:

Wow. That's really awesome! Thanks for writing down what you learned. Those are some good lessons.

I noticed that you mention the speed up in FPS several places. It turns out to be easier to think about speedups if you measure things in the millisecond cost of the thing. The advantage is that if you have a target for FPS then you can calculate how many total ms you have for rendering and then divide those ms between each task.

When something takes 2ms and something else takes 3ms, that takes 5ms out of your budget. Try to do the math that simply using FPS. You can't. Instead, you end up having to convert the FPS to something else in order to be able to calculate the total performance hit.

This article explains it better than me: renderingpipeline.com/2013/02/fps-vs-msecframe/

+3 votes     reply to comment
dirkson Author
dirkson Sep 21 2013 replied:

Yup! I'm actually familiar with this. My user-facing metric is FPS, and my me-facing metric is a combination of millisecond timings and profiling using apitrace. (Only learned about apitrace the other day. Amazing stuff!)

It's also worth noting that there's a difference between the cpu time taken by commands the the gpu time taken. I haven't entirely sussed out the relationship(s), but apitrace is helping.

I just figure users and general readers are more familiar with FPS, so I went with that for the article.


+2 votes   reply to comment
Guest Sep 21 2013 says:

I would love to see more ship simulation get added. This game looks great and I cannot wait to be able to fully simulate a ship's functions.

+4 votes     reply to comment
zellman86 Sep 21 2013 replied:

I second this. 3D ship movement would be super cool!

+1 vote     reply to comment
Lulloser Sep 21 2013 says:

Nice one Dirk!
Now I am 100% pleased with the graphics on distance :D

I think the next step should be flying our ships and maybe add the function to fire weapons so we can actually try our ships :P

+3 votes     reply to comment
BurningPet Sep 21 2013 says:

Impressive work mate.

The main thing that is still bothering me is the UI, it is in a completely different style with the game graphics.

I took the liberty in demonstrating how a more fitting UI might look like:

If you like it, i can send you the open PSD file so you could extract the elements.

+3 votes     reply to comment
Insolent. Sep 21 2013 replied:

I actually quite like that UI! I'm sure Dirk will accept it as a mod - maybe even a togglable option in-game?

+1 vote     reply to comment
dirkson Author
dirkson Sep 21 2013 replied:

That actually... doesn't look too bad!

I *have* been wanting an alternative - For every UI compliment, I get one UI complaint. If you create block-ized versions of the rest of the gui options, I'd love to stick 'em in the game as an option.

Do you have a copy of the game yet? You should say hi: Scrumbleship.com


+1 vote   reply to comment
Guest Sep 21 2013 replied:

I really like that UI concept. Much more fitting with the voxel theme. Perhaps also have a shader to distort the view to look more like you're staring out of a helmet of a spacesuit.

The UI should definitely be a priority though.

+3 votes     reply to comment
Insolent. Sep 21 2013 says:

This was a triumph.
I'm making a note here: huge success.
It's hard to overstate my satisfaction.

Seriously, well done. I think you're right - the graphics and LOD systems are now at Tue point where you can focus on gameplay features. But which ones? Thinking of the way the game currently plays, I think atmospheric simulation and electricity would be a fin next step that would also help set the game apart. If you make players need air, then you'll turn the existing multiplayer play space into a survival game in which players need to build spaceworthy ships and asteroid bases to survive. :D

Of course, you'd want to implement electricity simulation either before atmosphere, or immediately after air pressure. Otherwise, where would the fresh air be coming from?

So yeah, air and power are my two cents for what to do next. It'll really highlight ScrumbleShip's physics-centric simulation, and be fun.

After those are in place, I think player models and player damage simulation is in order.

+3 votes     reply to comment
micromil Sep 21 2013 says:

The improvements look awesome and improved functionality - even better!

The next step would be a difficult choice, as it all needs to come together eventually.

If ship movement could be done and then the realism (power, fuel, structural stress, etc) filled in behind with minimal issue I know a heap of people would like that.

A close second would be Insolents Ideas of space worthiness testing.

+3 votes     reply to comment
Jacob843 Sep 21 2013 says:

Awesome! This really shows ScrumbleShip's beauty!

Personally, I would really like atmospheric simulation. Mostly because I know it will be complex, and complex things are fun! But I doubt that would happen in the next release, so full ship movements sounds good too!

+1 vote     reply to comment
Omyki Sep 23 2013 says:

i think you should begin to focus on some core gameplay features, to begin making the game experience evolve.

As to the order of these features i think you should begin, not with the ones that depend on others to work, but to the most basic ones, and then onto the more advanced ones. For instance, i would not recommend ship movement yet, since it depends on electricity, so as for a start, why not begin to insert electrical ability, generators. Then moving on to use this electricity somehow (displays, switches, stuff) and after that mabe some oxygen generators, and then the ability so suffocate, gaz physics, like if your ship is broken, the air would escape. Etc...

Keep on the good work, i've been following you for more than a year now

+3 votes     reply to comment
Jacob843 Sep 23 2013 replied:

Now that I think about it, this does make more sense. Implementing a backbone of resources into the game will make future features easier to make.

+1 vote     reply to comment
nadanova Sep 25 2013 says:

Some fantastic explanations here, I may just have to send some of my money your way in the near future for a copy ^^

+2 votes     reply to comment
BlackMoons Oct 1 2013 says:

Yes I am amazed how well 'early Z' depth culling works (What you get when you render front to back) 10~30% performance improvement in my game for most scenes for just rendering the nearest terrain 'first' to depth buffer only and then rendering the rest in random order.

Although I must note, Using alpha test/discard() disables early z optimizations. Avoid it for most rendering if you can!

+1 vote     reply to comment
Guest Oct 31 2013 says:

Atmospherics ftw!!!! :)

+1 vote     reply to comment
Post a comment

You are not logged in, your comment will be anonymous unless you join the community. Or sign in with your social account:

Windows, Mac, Linux
Developer & Publisher
Orangehat Tech
Custom Built
Send Message
Release date
Released 2011
Game watch
Start tracking
Post news
Related Games
ScrumbleShip Futuristic Sim
Related Groups
Indie Devs
Indie Devs Hobbies & Interests with 1,283 members
Indie Gamers
Indie Gamers Hobbies & Interests with 1,302 members
Linux Gamers
Linux Gamers Fans & Clans with 2,919 members
Open Source Game Development
Open Source Game Development Other with 39 members
Orangehat Tech
Orangehat Tech Developer & Publisher
Science fiction fans
Science fiction fans Arts & Literature with 691 members
Scientific software
Scientific software Educational with 13 members