162 lines
4.6 KiB
GLSL
162 lines
4.6 KiB
GLSL
#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.;
|
|
}*/
|