#version 130 const float e = 2.7182818284; const float pi = 3.1415926; float Phong_diffuse(vec3 l, vec3 n, vec3 h, vec3 v, float shininess) { return max(dot(n, l), 0.); } float Phong_specular(vec3 l, vec3 n, vec3 h, vec3 v, float shininess) { return pow(max(dot(n, h), 0.), shininess); } float Cook_Torrance_diffuse(vec3 l, vec3 n, vec3 h, vec3 v, float shininess) { return max(dot(n, l), 0.); } float Cook_Torrance_specular(vec3 l, vec3 n, vec3 h, vec3 v, float shininess) { float NdotL = max( dot( n, l ), 0. ); float NdotV = max( dot( n, v ), 0. ); float NdotH = max( dot( n, h ), 1.e-7 ); float VdotH = max( dot( v, h ), 0. ); float geometric = 2. * NdotH / VdotH; geometric = min(1., geometric * min(NdotV, NdotL)); float r_sq = 1. / (shininess * shininess); float NdotH_sq = NdotH * NdotH; float NdotH_sq_r = 1. / (NdotH_sq * r_sq); float roughness_exp = (NdotH_sq - 1.) * (NdotH_sq_r); float roughness = exp(roughness_exp) * NdotH_sq_r / (4. * NdotH_sq); float fresnel = 1. / (1. + NdotV); return min(1., (fresnel * geometric * roughness) / (NdotV * NdotL + 1.e-7)); } float Minnaert_diffuse(vec3 l, vec3 n, vec3 h, vec3 v, float shininess) { return max(dot(n, l), 0.); } float Minnaert_specular(vec3 l, vec3 n, vec3 h, vec3 v, float shininess) { float k = shininess / 128.; float d1 = pow(max(dot(n, l), 0.), 1. + k); float d2 = pow(1. - dot(n, v), 1. - k); return d1*d2; } float fresnel(float x, float kf) { float dx = x - kf; float d1 = 1.0 - kf; float kf2 = kf * kf; return (1.0 / (dx * dx) - 1.0 / kf2) / (1.0 / (d1 * d1) - 1.0 / kf2 ); //return 1.0; } float shadow(float x, float ks) { float dx = x - ks; float d1 = 1.0 - ks; float ks2 = ks * ks; //return (1.0 / (dx * dx) - 1.0 / ks2) / (1.0 / (d1 * d1) - 1.0 / ks2 ); return 1.0; } const float smooth_ = 0.5; const float transp = 0; const float k = 0.1; const float kf = 1.12; const float ks = 1.01; float Strauss_diffuse(vec3 l, vec3 n, vec3 h, vec3 v, float shininess) { vec3 h2 = reflect(l, n); float metal = shininess / 20.; float nl = dot( n, l); float nv = dot( n, v); float hv = dot( h2, v); float f = fresnel( nl, kf ); float s3 = smooth_ * smooth_ * smooth_; // diffuse term float d = ( 1.0 - metal * smooth_ ); float Rd = ( 1.0 - s3 ) * ( 1.0 - transp ); float diff = nl * d * Rd; // inputs into the specular term // composite the final result, ensuring return max(diff, 0.); } float Strauss_specular(vec3 l, vec3 n, vec3 h, vec3 v, float shininess) { vec3 h2 = reflect(l, n); float metal = shininess / 20.; float nl = dot( n, l); float nv = dot( n, v); float hv = dot( h2, v); float f = fresnel( nl, kf ); float s3 = smooth_ * smooth_ * smooth_; // diffuse term float d = ( 1.0 - metal * smooth_ ); float Rd = ( 1.0 - s3 ) * ( 1.0 - transp ); float diff = nl * d * Rd; // inputs into the specular term float r = (1.0 - transp) - Rd; float j = f * shadow ( nl, ks ) * shadow ( nv, ks ); float refl = min ( 1.0, r + j * ( r + k ) ); float Cs = 1. + metal * (1.0 - f); float spec = Cs * refl; spec *= pow ( -hv, 3.0 / (1.0 - smooth_) ); // composite the final result, ensuring return max(spec, 0.); } uniform float a, b; float Oren_Nayar_diffuse(vec3 l, vec3 n, vec3 h, vec3 v, float shininess) { float nl = dot ( n, l ); float nv = dot ( n, v ); vec3 lProj = normalize ( l - n * nl ); vec3 vProj = normalize ( v - n * nv ); float cx = max ( dot ( lProj, vProj ), 0.0 ); float cosAlpha = nl > nv ? nl : nv; float cosBeta = nl > nv ? nv : nl; float dx = sqrt ( ( 1.0 - cosAlpha * cosAlpha ) * ( 1.0 - cosBeta * cosBeta ) ) / cosBeta; return max(0. , nl) * (a + b * cx * dx); //return max(dot(n, l), 0.); } float Oren_Nayar_specular(vec3 l, vec3 n, vec3 h, vec3 v, float shininess) { return pow(max(dot(n, h), 0.), shininess); } /* float light_diffuse(int model, vec3 l, vec3 n, vec3 h, vec3 v, float shininess) { if (model == 0) return Phong_diffuse(l, n, h, v, shininess); if (model == 1) return Cook_Torrance_diffuse(l, n, h, v, shininess); if (model == 2) return Minnaert_diffuse(l, n, h, v, shininess); if (model == 3) return Strauss_diffuse(l, n, h, v, shininess); if (model == 4) return Oren_Nayar_diffuse(l, n, h, v, shininess); return 0.; } float light_specular(int model, vec3 l, vec3 n, vec3 h, vec3 v, float shininess) { if (model == 0) return Phong_specular(l, n, h, v, shininess); if (model == 1) return Cook_Torrance_specular(l, n, h, v, shininess); if (model == 2) return Minnaert_specular(l, n, h, v, shininess); if (model == 3) return Strauss_specular(l, n, h, v, shininess); if (model == 4) return Oren_Nayar_specular(l, n, h, v, shininess); return 0.; }*/