Object outline effect design in Unity

I’ve always wanted to learn how to achieve this effect through shaders.
For those unsure what I’m referring to, here’s an example:

Basically an outline around a mesh in its entirety.

Although I’ve yet to even begin learning how to create this type of shader, what has always puzzled me is how the effect would be applied in practice.

If the outline is a dedicated shader in itself, how can it be applied to an object that’s already using a certain shader. Like say the Unity standard shader. Would it have to be directly added to the standard shader or could it be added in post processing?

The following is a really neat looking example of what I’d love to make:

I’m assuming it works with any surface shader so there must be some post processing involved…right?

I’d love to hear thoughts from people on how this is commonly tackled, best practices and so forth.

This isnt really a shader as much as pipeline / postprocessing.
You’d want to set up some code to designate some objects, go though all the submesh materials and set them up to mark a render target or stencil bit.
Using this mask in either a post process or command buffer, you’d apply some sort of dilation or blur filter to have it bleed out of the model coverage area. Then using the mask again, remove the effect from on top of the model. You’re then left with an outline.

Having different objects with different colors like in the image is the same process, although here i imagine the creator is using an RGBA buffer and writing both color and alpha info per model. Then he blurs the color, multiplies with 1-alpha and adds on top of the framebuffer.

1 Like

Interesting.
So essentially, in your example, you’d color over all the materials present in the models using a mask, have them stretch a bit outwards, then draw the regular materials on top?
And this all being done not as a dedicated “outline” shader but in a separate post processing pipeline.

I can’t fathom just yet how much of a technical challenge that is, but it sounds like a very clever yet simple solution. As opposed to adding lines around the object in its entirety.

I’ve found this :

http://wiki.unity3d.com/index.php/Silhouette-Outlined_Diffuse

Scaling a 2d rendered image or scaling a 3d model on normals achieve the same basic result, but including a post-processing step allows you to create various other effects. (perhaps they can also be done with shader-coding but I’m not sufficiently skilled)

1 Like

Indeed. I saw that page a while ago. I think I even tried using it and I remember it being a bit outdated (non functional). It’s one of the things that had me wondering how you would achieve the effect with a dedicated outline shader, in conjunction with the Unity standard shader or even any other diffuse shader.

The question being whether you’d edit the shader you wanted to use to include the outline, or somehow use one after the other. So you could keep the outline on its own in a separate shader without messing up the diffuse shader. Plus, you might have several different diffuse shaders you’d wanna use with the outline shader so needing to edit all of them to include outline code seems rather drastic.
This might all be a gross misunderstanding of how shaders actually work though, seeing as I’m not skilled at writing them either.

The scaling on normals method requires drawing the geometry more than once. (You’ll notice in the example shader there are two passes). If you’re only doing one or a few objects, it should be fine. However with many objects or a high triangle counts, a screen effects can be more efficient and easier to manage.
The scaling method can also suffer from some problems, if your model has split normals, or normals interpolate strangly in certain areas… Also the silhouette would shrink with distance given it is a object / worldspace offset. You could set it up to scale with camera distance, but itll look odd and is hard to control.

Scaling along normals is a pretty old trick. Generally in current games this is almost always implemented as a screen effect. Its easier to manage in the pipeline, the lines are of constant width and don’t depend on surface normals. And also, the geometry doesn’t need to be drawn multiple times. Its also more flexible in terms of what you can do visually, like using the depth buffer or blurring or adding other effects.

example in fallout

2 Likes

Thanks for elaborating. Both methods sound pretty solid in terms of effect.

I’m still a little fuzzy on the post processing though. And generally what’s done in a shader and what can be scripted. Normally are we talking about achieving the effect through a regular script that pieces together the materials in the object, adds the mask etc. as per the example you mentioned before?

3 Likes

Wow, that’s brilliant. :open_mouth: