So, how do we do this. Well, first thing you have to know is that there are actually 2 effects happening on the screen, one is called cell-shading, the other is called a sobel filter. We will cover how both work.
First up is cell-shading. As can be seen previously, in the image above, cell-shading is responsible for the layered or "blocky" shadows in the scene.
To do this, two shaders are needed a fragment shader and a vertex shader as well as the position where the light is coming from. The fragment shader requires four variables in order to function properly, the texture coordinates, the information on the normals, and two uniform variables for the input image and the qmap. For our purposes, the qmap is simply a grey scale from white to black. The vertex shader on the other hand only requires the texture coordinates, the information on the normals, and vertex positions. This shader will inform the fragment shader where to draw the shadows and what shade they should be.
Now
that we have these shaders we normalize the vectors and create the calculations
for the qmap which first needs a diffuse calculation which helps in calculating
the shadows of the scene, after this the maximum of either the zero or the dot
product of the normalized vector and the vector for the direction of the light.
These calculations are then used to calculate the shadows which are displayed
as layers of gradient as oppose to a smooth transition from light to dark.
Lastly, the texture 2D data of the input image and the texture coordinates are
stored in a vector. This vector is then multiplied by the results of the shadow
calculations which creates the toon shadows.
The
thick lines of the image are created using the sobel filter which filters the
normals to create an edge texture that creates black lines around the edges of
the models but leaves the rest white. To start define a kernel to calculate the
edge detection so that both the horizontal and the vertical edges of the models
are detected. The sobel filter will take in the x and y image coordinates and
the image data. Now the pixel size and sum vector for the sum of location of
the kernel and the texture data. Now the dot product of the sum by itself is
taken and returned if the result is lower than 1 otherwise zero is returned.
Now
the put the shading and the lines together simply multiply them together to
generate the finished toon shader.
No comments:
Post a Comment