Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

How can I draw outlines around 3D models? I'm referring to something like the effects in a recent Pokemon game, which appear to have a single-pixel outline around them:

enter image description here enter image description here

share|improve this question
    
Are you using OpenGL? If so, you should search on google how to draw outlines for a model with OpenGL. –  oxysoft Jan 5 at 18:58
    
If you're referring to those particular images you put in there, I can say with a 95% certainty that those are hand drawn 2D sprites, not 3D models –  Panda Pajama Feb 24 at 6:12
    
@PandaPajama: No, those are almost certainly 3D models. There's some sloppiness in what should be hard lines in some frames that I wouldn't expect from hand-drawn sprites, and anyway that's basically how the in-game 3D models look. I suppose I can't guarantee 100% for those specific images, but I can't imagine why anyone would go to the effort of faking them. –  C. A. McCann Jul 30 at 23:39
    
Which game is that, specifically? It looks gorgeous. –  Vegard Aug 2 at 12:35

3 Answers 3

This effect is particularly common in games that make use of cel shading effects, but is actually something that can be applied independently of the cel shading style.

What you are describing is called "feature edge rendering," and is in general process of highlighting the various contours and outlines of a model. There are many techniques available and many papers on the subject.

A simple technique is to render only the silhouette edge, the outmost outline. This can be done as simply as rendering the original model with a stencil write, and then rendering it again in thick wireframe mode, only where there was no stencil value. See here for an example implementation.

That will not highlight the interior contour and crease edges, though (as shown in your pictures). Generally, to do that effectively, you need to extract information about the mesh's edges (based on discontinuities in the face normals on either side of the edge, and build up a data structure representing each edge.

You can then write shaders to extrude or otherwise render those edges as regular geometry overtop your base model (or in conjunction with it). The position of an edge, and normals of the adjacent faces relative to the view vector, are used to determine if a specific edge can be drawn.

You can find further discussion, details and papers with various examples on the internet. For example:

share|improve this answer
    
I can confirm that the stencil method (from flipcode.com) works and looks really nice. You can give the thickness in screen coordinates so the thickness of the outline doesn't depend on the size of the model (nor on the shape of the model). –  Vegard Aug 2 at 14:17

The simplest way to do this, common on older hardware before pixel/fragment shaders, and still used on mobile, is to duplicate the model, reverse the vertex winding order so that the model displays inside out (or if you want to, you can do this in your 3D asset creation tool, say Blender, by flipping surface normals -- same thing), then expand the entire duplicate slightly around it's centre, and finally colour/texture this duplicate completely black. This results in outlines around your original model, if it's a simple model such as a cube. For more complex models with concave forms (such as that in the image below), it is necessary to manually tweak the duplicate model to be somewhat "fatter" than its original counterpart, like a Minkowski Sum in 3D. You could start by pushing each vertex out a bit along its normal to form the outline mesh, as Blender's Shrink/Fatten transform does.

Screen space / pixel shader approaches tend to be slower and harder to implement well, but OTOH don't double the number of vertices in your world. So if you're doing high poly work, best opt for that approach. Given modern console and desktop capacity for processing geometry, I'd not worry about a factor of 2 at all. Cartoon-style = low poly for sure, thus duplicating geometry is easiest.

You can test the effect for yourself in e.g. Blender without touching any code. Outlines should look like the image below, note how some are internal, e.g. under arm. More detail here.

enter image description here.

share|improve this answer
    
Could you please explain, how "expand the entire duplicate slightly around it's centre" complies with this picture, because simple scaling around center would not work for arms and other parts which are not concentric, it also won't work for any model that has holes in it. –  Krom Stern Feb 23 at 20:12
    
@KromStern In some instances, subsets of vertices need to be scaled by hand to accommodate. Amended answer. –  Nick Wiggill Feb 24 at 5:52

For smooth models (very important), this effect is fairly simple. In your fragment/pixel shader you will need the normal of the fragment being shaded. If it is very close to perpendicular (dot(surface_normal,view_vector) <= .01 - you might need to play with that threshold) then color the fragment black instead of its usual color.

This approach "consumes" a little bit of the model to do the outline. This may or may not be what you want. It's very difficult to tell from the Pokemon picture if this is what is being done. It depends on if you expect the outline to be included in any silhouette of the character or if you'd rather have the outline enclose the silhouette (which requires a different technique).

The highlight will be on any part of the surface where it transitions from front-facing to back-facing, including "inner edges" (like the legs on the green Pokemon, or its head - some other techniques would not add any outline to those).

Objects that have hard, non-smooth edges (like a cube) will not receive a highlight in the desired locations with this approach. That means this approach is not an option at all in some cases; I have no idea if Pokemon models are all smooth or not.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.