Search Unity

  1. Get all the Unite Berlin 2018 news on the blog.
    Dismiss Notice
  2. Unity 2018.2 has arrived! Read about it here.
    Dismiss Notice
  3. Improve your Unity skills with a certified instructor in a private, interactive classroom. Learn more.
    Dismiss Notice
  4. ARCore is out of developer preview! Read about it here.
    Dismiss Notice
  5. Magic Leap’s Lumin SDK Technical Preview for Unity lets you get started creating content for Magic Leap One™. Find more information on our blog!
    Dismiss Notice
  6. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

Custom toon and outline shader

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

  1. Mehd

    Mehd

    Joined:
    Apr 29, 2016
    Posts:
    65
    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:
    2,358
  3. Mehd

    Mehd

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

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    4,521
    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);