Search Unity

  1. We want you to join us at GDC this year! Take a peek at all of the events we will be hosting during the week of GDC.
    Dismiss Notice
  2. Tell us about your experience here and you’ll get early access to the 2018 Game Studios report + more goodies.
    Dismiss Notice
  3. Unity 2017.3 has arrived! Read about it here.
    Dismiss Notice
  4. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice
  5. We've closed the job boards. If you're looking for work, or looking to hire check out Unity Connect. You can see more information here.
    Dismiss Notice

Custom toon and outline shader

Discussion in 'Shaders' started by Mehd, Feb 11, 2018.

  1. Mehd

    Mehd

    Joined:
    Apr 29, 2016
    Posts:
    36
    Hello,

    I'm writing my own custom shader for outline and cel-shading and I'm running into a weird effect that I don't completely understand.

    1. I want three degrees of cel-shading, hence, I created three levels of steps. But no matter how I tweak the values, I can only get two levels of shading in engine
    2. The outline is weird. Only rendering on one side. I tried to take the absolute value of the dot product between world normal and view direction, but in vain.

    Here's the guilty code: https://github.com/Mehd6384/Shaders/blob/master/ToonAndOutline.shader

    And some pictures: (The concerned shader is used on the guy on the left) Capture du 2018-02-11 11-34-07.png Capture du 2018-02-11 11-34-40.png


    Thanks!
     
  2. Peter77

    Peter77

    Joined:
    Jun 12, 2013
    Posts:
    1,721
  3. Mehd

    Mehd

    Joined:
    Apr 29, 2016
    Posts:
    36
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    3,884
    The Input variable viewPos isn't one of the special variables Unity's Surface Shaders do anything with, so it's initialized as float3(1,0,0) and that's it. Your dot product against the IN.worldNormal just results in dot(float3(1,0,0), IN.worldNormal), or the equivalent of just using IN.worldNormal.x.

    You'll need to calculate the "viewPos" value yourself, though traditionally the "viewPos" is the view relative position, which isn't really what you want either since then you'd be doing a dot product between a view space vector and a world space vector. You want the world space camera to world pos direction.

    Replace float3 viewPos; with float3 worldPos; in the Input struct and try this instead (you may need to reverse the order of IN.worldPos and _WorldSpaceCameraPos.xyz):

    float d = dot(normalize(IN.worldPos - _WorldSpaceCameraPos.xyz), IN.worldNormal);