Mar 312013
 

Here’s a quick video of something I’ve been working on recently:

This is just an experiment in coming up with a more interesting ray-marched scene to test out graphics techniques. It may be developed into a proper demo at some point, but that probably requires more artistic input than I’m able to give, so we’ll see.

What we have here are two infinite length boxes, with X and Y coordinates rotated around the Z axis depending on Z. Another box is intersected at intervals to break it up a bit. Finally a texture is used to add some small-scale surface detail. So there’s nothing particularly interesting about the base shape.

The background environment map was made in Spacescape, an awesome little program for drawing sky boxes of stars and nebulae. and then baked into a cubemap. The basic rendering is much the same as I talked about here. There is also an implementation of the Bokeh depth of field presented here (which I’ll post a bit more about at some point), and lots of point lights rendered using an implementation of the tiled deferred shading presented here.

I’ve not really worried about optimisation but it’s currently running at around 100fps at 720p on my HD7950.

Mar 122013
 

Last time I talked about basic ambient and diffuse lighting.  This is good for perfectly matt surfaces, but every real surface has some degree of specularity, which is when light is reflected off a surface to give a shiny appearance.  You may not think of most objects as having a shiny surface, but it’s a significant part of the look of almost any surface.  If you want to see for yourself, take a look at this article which shows you how to split up the light from any object into specular and diffuse components.

Specular from perfect mirrors

Light reflects off specular surfaces in exactly the same way as a mirror (because mirrors are in fact just very flat surfaces with pure specular reflection, and no diffuse lighting).  If you have a point light source, you can work out the reflection direction by reflecting around the surface normal.

Mirror reflections

When looking in a mirror, you see the reflection of the light at the point where the reflected light direction goes directly into your eye. If you work backwards you can see that each point on the surface of the mirror will reflect light from a different point in the world. Mirrors are the simplest case because they are completely flat, meaning that light from a point in the world will only be reflected towards your eye from one point on the mirror.

Imperfect reflections

Most surfaces aren’t perfectly flat, and so don’t have perfect mirror reflections. If a surface isn’t perfectly flat it means that the normals around a given point will be pointing in lots of different directions. On average the normals will all point directly away from the surface, but if you look close enough at a rough surface (e.g. tarmac) you’ll see lots of surface facets pointing in different directions.

When we’re far enough away from the surface, all of these surface facets will look small enough that they occupy just one pixel on the screen, or one receptor in our eye. However, the distribution of the normals still affects how it appears to us.

Reflections from rough surfaces

What we see in the diagram is that one pixel on a rough surface actually reflects light from lots of different directions. The strongest reflections are from the ‘mirror’ reflection direction, with the reflection strength tailing off the further you get from this (because on average more of the surface facets will be pointing in the normal direction). What this means is that if the light source is at A then you’ll get a very bright reflection because lots of the light is reflected towards the eye. If the light is at B then there will still be some reflection but it will be weaker. This is why shiny surfaces have sharp, bright highlights and rough surface have blurry, dim highlights.

Implementation

To calculate the specular highlights from a light source at a given pixel, we first need to find out how much the angles all line up. We need three pieces of information at each pixel:

  1. View vector. This is the vector from the pixel to the eye, in world space. It is calculated in the vertex shader and interpolated for each pixel.
  2. Normal vector. This is part of the data for each vertex in the mesh, and interpolated for each pixel. Normal maps can also be used to provide more detail (I’ll talk about those another time).
  3. Light vector. This is the vector from the light to the pixel, and for distant light sources is constant for all pixels. For near light sources this is calculated in the vertex shader, the same as for the view vector.

Now we need to find the halfway vector, which is half way between the view and the light vectors.  To find this, simply work out (lightVecviewVec) and renormalise.

Then take the dot product of the halfway vector and the normal, which will give you a value for how aligned the two are. This value will be 1 if the vectors are perfectly aligned, and zero if they are at 90 degrees. It should never be negative (as this would mean you are viewing a surface from behind it) but it’s possible due to the way things are interpolated sometimes.

The next part is to come up with some simple way of simulating the rough surfaces, in particularly how all the normals reflect light from different directions.  Because the dot product is between zero and one, the simplest way is to just raise it to a power – higher powers cause the value to drop off quicker the further the halfway vector is from the normal, leading to a sharper highlight. The full specular equation is then:

spec = pow(dot(normalize(lightVecviewVec), normalVec), specularPower) * lightColour

Varying the specular power will change the sharpness of the highlight. Here are examples of just the specular lighting with powers of 2 and 20:

Specular power of 2

Specular power of 20

 Add this to the other lighting and you start to get a more believable image:

Specular, diffuse and ambient lighting

Better specular

The problem with this method of doing specular highlights is with the simplicity of just taking a dot product and raising it to a power.  This method is chosen because it looks “about right” and is very cheap to calculate. It isn’t based on anything fundamental about the way light behaves, and because of this it will never produce photorealistic images.

In a future post I’ll talk about Physically Based Rendering (PBR), which boils down to a more complicated method of doing specular highlights, but a method that is based in the real-world behaviour of lights and surfaces. It is an advanced technique and has only been widespread in games for the last few years, but it given much nicer results (and the cost of being a lot more expensive to calculate).  Anyway, I’ll come back to this in a future post.

Next time I’ll talk about normal mapping, which allows much more detail to be put into lighting models.

