Search Unity

Outline Shader

Discussion in 'Shaders' started by ProjectCryken, Nov 14, 2013.

  1. ProjectCryken

    ProjectCryken

    Joined:
    Jul 25, 2012
    Posts:
    41
    My entire game consists only of materials that are white, so in order for people to tell when one object ends and another begins I need a black outline around the object. The unity toon shader is inconsistent when it comes to showing lines and generally looks poor. I have zero knowledge of shaders, so any help appreciated. Not unlike this (antichamber): $antichamber.png
     
  2. xiewneqi

    xiewneqi

    Joined:
    Aug 20, 2012
    Posts:
    31
    I think what you need is not outline, but edge detection. Unity has an edge-detection scripts in ImageEffects package, which I think would help you out.
    $cube.jpeg
     
  3. ProjectCryken

    ProjectCryken

    Joined:
    Jul 25, 2012
    Posts:
    41
    Will that work in Unity Free?
     
  4. Mauri

    Mauri

    Joined:
    Dec 9, 2010
    Posts:
    2,664
    Unfortunately, no. Image Effects are Pro-only.
     
  5. ProjectCryken

    ProjectCryken

    Joined:
    Jul 25, 2012
    Posts:
    41
    I guess I need an alternative then. I know shaders can do what I need, I just don't where to find them.
     
  6. Mauri

    Mauri

    Joined:
    Dec 9, 2010
    Posts:
    2,664
    Actually, Unity has four Toon Shading shaders (two are with Outline) and they're also working with Free.
    You'll find them in the Standard Assets or get them via Assets > Import Package > Toon Shading.

    Edit: I saw that you're already aware of the toon shaders. Didn't read your posting properly. My fault.
     
    Last edited: Nov 15, 2013
  7. jRocket

    jRocket

    Joined:
    Jul 12, 2012
    Posts:
    700
    What part of the toon shaders don't you like? I know you can adjust them so line width is consistent. Since you don't have pro, your only other option is to manually make outlines by duplicating the geometry, pushing the verts out in the direction of their normal, and flipping the normals.
     
  8. ProjectCryken

    ProjectCryken

    Joined:
    Jul 25, 2012
    Posts:
    41
    The toon shaders seem to sometimes miss certain edges of models unless you look at it from a specific angle. In my game than can be confusing because all you have to go off are those lines.
     
  9. xiewneqi

    xiewneqi

    Joined:
    Aug 20, 2012
    Posts:
    31
    Toon shaders works fine when normals of rendered objects are consistent, so if you use toon shader to render a cube whose normals at the edge of two adjacent sides are not consistent with normals of the two sides, then toon shader could not get a right consistent outline for these edges. Sorry but I don't know how to handle with this :(.

    Edit: There is a way to improve normals consistent of an objects, in fbx import settings, set "Normals" to "Calculate" and "Smoothing Angle" value as large as possible. And there is also a expensive way to achieve more accurate result. when building models, every model is comprised of two sub-models, a larger one and s small one. the small one is wrapped by the larger one, and when rendering the model, render the larger one with Cull Front, render the small one with normal method. This could get a fine appearance while your vertex numbers could be doubled.

    Here is a simple version of toon shader, you can see vertices in view-space are pushed into normal direction to get a larger version of rendered object in the first pass, and the second pass is used to draw the object self.

    Code (csharp):
    1. Shader "Custom/TestShader"
    2. {
    3.     Properties {
    4.         _OutlineColor ("Outline Color", Color) = (0,0,0,1)
    5.         _Outline ("Outline width", Range (0, 0.1)) = .005
    6.         _MainTex ("Base (RGB)", 2D) = "white" { }
    7.     }
    8.  
    9.     SubShader {
    10.         Tags { "RenderType"="Opaque" }
    11.         Pass
    12.         {
    13.             // Pass drawing outline
    14.             Cull Front
    15.        
    16.             Blend SrcAlpha OneMinusSrcAlpha
    17.            
    18.             CGPROGRAM
    19.             #include "UnityCG.cginc"
    20.             #pragma vertex vert
    21.             #pragma fragment frag
    22.            
    23.             uniform float _Outline;
    24.             uniform float4 _OutlineColor;
    25.             uniform float4 _MainTex_ST;
    26.             uniform sampler2D _MainTex;
    27.  
    28.             struct v2f
    29.             {
    30.                 float4 pos : POSITION;
    31.                 float4 color : COLOR;
    32.             };
    33.            
    34.             v2f vert(appdata_base v)
    35.             {
    36.                 v2f o;
    37.                 o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
    38.                 float3 norm   = mul ((float3x3)UNITY_MATRIX_IT_MV, v.normal);
    39.                 float2 offset = TransformViewToProjection(norm.xy);
    40.                 o.pos.xy += offset  * _Outline;
    41.                 o.color = _OutlineColor;
    42.                 return o;
    43.             }
    44.            
    45.             half4 frag(v2f i) :COLOR
    46.             {
    47.                 return i.color;
    48.             }
    49.                    
    50.             ENDCG
    51.         }
    52.        
    53.         Pass
    54.         {  
    55.             // pass drawing object
    56.            
    57.             CGPROGRAM
    58.             #include "UnityCG.cginc"
    59.             #pragma vertex vert
    60.             #pragma fragment frag
    61.            
    62.             uniform float4 _MainTex_ST;
    63.             uniform sampler2D _MainTex;
    64.  
    65.             struct v2f {
    66.                 float4 pos : POSITION;
    67.                 float2 uv : TEXCOORD0;
    68.             };
    69.            
    70.             v2f vert(appdata_base v) {
    71.                 v2f o;
    72.                 o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
    73.                 o.uv = v.texcoord;
    74.                 return o;
    75.             }
    76.            
    77.             half4 frag(v2f i) :COLOR
    78.             {
    79.                 return tex2D (_MainTex, _MainTex_ST.xy * i.uv.xy + _MainTex_ST.zw);
    80.             }
    81.                    
    82.             ENDCG
    83.         }
    84.     }
    85.    
    86.     Fallback Off
    87. }
     
    Last edited: Nov 16, 2013
    moonglow likes this.
  10. Deleted User

    Deleted User

    Guest

    old thread but still id like to chip in my 2 cents.

    of course it depends on what exactly trying to achive, but you can visualize the white objects with black outline via simple black/white textures.

    works well with cube like shapes. round objects probably need a tex that looks like a simple mesh.