attribute vec3 a_Position; attribute vec3 a_Normal; attribute vec2 a_TexCoord; varying vec2 v_TexCoord; varying vec3 v_Normal; varying vec3 v_Position; varying vec3 Tdir; varying vec3 Bdir; uniform vec3 u_Color; uniform vec3 u_SpecColor; uniform float u_SpecExp_a; uniform float u_SpecExp_b; uniform float u_Texture; uniform sampler2D u_Sampler; uniform vec3 u_LightColor; uniform vec3 u_LightDirection; uniform float u_LightAmbient; uniform vec3 u_CameraPos; uniform float u_Shaded; uniform float u_NPR; uniform float u_Edges; uniform mat4 u_MMatrix; uniform mat4 u_VMatrix; uniform mat4 u_PMatrix; uniform mat4 u_NMatrix; //////////////// void main() { vec4 v = u_VMatrix * u_MMatrix * vec4(a_Position, 1.0); vec4 n = u_NMatrix * vec4(a_Normal, 0); gl_Position = u_PMatrix * v; v_TexCoord = a_TexCoord; v_Normal = normalize(n.xyz); v_Position = v.xyz / v.w; Bdir = normalize(cross(v_Normal, vec3(0.24, 0.0, 0.42))); Tdir = normalize(cross(Bdir, v_Normal)); } ////////////////// // blinn-phong specular reflection vec3 blinnphong(vec3 viewdir, vec3 normal, vec3 lightdir, vec3 lightcol, vec3 matspecular, float matspecexp) { vec3 halfdir = normalize(viewdir + lightdir); float specAng = max(dot(halfdir, normal),0.0); float specular = pow(specAng, matspecexp); return matspecular * lightcol * specular; } vec3 ward(vec3 viewdir, vec3 normal, vec3 lightdir) { vec3 halfdir = normalize(viewdir + lightdir); float mult0 = 1.0 / sqrt(max(0.0, dot(lightdir, normal) * dot(viewdir, normal))); float mult1 = 1.0 / (4.0 * 3.14159 * u_SpecExp_a * u_SpecExp_b); float e = -2.0 * (pow(dot(halfdir, Tdir) / u_SpecExp_a, 2.0) + pow(dot(halfdir, Bdir) / u_SpecExp_b, 2.0)) / (1.0 + dot(halfdir, normal)); return u_SpecColor * max(0.0, dot(lightdir, normal) * mult0 * mult1 * exp(e)); } vec3 bl(vec3 c0, vec3 c1, float t) { if(t <= 0.001) return c0; if(t >= 0.999) return c1; return c0*(1.0-t) + c1*t; } void main() { vec4 tex = texture2D(u_Sampler, v_TexCoord); vec4 color = vec4(u_Color, 1.0) * (1.0-u_Texture) + u_Texture * tex * vec4(u_Color, 1.0); float nDotL = dot(u_LightDirection, v_Normal); vec3 viewdir = normalize(u_CameraPos - v_Position); // compute diffuse+ambient+specular vec3 diffuse = color.xyz * max(0.0,nDotL); vec3 ambient = color.xyz * u_LightAmbient; vec3 specular = ward(viewdir, v_Normal, u_LightDirection); vec3 color_PR = u_LightColor * (diffuse + ambient + specular); // compute NPR float NPR_ramp = 0.0; if(nDotL > 0.7) NPR_ramp = 1.2; else if(nDotL > -0.2) NPR_ramp = 1.0; else NPR_ramp = 0.6; vec3 color_NPR = color.xyz * NPR_ramp; float nDotC = dot(viewdir, v_Normal); float edged = 1.0 * (1.0-u_Edges) + (nDotC < 0.2 ? 0.8 : 1.0)*u_Edges; vec3 c1 = bl(color_PR, color_NPR, u_NPR); vec3 c0 = bl(color.xyz, c1, u_Shaded) * edged; gl_FragColor = vec4(c0, 1.0); //gl_FragColor = vec4(color.xyz * (1.0-u_Shaded) + (color_PR * (1.0-u_NPR) + color_NPR * u_NPR) * u_Shaded * edged, 1.0); }