Mar 022013
 

Lately I’ve mainly been playing a couple of shooters at different ends of the same evolutionary path.  They are Planetside 2 and Wolfenstein: Enemy Territory (henceforth called ET).

Wolfenstein: Enemy Territory

I’ll start with ET, as it’s pretty old now and you might not have come across it.  It’s a free game that started out as an expansion to Return to Castle Wolfenstein, but was never finished and simply given away as a standalone game.  Amazingly I’ve been playing this on and off with my gaming group for eight or nine years now, and it still gets an enthusiastic response.

Wolfenstein: ET Seawall Battery

This is purely a multiplayer game and was an early example of lots of the things you see in modern shooters. It has asymmetrical gameplay, with an attacking and defending team. It’s purely objective based, with a string of objectives for the attacker to accomplish within a time limit.  It’s class based, with five distinct classes. And it has an XP and levelling system.

Our favourite map is Fuel Dump.  The Allies are attacking and first must escort a tank across a bridge, with their engineers keeping it repaired while the Axis team rain down air strikes and sniper shots. Oh, and the bridge requires building before the tank can cross, and every time it’s built the Axis team seem to blow it up again.  Then the tank is driven through a tunnel system before finally blowing a hole in the fuel dump wall.  Finally the Allies have to get into the base, destroy the gates with explosives and plant the dynamite.

The longer maps can be a bit of a gruelling slog, repeatedly running out into the defenders’ guns as you inch closer to achieving the objective, but when you finally get that dynamite to blow seconds before the 30 minute timer runs down, it’s really rewarding. The classes are varied – the engineer is the most generally useful as most objectives require building stuff or blowing stuff up, but you’ll likely die a lot. Soldiers have heavy weapons (switch to the Panzerfaust if you’re getting frustrated at not getting any kills…). Covert Ops can steal uniforms and snipe. Medics pick everyone up again when they go down. Finally, Field Ops get love and hate in equal measure as a well timed airstrike takes out three enemies in one go, or you wipe your entire team with a misplaced flare canister throw.

Wolfenstein: ET Gold Rush

It’s not the most accessible game ever, likely because it wasn’t ‘finished’. There are very few hints as to what you’re supposed to be doing as a new player and the maps can be a bit confusing, but after a game or two on each with someone showing you the ropes you’ll know exactly what’s going on. Also you need a decent sized group of players to make it work – three per side is the absolute minimum in my opinion, but you’ll have a great game with five or more per team.

I’m not exactly sure why we’re all still playing it years later (and in preference to many more recent games, including the disappointing sequal, ET: Quake Wars). At a guess, I’d say that it’s because it’s free (everyone has a copy), it runs fine on literally any machine, there are no server and connection issues (we have our own private server), and we’re all ‘bought in’ so there’s no learning period any more.  Oh, and it’s just a damned good game.

 

Planetside 2

At the other end of the spectrum is Planetside 2, which I’ve played a fair bit in the last few weeks. Planetside 2 is an MMOFPS, with each server seeing hundreds of players across three teams, all fighting over the same objectives at once on a massive map.

The first thing that strikes you on joining the game is that it actually works. Countless other infantry rush around you, tanks trundle past and aircraft buzz overhead, and there’s hardly any lag. The second thing that strikes you is a hail of bullets, and you’re back at the respawn.

Planetside 2

PS2 also isn’t a particularly newbie-friendly game. The UI is confusing, and the mechanics of capturing objectives isn’t obvious. Identifying friend from foe is tricky, the constant explosions and gunfire is disorientating, and standing still in the open will get a sniper’s bullet in your head.  And it’s the closest a game has made to feel to taking part in a real war.

Or at least, one of those fictional wars where random people are pulled off the streets, given a gun and thrown into a combat zone with no training.

Nowhere is this more apparent than with the aircraft. My favourite activity in Planetside is flying the fighter jets. Very rarely do I get shot down. This isn’t because I’m some kind of flying ace, but because most flights end up with me crashing into mountains, buildings, trees, or the ground. Occasionally I crash into enemy aircraft, but that’s good because they tend to blow up and I get XP. Sometimes I manage to shoot at ground targets, although I imagine the conversation in the last transport I attacked would have gone something like this:

“Hey, there’s a plane firing rockets at us!”

“Really? But we’ve taken no damage.”

“Yeah, I’m using ‘at’ in the vaguest sense.  Oh, he’s coming in closer… er… looks like he’s trying to park upside down…”

Planetside 2, not crashed this plane yet

This is a free to play, micro-transaction supported game. This instantly sets off alarm bells among gamers about pay-to-win, but I’m impressed with how much this isn’t the case. All you can buy with real money is additional weapons and cosmetic player customisations. The basic free weapons are all good, and the paid for ones are just different rather than better.  All of the other unlocks and upgrades are bought with XP earned in game, so it’s perfectly viable to play on a level playing field without spending any money.

When this game is good, it’s really good. Your enjoyment is quite dependent on getting into a good squad (or bringing your own group of friends).  If you’re lucky you’ll end up in a well organised team, with a leader with voice comms who knows what they’re doing and sets appropriate objectives.  When that happens it’s as good an MMO experience as I’ve ever had (well, outside of a successful Eve Online fleet battle, but I don’t have time for those any more).

If you’re on Woodman server and come across a TR player called Schizofen, go easy on him…