cokane.com
Games
Articles
Links
:: How to make cartoon characters in Quake 3 using 3D Studio MAX - Step 1 ::
Step 1 is to make a low polygon Quake 3 character. Here's one I made earlier (it's the torso section of my Honey model).

Note that your model should be REALLY low polygon because this technnique doubles the end polycount of the character.

:: Step 2 ::
Next clone your model as a reference, and call it something smart, like object_outline.

:: Step 3 ::
Now apply a "normal" modifier to the cloned object (click on "more" in the modifier panel and select "normal") and check the "flip normals" box.

:: Step 4 ::
Assign a black material to the outline object. You won't be able to see it yet. This is just to make the outline show up in max, to make it work in Quake 3 you have to assign an image to it, and map the outlines into a black part of the image - I won't go into that now though as I'll assume that you know how to map a model, and anyway, there are plenty of other articles on how to do that.

:: Step 5 ::
Next, go to the modifiers list again and apply a "push" modifier to the outline mesh.

Slide the "push value" down a bit and you should see the outlines appear.

A bit like this! Slide the "push value" so that the lines are as thick as you need and then collapse the stack. Since the outline is a reference of the original mesh, if you modify the original in any way, the outlines will still work.

:: Step 6 - Shaders ::
That's the modelling part finished, the next step I'll deal with is the shaders.
To get the 'cell painted' cartoon look the following shader script is used:

	models/players/player_name/texture_name
	{	
		{
			map models/players/player_name/texture_name.tga
			rgbGen identity
 	     	}
		{
			map models/players/player_name/shade.tga
			blendfunc filter
			rgbGen identity
			tcGen environment 
		}
	}
			
I'll explain what each of those lines mean. The first line is just the name of the shader. For player models the shader is always named as the texture name, including its full path, but excluding its extension. Replace "texture_name" with the name of the actual texture image you are using. The next two lines tell the game to draw the texture as it is, with no lighting effects. Player model textures are normally drawn with "rgbGen lightingDiffuse" which gives realistic smooth shading, but "rgbGen identity" leaves the texture as it is, with no lighting effects. Here is one of the textures I used for Honey:

Notice that it has no shadows, just flat areas of color. That is because the next stage of the shader applies the shadow effect. This image...

..."shade.tga" is mapped onto the model with environmental mapping (tcGen environment). Environmental mapping is normally used for creating bright reflections, but in this situation instead of using an image to brighten the model, we are using it to shade the model. The "blendfunc filter" line means that the image will only be used to darken the model. So, the white parts of the image have no effect on the model, and the grey parts darken it slightly. This gives a clear 2-tone look to the model - like this...

If you wanted to have 3 shades on your cartoon character then you could use an image like this for "shade.tga"...

I find it is clearer with just one shade tone but you should experiment to see what suits your character best. Also you might not want to use this effect on the face of your character. On this character it looked really bad on her face, something like a 5 o'clock shadow, so I used an extra pass on the shader for the texture that mapped her face...


	{
		map models/players/player_name/texture_name.tga
		rgbgen identity
		alphaFunc GE128
	}	
			

This script re-draws the original texture over the shaded layer, but through and alpha channel. So your image has to be a 32-bit TGA with and alpha channel masking out all areas except the face (and anywhere else you want re-drawn without shadows). These lines go at the end of the shader script, just before the final brace.

That's it, if you have any questions or comments mail me - cokane at cokane dot com.


July 14th 2000