Jetboard Joust Devlog #54 – Smoke & Mirrors

For the past few days I’ve been working on adding some more ‘juice’ to Jetboard Joust – the sort of small details that don’t really add anything to gameplay per se but, when combined, add an awful lot to game feel (hopefully).

I’ll go over most of these in a separate post but one element seemed to deserve a post of it’s own – smoke.

I wanted to add smoke as a way of increasing a sense of ‘permanence’ to the combat. Explosions are over and done in less than a second but smoke could hang around for ten seconds or so and build up depending on how much destruction is going on.

I wasn’t after a ‘realistic’ smoke effect but something more stylised to fit in with the rest of the game art. It seemed logical to use circles as the base for the effect but I felt pretty sure I’d want these circles to increase in size over time, maybe quite dramatically, so I didn’t want to rely on scaling sprites for this. I decided to use custom shaders instead as this should give me much more control.

So the first step was to use a custom shader to draw a simple filled circle. Initially I thought the geometry behind this would be quite complex but, in fact, it’s just simple pythagoras. Here’s the approach in pseudo code…

// get coordinates relative to centre of circle
float x = 0.5-coords.x;
float y = 0.5-coords.y;

// fill the entire space
float radius = 0.5;

if ( x*x + y*y <= radius*radius )
{
// return a color
}
else
{
// discard
}

…I’d be lying if I said I got to this stage quickly though! Though it didn’t take me long to figure out the maths, I spent far too long passing the shader a region of a texture to draw rather than the entire texture and getting confused as to why my results were all off (forgetting that coords.x and coords.y are relative to the entire texture to be drawn, not the region). When I started passing a simple 2×2 image to the texture everything clicked into place.

Once I’d successfully drawn a filled circle it was pretty easy to expand that technique to draw concentric rings and the like, and to animate these by basing their radii on parameters that are passed to the shader and change each frame.

Next step was to find a way of applying motion to these circles that looked suitably smoke-like. I started by simple applying a uniform velocity to several circles distributed across a certain range, e.g. -60d to +60d, as well as increasing the circles size over time.

When I finally got this to work the way I intended it didn’t look too bad as a starting point so I added a couple more parameters to make things more interesting – a ‘deceleration’ parameter (so that the velocity of the circles decayed over time), and a ‘buoyancy’ parameter (so that the circles gradually floated upwards over time). I also decreased the opacity of the circles over time so that they gradually faded out.

This looked much better but the results were still far too uniform, forming very obvious geometric patterns as the circles intersected. To stop this I added a certain amount of randomisation to both the circles initial velocity and their ‘buoyancy’ – this produced a much more smoke-like effect – still stylised but not overly ‘geometric’.

I was almost there now but felt that the smoke cloud was dissipating too quickly and lacked some kind of ‘weight’ to it’s centre. I fixed this by adding additional batches of circles with a decreasing initial spread and velocity with the final one staying pretty much in the same place. This looked a lot better.

Lastly I experimented with adding pixelation to the shader so that the circles were drawn at the ‘game’ pixel resolution rather than the ‘screen’ pixel resolution. Unfortunately I felt this looked pretty crappy – one of those things that ‘should’ have worked but didn’t! So I left things as they were but I did add a gradually increasing amount of pixelation over time so that when the circles have pretty much faded out they kind of ‘dissolve’ out rather than just disappearing.

Actually I couldn’t stop there – I thought the centre of the smoke cloud looked too ‘solid’ to start with so added a small particle effect to imitate ash or something. It’s subtle but it just breaks things up a little.

I’m pretty happy with the final result – watch this space for a mini-tutorial on using shaders to draw geometric shapes. I think I might end up using that technique again in this game…

Dev Time: 1.5 days
Total Dev Time: approx 97.5 days

previous | next

mockup_3x
Successfully Drawing Circles With HLSL

mockup_3x
First Attempt At Multiple Circles – An Interesting Fail!

mockup_3x
Starting To Look More Smoke-Like But Still Too Geometric

mockup_3x
Adding Some Randomisation For A More Natural Effect

mockup_3x
The Final Shader With Pixel Dissolve

mockup_3x
The Final Smoke Effect In Game

2 Trackbacks

  1. […] using a custom shader. Luckily I was able to re-use the ‘smoke’ shader I talked about here. I may tweak this some more but am pretty happy with it as […]

  2. […] art style and was also causing a few performance issues on some machines. You can see the effect here (I usually turn this off for recording GIFs as it overloads the GIF […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: