• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Jick87 · May 09, 2017 at 05:22 AM · shadergeometrypost-process-effecttoonedge detection

How to Get Nice Thick Toon-Like Outlines On Non-Smooth Geometry?

I've been searching all over trying to find a good solution for this. Been through piles and piles of forum threads, answers on this site, and random blog posts. I've tried many free and non-free assets to no avail.

I want to have nice thick toon-style outlines on all the objects in my game.

I've tried tons of toon shaders but all of them that I can find suffer from the same problems. All your geometry has to be smooth in order for the extruded normals method (which almost all toon shaders use) to work correctly. Unfortunately that is not an option for my current project. Most of my geometry is sharp and I need it that way.

I've also been trying edge detection post effects, with limited success. The edge detection script included in the standard assets doesn't seem to want to do what I need. I've tried tons of different variations but I can't seem to get anything that looks good. If you try thick lines with that you get various other undesirable artifacts. If you tone it down to where the artifacts are less pronounced you can barely see the outlines. I've tried all the different modes offered by the script, but none of them seem to offer any real solution.

I even came across this at some point. However I'm not very sure on how to implement that, and it also might not be performant enough to work on every object in the game at the same time, which is what I need for my project.

I also read about using geometry shaders to do it, but from what I understand that can't be done in Unity currently because Unity does not provide adjacency information to shaders.

There is also plenty of theory posts out there in various places, that discuss how you might do it, but I really need more of a hands-on approach. Like, with code examples and such.

As I said, I've been through tons of searching and not found anything that solves my problem. Most of the stuff I can find is older posts which might be outdated by now. So, I figured I'd ask now to see if there is any new options in this area. Or perhaps there is a way to get one of the other options working and I just haven't seen it.

Sorry if this has been addressed somewhere before and I just missed it...

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
2

Answer by Namey5 · May 09, 2017 at 07:41 AM

This is a custom shader I wrote a while back that I generally use instead for this reason;

 Shader "Custom/CustomOutline" {
     Properties {
         _Color ("Color", Color) = (1,1,1,1)
         _Outline ("Outline Color", Color) = (0,0,0,1)
         _MainTex ("Albedo (RGB)", 2D) = "white" {}
         _Glossiness ("Smoothness", Range(0,1)) = 0.5
         _Metallic ("Metallic", Range(0,1)) = 0.0
         _Size ("Outline Thickness", Float) = 1.5
     }
     SubShader {
         Tags { "RenderType"="Opaque" }
         LOD 200
         
         Pass {
             Cull Front
 
             CGPROGRAM
             #pragma vertex vert
             #pragma fragment frag
 
             #include "UnityCG.cginc"
 
             half _Size;
 
             fixed4 _Outline;
 
             struct v2f {
                 float4 pos : SV_POSITION;
             };
 
             v2f vert (appdata_base v) {
                 v2f o;
                 v.vertex.xyz *= _Size;
                 v.normal *= -1;
                 o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
                 return o;
             }
 
             half4 frag (v2f i) : SV_Target
             {
                 return _Outline;
             }
             ENDCG
         }
 
         Cull Back
 
         CGPROGRAM
         // Physically based Standard lighting model, and enable shadows on all light types
         #pragma surface surf Standard fullforwardshadows
 
         // Use shader model 3.0 target, to get nicer looking lighting
         #pragma target 3.0
 
         sampler2D _MainTex;
 
         struct Input {
             float2 uv_MainTex;
         };
 
         half _Glossiness;
         half _Metallic;
         fixed4 _Color;
 
         void surf (Input IN, inout SurfaceOutputStandard o) {
             // Albedo comes from a texture tinted by color
             fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
             o.Albedo = c.rgb;
             // Metallic and smoothness come from slider variables
             o.Metallic = _Metallic;
             o.Smoothness = _Glossiness;
             o.Alpha = c.a;
         }
         ENDCG
     }
     FallBack "Diffuse"
 }

Rather than extrude along the normal, I figured it was a better idea to extrude based upon the vector from the origin towards the vertex position. An easy way of doing this is to simply multiply the local vertex position.

Comment
Add comment · Show 7 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Namey5 · May 09, 2017 at 08:09 AM 1
Share

This will only work for some objects, however. If you want the distortion to be distributed equally for unsymmetrical objects, you can replace the displacement line with this;

 v.vertex.xyz += normalize (v.vertex.xyz) * _Size;

I'm currently working on a proper post processing outline effect that doesn't rely on object normals and the such (similar to that used in things like Deus Ex), but it's a bit power intensive at the moment.

avatar image Jick87 · May 10, 2017 at 05:20 AM 0
Share

Thanks for the try, however it doesn't seem to work much better than the usual toon outline shaders, at least not with my geometry it seems...

I would definitely be interested in the post processing effect you mention though! I'd be happy to be a tester when you get it closer to a working solution, if you need it. ;)

avatar image Namey5 Jick87 · May 11, 2017 at 06:54 AM 0
Share

https://www.youtube.com/watch?v=hNuhN033PPk

Here's a video showing off the outline effect in a more working state. Still relies on multiple per-pixel samples for full screen in order to look decent, but it works.

avatar image Jick87 Namey5 · May 11, 2017 at 07:36 AM 0
Share

Looks interesting, but would it work with many objects all at the same time? In the video it seems more like a selection outline, for like highlighting one or two specific items, rather than something to outline all objects, like for an overall toon style for the game as a whole. That is more what I'm looking for. I would need to outline pretty much every single object in the scene at the same time for the effect I'm going for.

As I said in my initial post, there are many "options" out there but, all of the solutions I have tried so far fall short of what I would like.

Show more comments
avatar image Patrick2607 · May 11, 2017 at 09:04 AM 0
Share

Thanks for this shader, might come in handy some day :) Cheers!

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

7 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How to smooth out jaggedness of Edge Detection? 0 Answers

Fake directional light on toon shader 0 Answers

Disable backface culling or double geometry? 0 Answers

Toon shader for a cube - outline problem 2 Answers

Shader Assitance: Sprite Outline Color, Hidden Object -1 Answers

  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges