It was just another ordinary day for Lima. Though unexpectedly, the routine chore of picking apples, will send Lima into a dangerous journey. Labyrinthica: The Quest of Lima is a single-player, melee focused action game. Labyrinthica has similarities to rogue games, but is based on real-time action. You move Lima with the keyboard and aim with the mouse. Unlike similar games, you will need to fight monsters face to face rather than shoot them from a safe distance. You use both your weapon and shield in battle, though using a sword is not always the only way to harm enemies! Potions should be used wisely. Drinking that green potion might prove fatal. It might be poison! And throwing that bronze potion on the boar creature might make it go berserk. Potion colors are randomly assigned to each type. You will have to discover on your own what each potion color does. Labyrinthica awaits to test your wits and reflexes.

Post news Report RSS General cel shader

A blog post about general cel shader used in Labyrinthica: The quest of lima.

Posted by on

In a new development blog at, I will be making posts relating game development.
I wish to share with you the post about genereal cel shader used in labyrinthica.
The code in this post might be useful for some people.

Labyrinthica features cel shaded graphics.

On the most simplistic level shading is taking a color value from the surface's texture and multiply it by an intensity scalar, which is based on how the light source affect the surface.
The scalar value is usually a floating point that goes from 0 to an unbounded positive number.
In cel shading, we want to quantize this scalar into non continuous values.

The general cel shader is a piece of code that quantize the intensity scalar. The parameters to the function are:
a - The original intensity scalar.
n - The number of quantization cels.
f - The cel transaction factor.
Return value = The quantized intensity scalar.

There are actually n+1 cel levels, the additional cel level is for intensity values greater than 1.
I will not explain the shader in details. I hope the code will be clear enough for people to understand on their own. Though I could explain it in more details if there will be a demand.
A few screen shots with different parameter values:

n = 2, f = 0.8
Cel shade(n=2, f=0.8)

n = 2, f = 0.5
Cel shade (n=2, f=0.5)
n = 3, f = 0.8
Cel shade (n=3, f=0.8)

One last word before the code. My older CelShade function got only one parameter, the intensity.
I made the new CelShade with 3 paramters, but then I saw I would need to update every place I called the function.
Instead I have created GeneralCelShade as the function with 3 parameters, and replaced the old function with a function that calls GeneralCelShade with appropriate parameters.
The bonus is that now changing the parameters in only one place affect the whole game/shaders.
Very simple, yet very useful.

c code:
Quantize (float a, float n)
     return floor(a*n)+1.;

Trunc (float c, float f)
     return (c>f)*(c-f)/(1.-f);

SubCel (float a, float n, float f)
     float q = Quantize(a, n);
     float c = q-a*n;
     return (q>1.)*Trunc(c, f)/n;

GeneralCelShade (float a, float n, float f)
     float c = Quantize(a, n)/n;
     a = c-SubCel (a, n, f);
     a = min (a, (n+1)/n)*(3./2.)/((n+1)/n);
     return a;

CelShade (float a)
    return GeneralCelShade (a, 2, 0.8);

Heh, as a 2D game developer and future game developer I've always wanted to know more about Shaders, what they are, and how they work. I guess the real trick with your shader is how it quantizes your sprites into cells. I'm curious what your non-shaded sprites look like and how it does that.

Reply Good karma Bad karma+1 vote
PompiPompi Author

Making a post explaining shaders sounds like a great idea. Thanks :)

I don't understand what do you mean by sprites. The character and the apple you see in the screenshots are not sprites, they are 3D meshes.
The piece of code I posted is only part of the shader, its not the shader itself.

I thought maybe the code I posted is too difficult to understand.
The concept is very easy to understand if you first try to understand what the function do, making SubCel return 0.
If SubCel return 0, you still get cel shading with n+1 cels, but this time there is no smoothing on the edge of the cels.
Subcel just calculate those smoothing between cel edges.

Reply Good karma+1 vote
PompiPompi Author

Regarding sprites though, you could do something like this with sprites.
But if you don't intend the sprite to change its shading relative to the position of the light source, then there isn't a great benefit doing that with shaders.
You could just do it offline(or precalculate).

Tell me what kind of an effect you are trying to achieve with your sprites, and maybe I can figure out how to do it with shaders and if they are needed for that.

Reply Good karma+1 vote

No sorry, I just assumed that they were 2D sprites and not 3D meshes.

Reply Good karma Bad karma+1 vote
PompiPompi Author

By the way, you can use shaders for all kind of neat effects with 2D sprites.

For instance, you can make a "2.5D" sprite.
That is, you draw a color sprite, which is like drawing a regular sprite.
Only you draw the raw colors and don't draw the shadows.
Then, you draw a height map.
That is a grey values sprite, which is the same as the sprite you have drawen, only each grey color is the height of the sprite relative to the camera. Or the bumpiness of the sprite.
You then translate this height map into a normal map, and you have a sprite that can be affected by light sources like any 3D mesh object.

However, sometimes there is no point bothering doing all these special effect, since a good spriter can make a game look fantastic without all these effects.
But just in case you find these kind of thing interesting.

Reply Good karma+1 vote
Post a comment
Sign in or join with:

Only registered members can share their thoughts. So come on! Join the community today (totally free - or sign in with your social account on the right) and join in the conversation.

Follow Report Profile
Labyrinthica: The quest of lima
Send Message
Release date
Game watch
Dev Diary
Post news
Related Games