[NO SPOILERS] Fun with shaders for LD37, part 1!

Posted by (twitter: @avaskoog)
December 16th, 2016 2:34 pm

Hey! They’re not all too advanced, but I still thought I’d share a little something on the custom shaders that were written for our LD37 entry, LOCK AND RELOAD. c:

Since the posts easily get a bit lengthy, I’ll divide this into a series of more bite-sized posts so that I don’t have to sacrifice all too much clarity for the sake of space. We’ll start with the main shader that gives the game its look and feel!


Some of the effects are connected to slightly fundamental parts of the story, and since the game ended up being really short due to time constraints, I recommend you play the game first to avoid the spoilers and get the most out of the game with it’s little twists! So I’ll be adding a “read more” tag at to some parts to hide some of the stuff from the front page of the blog.

Note: the game was made in Unity and the shaders were written accordingly and so any code will be given as boiled down versions of the shader code written for that, but obviously everything is readily convertible to something like GLSL with minor to no changes.


Post effect filter

This one won’t spoil a thing as it is the very first thing to see upon starting the game: the wonky colour effects and checkerboard overlay. There’s also a dark vignette as well as some increased contrast.

View post on imgur.com

This effect applies to the whole final rendered image rather than individual objects and is therefore done in one step at the end of each frame, simply applying the shader to each pixel, or fragment.

Let’s go! ᕕ( ᐛ )ᕗ

The low-fi colour effect

This is achieved by first multiplying the colour values (which are all normalised between 0.0 and 1.0) by some factor, then rounding the numbers so that any resulting decimals disappear, and then dividing the values back down again by the original factor. This effectively decreases the colour variation. The smaller the factor, the greater the effect.

col.rgb *= factor;
col.rgb = round(col.rgb);
col.rgb /= factor;



The contrast effect is fundamentally not so complicated. It can be done in different ways, but for this particular game what I found worked best was to subtract some of the intensity of the colour if the original colour was below some tolerance value, but multiply it by some factor if it were above it.

col.rgb += (col.rgb < tolerance) ? 0.5 : 1.5;



Alternating dark and bright squares are all over the screen. This isn’t some texture; just a little bit of maths. By checking the position of each pixel on the screen and figuring out whether it’s even using the modulo operator (which gives the remainder of a division), we can figure out whether the number is evenly divisible by two and thereby whether it’s odd or even.

If we multiply the coördinates by some factor to pretend that the screen is smaller or bigger than it really is, we can control how big the squares get. We apply the effect by darkening odd squares and leaving even ones untouched or vice versa.

col.rgb -= ((floor(x * s) % 2.0) - (floor(y * s) % 2.0)) * darkness;



In this case, a vignette is a darkening of the corners of the screen. We’re basically applying darkness to the whole screen except an oval in the middle, leaving the corners dark but the middle unaffected. Circles are easy. We can achieve an oval by pretending that our rectangular canvas is in fact square.

fixed ratio = height / width;
fixed2 middle = fixed2(0.5 * ratio, 0.5);

We can then check the distance from the center to the current fragment, adjusted for the rectangle’s ratio, to get its position inside a circle, which will appear as an oval thanks to the ratio.

fixed2 pos = fixed2(x * ratio, y);
fixed factor = length(pos - middle);
col.rgb -= factor * darkness;


You will probably want to adjust some values by multiplying them by various factors to make your vignette look the way you want.

That’s it for this part! In the next one (and I won’t be posting it right away as I don’t want to be spammy), we’ll be talking about the first of the two effects in the game that required extra cameras and render textures!

Stay tooned! ☆

Tags: , , , , , , , , , , , , , , , , , , , , , , , , , , ,

2 Responses to “[NO SPOILERS] Fun with shaders for LD37, part 1!”

  1. sP0CkEr2 says:

    could you share an example project of how you made these effects in unity?

    • Avant-Marde says:

      No need for a whole project. c:

      You need a generic image effect script on your camera (can be used for all cameras that need post effects and isn’t particular to a specific effect unless you want to add settings or something):


      You put this script onto your camera. As you can see, this will put a field for a shader into the inspector. So you need to create that shader so that you can drag it there.

      The easiest way to get started is to right-click in Unity’s file explorer and create a new “unlit shader”. That one has some unnecessary code related to fog, however, so you probably want to remove all of that. Here’s a modified version that has only the stuff you need:


      There’s a comment in capital letters that I added near the bottom of the file where you will need to write your own code to modify the output. Note that with fragment shaders you are working with one pixel (or fragment) at a time, so this code will be running on every pixel on the screen, which you need to bear in mind when you design your shader code.

      Unless you want to load more textures and stuff into the shader, this is all you need! c: You’ll have to delve into the shader docs on your own in that case.

Leave a Reply

You must be logged in to post a comment.

[cache: storing page]