Lighting (and graphics in general) in Neon City Getaway

Posted by (twitter: @dManabreak)
December 22nd, 2015 11:59 am

Hey! Since I’ve got so much awesome feedback from you guys, I thought to write a little summary of the lighting I implemented in Neon City Getaway. I’ll go over the overarching stuff here, and if you’re interested on the actual implementation, take a look at the BitBucket repo (more specifically, the file). :)


The graphics in this game are as simple as possible, and it’s achieved with the combination of 2D and 3D graphics. The 2D graphics are quite roughly drawn sprites and there’s just six sprites overall – the car, four smoke particles and a skid mark sprite. The key here is randomization – for example, the smoke is achieved by spawning smoke particles with random size, transparency and rotation. Nothing too fancy!

The 3D graphics are rather “lame” as well. The textures are 48 pixels squared, and are pretty much just squares drawn in rows. The 3D models were done in Blender and the rather crude textures were mapped onto the cubes and planes, all sized the same.

Blender in action

Blender in action

The tricky part was to combine the 2D sprites and the 3D blocks. I already had a crude prototype working at this point where I was cruising around with my 2D car and didn’t want to touch that part of the code, so I had to figure out a way to bend the 3D stuff there as well. I ended up drawing the 2D stuff in its own pass and the 3D stuff in its own. The result “works”, but is tremendously limited: the 2D stuff is really drawn on top of the 3D stuff, making it look really off at times, especially if the camera was to be zoomed or rotated around. For this game, though, the limitation did not impose any problems.


To start off with the lighting, we have the unlit scene (the leftmost picture). This is a combination of two render passes: the first one renders the 3D scene (the road and the buildings) to a framebuffer, which is then rendered to a full screen quad. Next, the sprites (the car, smoke, skid marks) are rendered on top of the full screen quad. Obviously, this isn’t looking that nice, so onwards we go!

From left to right: Lighting off / Vertex lighting / Box2DLights / Combined lighting

From left to right: Lighting off / Vertex lighting / Box2DLights / Combined lighting


The second picture shows the 3D scene rendered with vertex lighting. There’s a single point light placed on top of the car, so it lits the area around the car. There are also two smaller points lights placed right at the bottom edge, with blue and red tints, to simulate a cop car. These are always at the bottom edge of the screen so you don’t actually ever see the cop car. :) This is almost the final result, but we are still missing shadows. Rendering shadow maps for a scene like this would be overkill since there really is just a single plane which receives shadows.

So, instead of full 3D lighting, I used Box2DLights. The third picture shows the scene rendered without the vertex lighting but with the Box2DLights enabled. As you can see, the buildings become dark as they’re “in the shadow”, as does the road that’s behind the building.

The rightmost picture depicts the final rendering result. This is the combination of the vertex-lit 3D scene with 2D sprites rendered on top of it, and the Box2DLights light map rendered on top of all that.


The lighting is done by cheating all the way, just like you would imagine. For instance, the skidmarks and smokes are occasionally drawn on top of the buildings since there’s no depth testing against the 3D scene when the sprites are drawn. However, it just fits in this kind of game where the player focuses on the next corner and the top edge of the screen instead of the particles. The shadows overlap buildings and so on… but it all works for this specific game. For example, the car could theoretically be drawn on top of the buildings, but that will never happen because the camera is placed right on top of the car. No building can make its roof reach “over” the car.

Is this the best way to do things?

Absolutely not. This is something I managed to manifest in 20 hours of jamming and compoing. It’s cheaty, it’s only suited for this game, and it all could be done in a better, more efficient way. :)

Leave a Reply

You must be logged in to post a comment.

[cache: storing page]