Outline effects in OpenGL

24,299

Solution 1

They did not use wireframe for this. I guess it is heavily shader related and requires this:

  1. Rendering object to a stencil buffer
  2. Rendering stencil buffer with color of choice while applying blur
  3. Rendering model on top of it

Solution 2

I'm late for an answer but I was trying to achieve the same thing and thought I'd share the solution I'm using.

A similar effect can be achieved in a single draw operation with a not so complex shader.

In the fragment shader, you will calculate the color of the fragment based on lightning and texture giving you the un-highlighted color 'colorA'.

Your second color is the outline color, 'colorB'.

You should obtain the fragment to camera vector, normalize it, then get the dot product of this vector with the fragment's normal.

The fragment to camera vector is simply the inverse of the fragment's position in eye-space.

The colour of the fragment is then:

float CameraFacingPercentage = dot(v_fragmentToCamera, v_Normal);
gl_FragColor = ColorA * CameraFacingPercentage + ColorB * (1 - FacingCameraPercentage);

This is the basic idea but you'll have to play around to have more or less of the outline color. Also, the concave parts of your model will also be highlighted but that is also the case in the image posted in the question.

Solution 3

Detect edges in GLSL shader using dotprod(view,normal)

http://en.wikibooks.org/wiki/GLSL_Programming/Unity/Toon_Shading#Outlines

Solution 4

As far as I see it the effect on the screen short and many "edge" effects are not pure edges, as in comic outline. What mostly is done, you have one pass were you render the object normally then a pass with only the geometry (no textures) and a GLSL shader. In the fragment shader the normal is taken and that normal is perpendicular to the camera vector you color the object. The effect is then smoothed by including area close to perfect perpendicular.

I would have to look up the exact math but I think if you take the dot product of the camera vector and the normal you get the amount of "perpendicularness". That you can then run through a function like exp to get a bias towards 1.

So (without guarantee that it is correct):

exp(dot(vec3(0, 0, 1), normal));

(Note: everything is in screenspace.)

Share:
24,299
dupersuper
Author by

dupersuper

Updated on July 09, 2022

Comments

  • dupersuper
    dupersuper almost 2 years

    In OpenGL, I can outline objects by drawing the object normally, then drawing it again as a wireframe, using the stencil buffer so the original object is not drawn over. However, this results in outlines with one solid color.

    enter image description here

    In this image, the pixels of the creature's outline seem to get more transparent the further they are from the creature they outline. How can I achieve a similar effect with OpenGL?

  • dupersuper
    dupersuper over 11 years
    So we draw the object with a solid color to a texture, then draw that texture over the screen with a blurring shader?
  • weltensturm
    weltensturm over 11 years
    Yes, but it probably isn't the only way to do it.
  • Said algharibi
    Said algharibi over 11 years
    Note that this technique will highlight all visible "edges", not only the outline. Might or might not be desirable.
  • Philip Guin
    Philip Guin about 9 years
    This is essentially how it was done on the title I worked on, though it was problematically slow for us. Consider how much of the screen will contain your outline before committing to this approach -- there are cheaper effects available to communicate that "this model is highlighted". On a modern title, you probably don't have fill rate to spare.
  • Spider
    Spider about 9 years
    Why not doing it by a vertex shader that pushes the vertex by an offset in normal direction, and use that as the outline (flat render), then render the top color after that