Moebius Style Rendering

This text is a written version of the video above, with future plans to incorporate graphics and figures for illustration.
As I'm working my way through the backlog of videos that were published before this website, I suggest reading the article alongside the video for a comprehensive experience.

Moebius

Moebius, also known as Jean Giraud, was a French cartoonist and a major figure of French comic book arts.

And today I’m going to try and replicate his drawing style when rendering real time 3D. It is obviously never going to be as good as masterpieces drawn by an expert, but we’re going to see how far we can go.

Regarding "his style", Moebius had a lot of different phases throughout his career, but the style people associate most with him is minimalistic, thin black outlines, flat colors, lots of details.

Line

Outline

Let’s get started on the line, and more specifically, the outline.

The line of Moebius’ drawings has most of the time a fixed width, meaning it’s probably all drawn with the same pen. If I draw the line directly on a 3D object using a regular texture, the perspective is going to make it uneven, and pixelated up close, so there must be a screen space filter to keep everything at the same size.

For this, we’re first going to need an edge detection filter, in the form of a Sobel filter, which is a kind of convolution filter. Let me explain.

In a convolution filter, for every pixel on the screen, the result of the filter will be a weighted sum of the values of the neighboring pixels. To do this you sample the pixels around the target pixel, and multiply their values according to a weight matrix.

If the weights are just a simple average, we get a simple blur. If the weights are gaussian weights, we get gaussian blur.

This is the weight matrix for the Sobel filter:

1   0  -1
2   0  -2
1   0  -1

As you may already be able to tell, the resulting sum will highlight the differences between the left and right sides of the pixel. If the values are same-ish, the filtered pixel will be dark, if however there is a high contrast between the two sides, the filtered pixel will be much brighter.

If we test this on a sample image, we see that the Sobel filter highlights vertical edges.
We just have to add a second similar filter that highlights horizontal edges, and by taking the maximum value of both, we get a pretty nice edge detection filter.

In a 3D scene, we will apply the Sobel filter on the Depth map. This way when an object is far behind another, there will be a sudden change in depth, and voilà. Outlines.

Something that also has sudden changes along the edges of an object is the Normal map of the scene, so we can also apply the Sobel filter to the normal buffer, and we get even better edges.

Now, it’s all supposed to be hand drawn after all, so I’m going to add a slight noise to the UV sampling, in order to get wiggly lines.

Texture

Let’s add texture to our objects. There’s a lot of details we want to draw on our objects, and once again if we draw them directly on the object, the perspective is going to make the line uneven.

So my idea was to write the texture information to the normal buffer. After all we’re not really going to apply traditional lighting to the scene, and the change in normals will get caught by our Sobel filter.

The only issue with this is when you draw a single line in the normal texture, it will actually get outlined by the sobel filter, and even if you draw the thinnest lines, when you look up close it doesn’t look great.

But let’s simply not look too closely at objects, and this will be our little secret.

Shadow and Shade

In Moebius’ drawing, lighting is mostly conveyed via the line itself. So you will have bright colors (we’ll get to those in a moment), and the shading is going to be done using crosshatched lines.

To achieve this I prepared a special texture with three dimensions of crosshatching: horizontal, vertical, and diagonal. Each of these layers write independently to the red, green and blue channels of the texture respectively, which once in Unity gives me basically three textures in one. Pretty neat.

With this I can add the crosshatch depending on the brightness of a pixel:

The shader graph for this is pretty simple too:

In an ideal world, the crosshatch pattern would follow the curve of the object it’s on. This is how it would be drawn to convey volume. For the shady part of objects, this can be done by adding the crosshatch to the normal buffer, just like we do with texture. It works somewhat but since it goes through the Sobel filter the quality ends up being mmmeh.

For shadows however, while it might probably be feasible, uuuuh… not by me.

So we’re going to stick with screen-space crosshatch for now.

Specular

We’re almost done with the line component of our shader, the last thing we need is to show specular reflections.

In Moebius’ drawing this is done with very distinct white areas that are outlined as well.

With a simple dot product between the normal of a surface and the direction of the main light of the scene, we can get the area of the object that is most exposed to light and write that as a special color in our object’s normal map so it’s caught by the Sobel filter.

Color

Line looks all right! It handles our 3D scene pretty well. It definitely doesn’t look as detailed as it should be but that would require me having some skills so, no.
Let’s move on to color.

Objects are simple, they have either a single color, maybe a gradient if you want to be fancy schmancy.
Same for the sky box.

Also, since the crosshatch line thing is taking care of the brightness component of colors, all colors can be set at full brightness.

Post-Process

It’s all a bit too colorful so we’ll add post-processing effects to tweak saturation, contrast and other color adjustments.

Also throw in some grain to look a bit more like paper. I’m not a fan of Unity’s built-in film grain because it moves a lot, as if the image has white noise, so I made my own grain that only changes every 10 frames or so, to mimic the low framerate of old films.

The Game

Our shader looks like it’s ready in our sample scene, so let’s take her out for a spin, in a small racing game I made, dubbed Montrouge Grand Prix.

It’s a tiny racing game, very simple, go through the hoops to complete a lap. Three laps total Fastest wins. Your time starts now.

It’s available for you to play on itch.io, so go for it.

Have a good one!

Check these out

Credits

Moebius Stuff

Moebius drawings in this video are from the following books:

Music