//pref
Ambient|float|0.0|0.4|1
Diffuse|float|0.0|0.8|1
Specular|float|0.0|0.5|1
Roughness|float|0.001|0.15|0.5
Smooth|float|0.01|1|5
OutlineWidth|float|0.5|0.75|1.0
ShowGradient|bool|false
AOradius|float|0|0|16
Philip Rideout cel shading, Copyright 2010, MIT License|note
//vert
#version 330
layout(location = 0) in vec3 Vert;
layout(location = 3) in vec3 Norm;
layout(location = 6) in vec4 Clr;
out vec3 vN, vL, vV;
out vec4 vClr, vP;
uniform mat4 ModelViewProjectionMatrix;
uniform mat4 ModelViewMatrix;
uniform mat3 NormalMatrix;
uniform vec3 LightPos = vec3(0.0, 20.0, 30.0); //LR, -DU+, -FN+
void main() {
    vN = normalize((NormalMatrix * Norm));
    vP = vec4(Vert, 1.0);
    gl_Position = ModelViewProjectionMatrix * vec4(Vert, 1.0);
    vL = normalize(LightPos);
    vV = -vec3(ModelViewMatrix*vec4(Vert,1.0));
    vClr = Clr;
}
//frag
#version 330
in vec4 vClr, vP;
in vec3 vN, vL, vV;
out vec4 color;
uniform float Ambient = 0.4;
uniform float Diffuse = 0.7;
uniform float Specular = 0.6;
uniform float Roughness = 0.1;
uniform float Smooth = 1.0;
uniform float OutlineWidth = 0.0;
uniform vec4 ClipPlane = vec4(2.0, 0.0, 0.0, 0.0);
uniform bool ShowGradient = false;

float stepmix(float edge0, float edge1, float E, float x) {
    float T = clamp(0.5 * (x - edge0) / E, 0.0, 1.0);
    return mix(edge0, edge1, T);
}

vec3 desaturate(vec3 color, float amount) {
    vec3 gray = vec3(dot(vec3(0.2126,0.7152,0.0722), color));
    return vec3(mix(color, gray, amount));
}

void main() {
	if ((ClipPlane[0] < 1.5) && (dot( ClipPlane, vP) > 0.0)) discard;
	vec3 a = vClr.rgb;
	vec3 d = a * Diffuse;
	a *= Ambient;
	vec3 n = normalize(vN);
    vec3 l = normalize(vL);
    float df = dot(n, l);
    vec3 backcolor = desaturate(0.75 * a + 0.75 * abs(df) * d, 0.5);
    vec3 Eye = vec3(0, 0, 1);
    vec3 h = normalize(l + Eye);
    float specular =  pow(max(0.0,dot(n,h)),1.0/(Roughness * Roughness)) * Specular;
	float E = fwidth(specular) * Smooth;
	specular = smoothstep(0.3 - E, 0.3 + E, specular);
    const float A = 0.1;
    const float B = 0.3;
    const float C = 0.6;
    const float D = 1.0;
    E = fwidth(df) * Smooth;
    if (df < A + E) df = stepmix(A, B, E, df);
    else if (df < B + E) df = stepmix(B, C, E, df);
    else df = stepmix(C, D, E, df);
	float outline = mix(1.0, dot(vec3(0, 0, 1),n), OutlineWidth);

	#define antialias
	#ifdef antialias
    E = fwidth(outline);
    if (outline > 0.5 - E && outline < 0.5 + E)
    {
        outline = smoothstep(0.5 - E, 0.5 + E, outline);
    }
    else
    {
        outline = step(0.5, outline);
    }
    #endif
    //outline *= step(0.001, OutlineWidth);
    //specular = mix(specular, -1.0, outline);
	float backface = step(0.0, n.z);
	color.rgb = mix(a + df * d + specular, (n) + specular, float(ShowGradient) );
	color.rgb *= outline;
	color = vec4(mix(backcolor.rgb, color.rgb,  backface), 1.0);
}
//Unless otherwise stated in the file itself, all source code in
//this folder (and its descendent folders) is covered by the MIT
//License, described as follows:
//
//Copyright (c) 2010 Philip Rideout
//
//Permission is hereby granted, free of charge, to any person
//obtaining a copy of this software and associated documentation
//files (the "Software"), to deal in the Software without
//restriction, including without limitation the rights to use,
//copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the
//Software is furnished to do so, subject to the following
//conditions:
//
//The above copyright notice and this permission notice shall be
//included in all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
//EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
//OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
//NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
//HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
//WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
//FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
//OTHER DEALINGS IN THE SOFTWARE.
