Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Toon Outline but with Diffuse surface

Discussion in 'Shaders' started by Lokken, Jun 9, 2009.

  1. Lokken

    Lokken

    Joined:
    Apr 23, 2009
    Posts:
    436
    Hi all

    I have been looking through the shader documentation as well as the code in the built in shaders.

    It is definitely something I am going to have to spend some time on. In the mean time for my immediate need I would like to know if anyone has ever tried to get the outline feature of the Toony/Basic Outlined shader and have the actual face have a simple diffuse texture instead of the solid bright toon surface.

    Below is the screenshot I managed to make. It is the exact effect I want.

    I was only able to get this to display by applying the Toony/Basic Outline and then in script changing the shader to Diffuse on a mouse click.

     
  2. Omega

    Omega

    Joined:
    Jul 31, 2007
    Posts:
    125
    :eek:
    I can't believe I know the answer to this one. I wanted this too, and made a modified Toon shader to do it. Simple, really. Just swap out the toon shader UsePass call with one to the diffuse shader, tidy up the code, and you're done!

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

    Lokken

    Joined:
    Apr 23, 2009
    Posts:
    436
    Awesome!

    Thanks a ton for the reply that is exactly what I am needing

    L
     
  4. EducaSoft

    EducaSoft

    Joined:
    Sep 9, 2007
    Posts:
    650
    This looks great.

    Is there a possibility to write a shader which can nicely display ALL edges ?

    At this moment if you look at the outer edges, then they are outlined in black, but the lines between the red/yellow , then yellow/blue and red/blue don't have an outline.

    Is this possible so they all have an outline ?


    Second question, is there maybe a way to make sure that you can setup in your model (static in the model) which edges should get an outline and which not?


    Kind regards,

    Bart
     
  5. aaronsullivan

    aaronsullivan

    Joined:
    Nov 10, 2005
    Posts:
    986
    Please put it up on the wiki, or I will. :)
    http://www.unifycommunity.com/wiki/index.php?title=Shaders

    @EducaSoft
    I'd just do textures that include a dark line where you want it. It won't be perfect because the lines are going to taper due to perspective, but I think the only other way would be some sort of two pass thing where you draw the model and then have a second model rendered with ALL of its lines rendering (otherwise I'm not sure how you'd choose which lines are the important ones.) I only have limited knowledge of shaders, though. I could be wrong.

    Neil Carter with his Pheonix Final game uses the lines in the texture method to cool effect (not exactly what you want, but close?)
    http://www.nether.org.uk/phoenix_final/torpedoes.html

    Also, I like that archer in your avatar Omega.
     
  6. EducaSoft

    EducaSoft

    Joined:
    Sep 9, 2007
    Posts:
    650
    AaronSullivan,

    Maybe this is indeed the best way to solve it for me.
    I'll have a try thanks for hints
     
  7. Omega

    Omega

    Joined:
    Jul 31, 2007
    Posts:
    125
    @ EducaSoft
    The shader I posted can't work on all the edges, since all the default toon shader it does is move the faces out along their normals (with some scaling correction), color them, then draw the normal object on top of it. This becomes visible when one turns the distance waaaaaayyyy up on a non-sphere. (Try the cube!)

    To get all the lines, um, "lined" one either has to write a shader to (somehow) stroke the geometry, "stroke" the mesh with a line renderer, (but that could produce a fair amount of geometry in addition to another object), or bake it into the texture (as Aaron suggested). When going with the last one, just don't hide the UV map texture (which I'm sure you exported from your 3d program of choice) and you're 9/10 there.

    @Aaron
    Thanks! He's Hunter the Cheetah from Spyro. That particular image I found on Wikia and touched up somewhat.
     
  8. aaronsullivan

    aaronsullivan

    Joined:
    Nov 10, 2005
    Posts:
    986
  9. Nick-Wiggill

    Nick-Wiggill

    Joined:
    Jan 31, 2010
    Posts:
    46
    Just to point out that as at least one other person wants to use this (me), I strongly suggest someone put it up on that wiki.

    :wink:

    (thanks for the great info)
     
  10. Kuba

    Kuba

    Moderator

    Joined:
    Jan 13, 2009
    Posts:
    416
    In the Shader Replacement Project there is an Edge Detection image effect which looks at the differences in normals and depth for neighbouring pixels and where the difference is big - colours the pixels black. E.g. look at the rocks here: PuzzleBloom.
     
  11. aaronsullivan

    aaronsullivan

    Joined:
    Nov 10, 2005
    Posts:
    986
  12. AndrewGrayGames

    AndrewGrayGames

    Joined:
    Nov 19, 2009
    Posts:
    3,821
    This is some great stuff, I was thinking of modifying this for a sort of holographic/Tron-esque look.

    EDIT: I've used this for a Tron-esque look. I use a single directional light, I just dropped its strength to 0.162 (1/10 of Phi, my favorite number to use), and played with the edge settings. My way of covering up the awful programmer art I made.
     

    Attached Files:

  13. Nick-Wiggill

    Nick-Wiggill

    Joined:
    Jan 31, 2010
    Posts:
    46
    Hi guys,

    This thread was a life-saver for me. As a result of Omega's script, I created a little hybrid shader that allow for highlighted object picking as in eg. Dungeon Siege -- see separate thread with the new shader source.

    Thank you for sharing! Great community we've got here. 8)
     
  14. hellraizerhhh

    hellraizerhhh

    Joined:
    May 26, 2010
    Posts:
    619
    Used your shader code and other codes out there but im trying to achieve an effect like this
    http://www.ixbt.com/video2/images/terms2k5/toon_tmnt.jpg

    Judging by what other people have done you need some sort of cubemap to get the lighting to appear to show the light and dark sides on a character. I'm a bit lost since I'm an artist and know nothing of shaders :) Any help is appreciated thanks guys
     
  15. mouf

    mouf

    Joined:
    May 3, 2010
    Posts:
    30
  16. Vert

    Vert

    Joined:
    Mar 23, 2010
    Posts:
    1,099
    How hard is it to add a bump map to this? I am looking for an outlined Bumped Specular and Bumped Diffuse Shader. I have looked into using different passes but couldn't figure out how to do it myself. :?
     
  17. Esa

    Esa

    Joined:
    Mar 18, 2010
    Posts:
    39
    Is it possible to access material's Outline Color by script? I could change the material's color by renderer.material.color, but could not find a way to manipulate the outline color.
     
  18. Esa

    Esa

    Joined:
    Mar 18, 2010
    Posts:
    39
    This helped a lot, thank you.
     
  19. Bren

    Bren

    Joined:
    Aug 28, 2008
    Posts:
    191
    This shader doesn't seem to work with an Orthographic camera. Any idea why?
     
  20. PsychicToaster

    PsychicToaster

    Joined:
    Jan 9, 2010
    Posts:
    13
    I can't seem to get this shader working in Unity 3. Can anyone shed some light on it?
     
  21. alejocadavid

    alejocadavid

    Joined:
    May 7, 2010
    Posts:
    20
    I have the same problem here.

    UsePass "Diffuse/BASE"?? Where do i get that stuff??

    Help Please :)
     
  22. pretender

    pretender

    Joined:
    Mar 6, 2010
    Posts:
    862
    i am wondering if you can control the width of the outline in this shader...i tried modifying
    this line:

    Code (csharp):
    1. _Outline ("Outline width", Range (0.005, 0.001)) = 0.005
    but it seems unchanged....also changing the color in the script does not affect material
    what i am doing wrong?
     
  23. pretender

    pretender

    Joined:
    Mar 6, 2010
    Posts:
    862
    ok, i figured out what i was doing wrong...
    i have very limitied knowledge about shaders, can somebody tell me if it is possible to modify this shader so the outline is always
    shown on top of everything else? i hope it is something that is quickly fixable, thanks!
     
  24. VicciGames

    VicciGames

    Joined:
    May 23, 2013
    Posts:
    24
    In replying to the edges of the toon shading. I read that smoothing out the geometry on the edges of the mesh (beveling) will solve the problem. Never actually tried it. If it works please tell me :)
     
  25. Mars91

    Mars91

    Joined:
    Mar 6, 2012
    Posts:
    572
    Hi,
    I wanted to use this shader but I can't get it working when using "Deffered Lighting" this shader seems to work only when Rendering Path is set to "Forward". Can someone figure out why?

    Code (csharp):
    1.  
    2. Shader"DiffuseToon" {
    3. Properties
    4.  {
    5. _Color ("MainColor", Color) = (.5,.5,.5,1)
    6. _OutlineColor ("OutlineColor", Color) = (0,1,0,1)
    7. _Outline ("Outlinewidth", Range (0.002, 0.03)) = 0.01
    8. _MainTex ("Base (RGB)", 2D) = "white" { }
    9.  }
    10.  
    11.  
    12. SubShader
    13.  {
    14. Tags { "RenderType"="Opaque" }
    15. LOD200
    16.  
    17.  
    18. CGPROGRAM
    19. #pragmasurfacesurfLambert
    20.  
    21. sampler2D_MainTex;
    22. fixed4_Color;
    23.  
    24. structInput {
    25. float2uv_MainTex;
    26.  };
    27.  
    28. voidsurf (InputIN, inoutSurfaceOutputo) {
    29. fixed4c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
    30. o.Albedo = c.rgb;
    31. o.Alpha = c.a;
    32.  }
    33. ENDCG
    34.  
    35. Pass
    36.  {
    37. Name"OUTLINE"
    38. Tags { "LightMode" = "Always" }
    39.  
    40. CGPROGRAM
    41. //UpgradeNOTE: excludedshaderfromOpenGLES2.0becauseitdoesnotcontainasurfaceprogramorbothvertexandfragmentprograms.
    42. #pragmaexclude_renderersgles
    43. //UpgradeNOTE: excludedshaderfromDX11andXbox360; hasstructswithoutsemantics (structappdatamembersvertex,normal)
    44. #pragmaexclude_renderersd3d11xbox360
    45. #pragmavertexvert
    46.  
    47. structappdata {
    48. float4vertex;
    49. float3normal;
    50.  };
    51.  
    52. structv2f {
    53. float4pos : POSITION;
    54. float4color : COLOR;
    55. floatfog : FOGC;
    56.  };
    57. uniformfloat_Outline;
    58. uniformfloat4_OutlineColor;
    59.  
    60. v2fvert(appdatav) {
    61. v2fo;
    62. o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
    63. float3norm = mul ((float3x3)UNITY_MATRIX_MV, v.normal);
    64. norm.x *= UNITY_MATRIX_P[0][0];
    65. norm.y *= UNITY_MATRIX_P[1][1];
    66. o.pos.xy += norm.xy * o.pos.z * _Outline;
    67.  
    68. o.fog = o.pos.z;
    69. o.color = _OutlineColor;
    70. returno;
    71.  }
    72. ENDCG
    73.  
    74. CullFront
    75. ZWriteOn
    76. ColorMaskRGB
    77. BlendSrcAlphaOneMinusSrcAlpha
    78. SetTexture [_MainTex] { combineprimary }
    79.  }
    80.  }
    81.  
    82. Fallback"Diffuse"
    83. }
    84.  
     
  26. Deathpyre

    Deathpyre

    Joined:
    Mar 17, 2013
    Posts:
    1
  27. Onsterion

    Onsterion

    Joined:
    Feb 21, 2014
    Posts:
    215
    Outline Diffuse for WebGL?