PDA

View Full Version : Performance Friendly Cell Shading?


elias4444
10-27-2007, 11:45 AM
I know of two methods that create the Cell Shading effect in openGL: The one from the NeHe tutorial, where you have to recalculate the light for every triangle every frame (which destroys the use of call lists, only marginally lets you use VBOs, and kills your framerate no matter what), and using a GLSL shader (which I don't actually know how to do, but it creates some rather steep system requirements for a casual game).

Other than those two, are there any performance friendly Cell Shading techniques for openGL? I've been looking for a way to possibly reduce the color range of a glLight, but haven't had any luck with that. It just seems to me like there's got to be an easier way; I mean, after all, aren't we actually simplifying things by using Cell Shading?

Any input is appreciated!

luggage
10-27-2007, 11:57 AM
Not sure if it's much help but a quick and dirty way to get a cell shading type effect (that can all be done in the modeller) is to...

* generate your mesh and texture it in bright, cartoony colours.
* then create a slightly scaled up version of the mesh, invert the normals and colour it black.

Now when you draw both models together (as one object) you'll get the black outline showing (thickness depends on how much you scaled the second model up by). Not 'true' cell shading, but it's certainly cheap and cheerful!

marshmonkey
10-27-2007, 01:46 PM
Not sure if it's much help but a quick and dirty way to get a cell shading type effect (that can all be done in the modeller) is to...

* generate your mesh and texture it in bright, cartoony colours.
* then create a slightly scaled up version of the mesh, invert the normals and colour it black.

Now when you draw both models together (as one object) you'll get the black outline showing (thickness depends on how much you scaled the second model up by). Not 'true' cell shading, but it's certainly cheap and cheerful!

do you have any examples of this in practice? I would like to see what this looks like.

elias4444
10-27-2007, 02:43 PM
I'm able to get the outlining done without a problem. The same Nehe tutorial that talks about Cell Shading also has an outline method that's really cool, and doesn't cost a whole lot (so long as you don't mind drawing your 3D objects twice). That, in conjunction with full ambient lighting, can make a pretty convincing 1970's style cartoon (a cartoon with no shading).

My main issue is trying to get some shading done that keeps the "cartoony" look (I'm going more towards 1990's style cartoons). So, I want shading, but not a gradiated shading... sort of a black or white style you could say (or, at least, a very limited grayscale quality).

oNyx
10-27-2007, 03:49 PM
do you have any examples of this in practice? I would like to see what this looks like.

That drawing twice stuff looks like this:
http://kaioa.com/k/cel_test.jpg (Q3 engine)

The width of the outlines varies with the distance and the angle. Not that impressive, but at least it's easy to implement.

luggage
10-27-2007, 05:07 PM
do you have any examples of this in practice? I would like to see what this looks like.I've just knocked this (http://www.bigfizz.com/toontest.rar) up in XNA (so you'll need whatever it is that XNA needs to run it - space cycles the models). It's not doing anything special at all when it's rendering and the trick is to not make the lines too thick (I've overdone it on a couple of the models in that sample).

The models were created by...

* loading the original model into max
* make a copy of it
* apply a normal modifier to invert the normals on one of the meshes
* use the 'face extrude' modifier to enlarge the inverted normal model (just a simple scale won't work properly on anything more complicated than a cube)
* apply a black material to the outside object, make sure it's specular is black too as you don't want the light to have any effect.
* export the model to a .X for XNA
* render as any other model

http://www.bigfizz.com/toontest/teapot.JPG
http://www.bigfizz.com/toontest/torus.JPG
http://www.bigfizz.com/toontest/pumpkin.JPG
http://www.bigfizz.com/toontest/tank.JPG

vjvj
10-27-2007, 05:53 PM
Ok... First off, I think elias is asking about the triangle interior shading, not the black outlines (black outlines != cell shading). Forgive me if I'm wrong, and forgive me for being the graphics terminology nazi :)

The only cel-shading implementation I've seen was a palette-based technique that was extremely efficient, so I'm surprised the other stuff out there is so expensive.

Can you provide a link to the GLSL implementation? I'll take a look at the shader; I can't see any reason why it couldn't be ported to GL's arbvp1/arbfp1 shader profile (if not fixed function), which would reduce your OpenGL min spec by quite a bit.

I'll take a more in-depth look at this tomorrow; sorry, lotsa Halloween parties today haha.

Surrealix
10-27-2007, 06:03 PM
do you have any examples of this in practice? I would like to see what this looks like.

The BuzzyBots (http://planethalflife.gamespy.com/View.php?view=HLMotw.Detail&id=93&game=4) mod for Half-Life used this effect, it worked really well, and I seem to recall reading somewhere that XIII used this technique as well.

luggage
10-27-2007, 06:05 PM
Depending on the effect you want to achieve, just using a simple outline and no lighting at all would give a cartoon look.

Here's (http://creators.xna.com/Headlines/developmentaspx/archive/2007/01/01/Non_2D00_Realistic-Rendering.aspx) a link to an XNA sample that implements a cartoon effect with banded lighting. Should be easy enough to lift the shader out and use that.

elias4444
10-27-2007, 08:49 PM
vjvj wins the prize for hitting the nail on the head! Correct! I already have outlining implemented, no problem if I decide to use that. It's the shading that's getting me. I want to implement a toon style shading rather than the standard shading that openGL gives.

The only cel-shading implementation I've seen was a palette-based technique that was extremely efficient, so I'm surprised the other stuff out there is so expensive.
Efficient, yes, but doesn't use any hardware acceleration. There are some ways to implement it by putting everything into VBOs, but you still have to loop through every single triangle and calculate the lighting for every frame. In casual games that are meant to run on pretty minimal hardware, that's a framerate killer.

As for the GLSL implementation, I've only seen it. I don't have access to the code. I only know they were using GLSL, which would, once again, limit the hardware usage to only "newer" video cards and drivers that support shaders.

I've experimented just turning all the lighting off, which certainly gives everything a cartoony look, but it's the look from those old 1970s cartoons, which isn't what I'm going for. Who knows? Maybe what I'm trying to do just isn't possible without taking a performance hit. But, I figured if it was possible, one of the many geniuses on this forum would certainly know a way. :D

Applewood
10-28-2007, 06:19 AM
Hang on a sec, you want to light a model (the method is irrelevant) without running over each pixel or each vertex and calculating lighting details ? If you figure this one out, do share...... ;)

I think I get what you mean though - you want some sort of shading, but it doesn't have to be dynamic ?

In that case, produce a cube-map that is made of several bands of colour, fading out toward where you want the lighting to be. Apply this cubemap with some sort of modulate to everything you want toon lit.

Dunno how you actually do that in OGL as I'm a DX guy through and through, but it must be possible somehow. You can produce a CPU generated cubemap easily using D3DX but if you don't have access to that you'll need to make your own map procedurally or maybe do it in bryce or something.

Does this make sense ?

vjvj
10-28-2007, 06:27 PM
Yeah, I have the same response... If a dot product per vertex is "expensive", my next two questions are a) what is your desired min spec, and b) how many triangles are you rendering per frame?

I took a look at the Nehe tutorial on cell shading, and that was exactly the technique I was thinking of; a single 1D texture that applies a gradient with discreet levels of falloff.

supagu
10-28-2007, 06:43 PM
you could try baking out some special cubemaps with toony lighting and not use glLight at all