hi you must be here for the video Well you're in luck because it's about shaders,
and if you behave there might even be a game
for you to play at the end I'm Leonard let's dive right
into this episode of Useless Game Dev Moebius, also knows that Jean Giraud,
was a French cartoonist and a major figure of French comic book arts. and today we're 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 this is more of an experiment
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 with him most is this: thin black outlines, flat colors,
lots of details 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. To do 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 the 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 As you may already be able to tell,
the resulting sum will highlight the differences between
the left and the 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 would 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 voila! 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. Nope that's too much. Perfect it's already looking quite good,
although for some reason when I zoom on this fern, I can gaze into the inter-dimensional void 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 are not really going to apply
any traditional lighting to the scene, and the normals will get caught
and outlined by your Sobel filter The only issue with this,
is that when you draw a single line on 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 a little secret Also we don't want to get too close
and risk falling into the void 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 this special texture
with three dimensions of cross hatching: horizontal, vertical, and sideways. 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: if it's between 100% and 75% brightness : no cross hatch
between 75% and 50%: only horizontal lines between 50% and 25%: horizontal and vertical and finally between 25% and zero:
all three types of lines 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 should 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,
erm, not by me So we're going to stick with screen-space cross hatch for now 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 Line looks alright it handles a 3D scene
pretty well it definitely doesn't look as detailed as it should be, but that would
require me having some actual drawing skill so, no.
Let's move on to color. Objects are simple: they have either a single color,
maybe a fancy schmancy gradient, and same thing for the skybox. Also since the crosshatch line thing is taking care of the brightness component of
colors, all colors can be at full brightness It's all a bit too colorful now so we'll add
post-processing effects to tweak saturation, contrast, and other color adjustments. Also throwing 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, like the image has white noise or something, So I made my own grain that only
changes every 10 frames or so, to mimic the low framerate of old films. Our shader looks like it's ready in our sample scene
so let's take her out for the 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 It's available for you to play on itch.io,
link in the description so go for it this is my current best score, comment below
if you can beat it. Until then have a good one