Cel-shading

Started by
9 comments, last by MMarcel 17 years, 11 months ago
Hi, My friends and I are making a computer game. We will use cel shading, but the results are everything but pleasant: http://img460.imageshack.us/my.php?image=texturcell7ha.jpg The tea pot to the left is good, but the other figure to the left is not. Do you have any ideas regarding how to use textures and cel shading? (Cel shading with vertex shader.) How do they do in other games? Like Worms 3D or similar? Hope you have some answers! Thank you in advance, Vkoy
Advertisement
I don't know how to do it, but I can offer some advice - there's a small section in a book 'Intro to 3D Game Programming with DirectX 9.0' by Frank D Luna, on Cartoon Rendering.

It explains about finding the edges and sillouette.

There is sample code from the book at: http://www.wordware.com/files/dx9/

Follow the Part IV link, download the .zip file and check out the Chapter 17 'toon' files.

It's all too complex for me, but hopefully it will help you out.

Sorry I can't be much more of a help
Thanks for the help, but actually that is exactually the same book we are using and it does not work. Well, thanks again, but if any of you have another idea that would be very nice. :D
Assuming cel shading is cartoon rendering.

There are many ways to generate the outline, heres one way to do it.
->render the object to a texture, using a solid color
->then preform a edge detection (sobel?), to generate the outline.
->Render a texture to the output
As a preprocessing step, make the texture more cartoon like (less colors). Gimp has an 'artistic filter' to do this.

The next part is the lighting. In cartoon rendering you want to have color banding. One way to achive that is to change your lighitng calculations to use integers.
IE in the final pixelshader: diffuse = (int)(Diffuse*4)/4.0;
Edit: I took this (putting it into my own words) from the book "shaders for game programmers and artists", though there is a similar method in shaders x2. xD

###
The book shaderx3 has an example of dot3 cellshading. Even cooler is an article in Game Programming Gems: 2 that talks about "Sketchy Drawings"

###
I would try to look at the lighting calculations, and try running the textures through the filter (ensuring to keep a backup)...

[Edited by - Aiursrage2k on May 7, 2006 10:09:15 PM]
Insufficent Information: we need more infromationhttp://staff.samods.org/aiursrage2k/
There's a very good article on this in the book ShaderX2. :)
Heres a method I discovered. Requires pixel shader though.

Render normally with whatever nice lighting u want, then do a bright pass (Yes in the same draw call.) Then still inside the same shader do a small bloom to the bright parts.

Here is the results I got.

http://astaroth.beatbuggy.net/adrian_beetle_post_toon.jpg

adrian_beetle_post_toon.jpg
Make sure your normal and light vectors are normalized? There's really not enough information from those pics to be able to know whats wrong. Post your shader maybe?
"Artificial Intelligence: the art of making computers that behave like the ones in movies."www.CodeFortress.com
I've always thought that cell shading does not look at all like actual cartoons...
I think the biggest issue is that the real stuff is drawn by hand as a 2d image; it is not a 3d model which is then flattened. Consequently, the 3d model introduces limitations on style. Since the 3d geometry is a continous shape, whereas the 2d model can actually change shape and have different(better) detail from different views, since each viewpoint in fact is a new 'model'.

So the 2d drawings benefit from arbitrary shape and detail changes, which means 'style' can be perfectly controlled by the artist. Whereas with the flattened 3d model method that everyone uses, you are at the mercy of the shader to decide what line goes where.

Perhaps the best solution is to use actual 2d vector spline models? with some kind of realtime 'tween-ing' system to generate intermediate angles? That would rock i'd think...
//
// Globals
//

extern matrix WorldViewMatrix;
extern matrix WorldViewProjMatrix;

extern vector Color;

extern vector LightDirection;

//
// Structures
//

struct VS_INPUT
{
vector position : POSITION;
vector normal : NORMAL;
};

struct VS_OUTPUT
{
vector position : POSITION;
float2 uvCoords : TEXCOORD;
vector diffuse : COLOR;
};


//
// Main
//

VS_OUTPUT Main(VS_INPUT input)
{
// zero out each member in output
VS_OUTPUT output = (VS_OUTPUT)0;


// transform vertex position to homogenous clip space
output.position = mul(input.position, WorldViewProjMatrix);

//
// Transform lights and normals to view space. Set w
// components to zero since we're transforming vectors.
// Assume there are no scalings in the world
// matrix as well.
//
LightDirection.w = 0.0f;
input.normal.w = 0.0f;
LightDirection = mul(LightDirection, WorldViewMatrix);
input.normal = mul(input.normal, WorldViewMatrix);

//
// Compute the 1D texture coordinate for toon rendering.
//
float u = dot(LightDirection, input.normal);

//
// Clamp to zero if u is negative because u
// negative implies the angle between the light
// and normal is greater than 90 degrees. And
// if that is true then the surface receives
// no light.
//
if( u < 0.0f )
u = 0.0f;

//
// Set other tex coord to middle.
//
float v = 0.5f;


output.uvCoords.x = u;
output.uvCoords.y = v;

// save color
output.diffuse = Color;

return output;
}
I think the vertex shader you posted would work well enough on solids, but won't work on a textured character. For your technique to work on a texture model, you'll have to change the texture and probably have a texture for a lighted and darker side.

You might want to look at using a pixel shader as people already suggested. You won't be limited to a 1D premade texture ;)

Cheers,

Shadx

This topic is closed to new replies.

Advertisement