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