Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

A better toon outline shader?

Discussion in 'Shaders' started by degeneration, Apr 2, 2009.

  1. degeneration

    degeneration

    Joined:
    Apr 3, 2008
    Posts:
    115
    Hi,

    Firstly I know very little about shaders, I am looking to learn but I need to find a quick solution to my problem.

    I'm working on a project where I want to make it really obvious what objects can and can't be interacted with. The toon outline shader seemed like the obvious option, but when applied I get this effect...



    The gaps on the corner and above and below aren't acceptable. I need the outline to be quite thick like this dodgy photoshop...



    Does anyone know of such a shader? I only want this to work on certain objects, not the whole scene.
     
  2. User340

    User340

    Joined:
    Feb 28, 2007
    Posts:
    3,001
    Increasing the objects smoothing angle should improve this.
     
  3. degeneration

    degeneration

    Joined:
    Apr 3, 2008
    Posts:
    115
    No joy I'm afraid. The original "door" was a cube created inside Unity, so I created a "door" in Max and imported by FBX so I could change the smoothing angle, but it did nothing to a cube.
     
  4. jonas-echterhoff

    jonas-echterhoff

    Unity Technologies

    Joined:
    Aug 18, 2005
    Posts:
    1,666
    I agree with Daniel. The normals need to be perfectly smooth for the toon shader to give good results. Try setting the smoothing angle to 1 or 0 (and enable "Calculate Normals").
     
  5. degeneration

    degeneration

    Joined:
    Apr 3, 2008
    Posts:
    115
    Whoops... Look like someone didn't hit "Apply" when he changed the smooth normals....
     
  6. SimonAlkemade

    SimonAlkemade

    Joined:
    Feb 4, 2009
    Posts:
    432
    i also discovered another problem with the toon shader and that is that the outlines always ramain the same thickness.
    I think the best way to solve this is to write a post proccessing effect for the outline but I first have to figure out how to do that.
    See the problem here:
     

    Attached Files:

  7. antenna-tree

    antenna-tree

    Joined:
    Oct 30, 2005
    Posts:
    5,324
    This modified shader has the z position taken out of the equation that determines the line thickness:

    Code (csharp):
    1.  
    2. Shader "Toon/Basic Outline" {
    3.     Properties {
    4.         _Color ("Main Color", Color) = (.5,.5,.5,1)
    5.         _OutlineColor ("Outline Color", Color) = (0,0,0,1)
    6.         _Outline ("Outline width", Range (.002, 0.03)) = .005
    7.         _MainTex ("Base (RGB)", 2D) = "white" { }
    8.         _ToonShade ("ToonShader Cubemap(RGB)", CUBE) = "" { Texgen CubeNormal }
    9.     }
    10.  
    11.     SubShader {
    12.         Tags { "RenderType"="Opaque" }
    13.         UsePass "Toon/Basic/BASE"
    14.         Pass {
    15.             Name "OUTLINE"
    16.             Tags { "LightMode" = "Always" }
    17. CGPROGRAM
    18. #pragma vertex vert
    19.  
    20. struct appdata {
    21.     float4 vertex;
    22.     float3 normal;
    23. };
    24.  
    25. struct v2f {
    26.     float4 pos : POSITION;
    27.     float4 color : COLOR;
    28.     float fog : FOGC;
    29. };
    30. uniform float _Outline;
    31. uniform float4 _OutlineColor;
    32.  
    33. v2f vert(appdata v) {
    34.     v2f o;
    35.     o.pos = mul(glstate.matrix.mvp, v.vertex);
    36.     float3 norm = mul ((float3x3)glstate.matrix.modelview[0], v.normal);
    37.     norm.x *= glstate.matrix.projection[0][0];
    38.     norm.y *= glstate.matrix.projection[1][1];
    39.     o.pos.xy += norm.xy * _Outline;
    40.    
    41.     o.fog = o.pos.z;
    42.     o.color = _OutlineColor;
    43.     return o;
    44. }
    45. ENDCG
    46.             //Color (0,0,0,0)
    47.             Cull Front
    48.             ZWrite On
    49.             ColorMask RGB
    50.             Blend SrcAlpha OneMinusSrcAlpha
    51.             SetTexture [_MainTex] { combine primary }
    52.         }
    53.     }
    54.    
    55.     Fallback "Toon/Basic"
    56. }
     
  8. Luisdiv

    Luisdiv

    Joined:
    Sep 17, 2012
    Posts:
    8
    This is an old thread I know.. Still, this is a nice shader, great work antenna!

    I tried using it on iOS, but it removes the outline :(...

    I have zero experience on shaders. Is there any chance of making it work for iOS?
     
  9. Gemberkoekje

    Gemberkoekje

    Joined:
    Mar 12, 2013
    Posts:
    2
    Normally, you need to set up your iOS project to use 'OpenGL ES 2.0' instead of OpenGL ES 1.x or earlier versions. This is because only 2.0 properly supports shaders.

    Unfortunately, due to not knowing overly much about Unity, I can't really help you with how to do it, but I hope it helps either way.
     
  10. Kerihobo

    Kerihobo

    Joined:
    Jun 26, 2013
    Posts:
    61
    I know this is an old thread, but you can do this in your modelling package without having to delve in to shaders.

    simply duplicate your mesh, apply a black material to it, use whatever function your modelling package has to push the mesh outwards based on normal angle, and reverse the normals.

    Now when you bring it in to unity, you'll have a perfect outline that's whatever size you wanted it to be when you were in maya/max/blender/whatever
     
  11. Adinnoh

    Adinnoh

    Joined:
    May 5, 2015
    Posts:
    3
    This will work, for sure, but will also double your triangles count. And if you work for mobile or "normal" PCs this will kill your game.