One of the most recent additions to Cycles render engine has been a toon shader. Many people seem to be interested in using it, but aside from the links shown here, there is little to no information about it, so they must resort to personal experimentation. This tutorial aims to teach readers how to use this toon shader to create renders with a comic style, and will be based on this simple scene as an example:
We will break up this tutorial in four different sections:
- Lighting setup
- Render parameters
The first step will be setting up our lighting, which will be basically a key light and a fill light. Both lights will be point lights with 0 size. Any light with a size different to zero will create gradients in our shading. We want shading to be as flat as possible, since we will manually create and control gradients in our objects and characters using ‘size’ and ‘smooth’ parameters in the toon shader.
Key Light: we will use a point lamp, placed slightly above and to the right of our character and set to a very high ‘strength’ value. This will be our main light, the one that will define shading direction and the only one casting shadows in our scene. The high ‘strengh’ value shown here is needed to light a model that is 10 blender units high. Smaller objects will need much lower values.
Fill Light: we will use a point lamp parented to the camera, and with ‘cast shadow’ disabled so it won’t create a second shadow under objects and characters. This light is there to fill the dark side of objects, so they won’t be pitch black. It will also create additional highlights and details in our objects. Again, seemingly excessive ‘strengh’ value is due to the size of the lighted model. Smaller objects will require more ordinary values.
World Background: usually our background will be absolute black, but if you are willing to experiment a little with it, you can raise it to a 25% gray. It can help to fill shadow, but can also introduce some noise, which will require higher sampling to clear up, and that means longer render times. For this particular scene we won’t use background lighting.
In this stage we will setup the materials defining our model’s appearance. We are going to use toon shader for all our materials here, so some advice about its behavior is in order.
First of all, you should always use the toon shader with smooth shading activated, otherwise you will get some nasty artifacts.
Another thing to be aware of when working with the toon shader is that certain combinations of ‘size’ and ‘smooth’ settings in the shader will produce very visible terminator artifacts on low poly objects.
The toon shader can work in diffuse mode and glossy mode, and a combination causing artifacts in one mode might not cause them in the other mode. After some experimenting I found that following these two rules for diffuse and glossy mode respectively, you can avoid terminator artifacts:
- Diffuse mode: size+smooth <= 0.9
- Glossy mode: size+smooth <= 1.0
As long as you don’t set the added values of size and smooth above 0.9 in diffuse mode or 1.0 in glossy mode, you will be safe from the terminator artifacts in the toon shader.
We will now examine the node setup for the main material in our robot. We will begin by setting our base diffuse shader. ‘Size’ will let us define the proportion between lighted and shadow areas in the object. On the other hand, ‘smooth’ will allow us to define the width of the terminator area, which is the border region that separates light and shadow areas in an object. The diffuse component in our material will have a 0.6 size, assigning lighted surface to a majority of the model, and 0.2 smooth, giving it a nice transition into shadow.
Next step is adding the glossy element. As counterintuitive as it may seem, this time we are going to use another toon shader in diffuse mode. As it turns out, setting smooth value to 0 will create a very sharp terminator with no transition between light and shadow, creating a glossy look. In certain cases such as this one, a toon shader in diffuse mode with smooth set to 0 will give us a better result than a toon shader in glossy mode. In order to get more subtle details in certain areas, we will use the same color we used for the diffuse element, tuned down to 80% by a HSV node. Also, instead of combining our diffuse and glossy elements with a mix shader node, driven by a layer weight node, we will simply use an Add Shader node:
To get a more detailed look, we can assign different variations of this material setup to parts of our model. The aspect of the model before proceeding to final rendering and compositing is this:
Before reaching the compositing stage, we must set the render settings for the scene.
Light paths: Forget physically correctness our unbiased rendering. We are doing a cartoon style render here, so we don’t need light bouncing around. Set min and max bounces to 0 and disable caustics.
Sampling: 0 rebounds and hard lights mean that noise will be low to pretty much nonexistent very soon. Usually 50 samples should be enough to have a clean render. You could use even less sampling and probably there wouldn’t be much of a difference to your naked eye, but edge filter nodes in the compositor will notice the difference and return a lot of noise along with the edges we need for our contours. Besides, this technique renders blazing fast already, so there isn’t much of a benefit for lower sampling.
Film: We are going to break up our scene into ‘background’ and ‘foreground’ renderlayers, so in order to be able composite them we will need to enable transparent film.
As I said above, before going into the compositing stage, we must create two renderlayers: Foreground and Background. This is necessary for a correct edge detection, and can even help us to speed our render (more on that in the background renderlayer paragraph). It will also allow us to set different contour intensities for background and foreground elements.
Foreground renderlayer: This renderlayer will have all objects in the scene, excluding background elements such as floors, walls, ceilings, landscapes or terrains. We must always enable normal pass in this renderlayer, as it is necessary for edge detection in the compositor. As you can see in the screenshot below, this renderlayer only includes the first layer, where we have placed everything but the floor.
Background renderlayer: This Renderlayer is for background elements such as floors, walls, ceilings, landscapes or terrains. Notice in the screenshot below that we have selected for this renderlayer only the second layer, where we have placed the floor. We will enable normal pass in this renderlayer only in those cases where we want to have countours drawn for the background. Also, in many cases with rather simple backgrounds, like the one in this scene, we can set a much lower sampling just for this renderlayer, thus speeding up our render. This can be done by adjusting the ‘Samples’ indicator in the screenshot below. If we leave the default value of 0, this renderlayer will be rendered using the same amount of samples as the rest of the scene.
We can now hit render and begin compositing. This is the node configuration we will setup in the compositor to create our contours:
As you can see we start by extracting the inner and outer contours from the foreground renderlayer. We are not going to extract contour from our background renderlayer in this example because the floor is a simple plane. Once we have our contours extracted, we composite together background an foreground and then multiply the result by inner and outer contours in independent steps, so we can use different intensities for both contours.
Inner Contour: this is where the normal pass comes into play. We will first split the Normal output in the Foreground renderlayer into its HSV components and filter its V (for Value) outupt using an edge detection filter. In this case we will use Kirsch, but in certain cases Prewitt and Sobel will work too. The resulting image can show some noise in areas where the source render is darker, which can be solved by decreasing the factor in the filter. After that we will invert the colors to get black edges over a white background, apply a Dilate/Erode Filter to make the edges more homogeneous and Gaussian Blur for some antialiasing. If you are not sure if you are going to make resolution changes in the future, setting relative values for the Gaussian blur is the sensible thing to do, since that mode gives the most consitent output across resolutions, thus minimizing tuture tweaking. Finally, when we apply this contour multplying our render with it, we will use only a 0.4 factor, which will give as a result a subtle contour that integrates better into the image.
Outer contour: Using the same basic method we used for get the inner contour, we will perform edge extractions based on the S (for Saturation) and A (for Alpha) components of the image output of the Foreground renderlayer and mulptiply them together before applying a gaussian blur filter to soften the resulting contour. This will allow us to have a more clear and regular contour, which is another good reason to split background and foreground elements into separate renderlayers. Having already composited the inner contour into our render, we will multiply the previous step with this contour, but this time will use a higher factor in order to highlight outer contour over the inner contour.
Cycles has been criticized often because of its render speeds and hardware requirements, but this 2048×1024 render takes a mere 26,69 seconds to render on an I7-2600K (Quadcore CPU at 3.4Ghz with hyperthreading). Another common misconception is that being a pathtracer, unbiased physically correct renders are its only objective, however Cycles has a large bag of tricks and tools for non photo realistic rendering, such as lights that don’t cast shadows, ray visibility settings for all lights and objects, negative lights that absorb light from the scene, light path nodes… and now a toon shader. The bottom line is this: although still in development, Cycles is already a versatile render engine, and its possibilities have not been totally exploited yet. Its future certainly couldn’t look any brighter.