Custom toon and outline shader

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.

  • 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
  • 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: Shaders/ToonAndOutline.shader at master · MoMe36/Shaders · GitHub

And some pictures: (The concerned shader is used on the guy on the left)

3387678--266241--Capture du 2018-02-11 11-34-40.png

Thanks!

Here is Cel Shader with Outline tutorial, which I found easy to follow. Hope it helps:
https://lindseyreidblog.wordpress.com/2017/12/19/cel-shader-with-outline-in-unity/
https://lindseyreidblog.wordpress.com/2018/02/04/colored-outline-shader-in-unity/

Hey, thanks ! But actually, I’m not really in favor of doubling the number of faces for rendering. Is it what you use ?

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);