Files
qad/libs/qglview/shaders/light_models.frag
2020-08-25 22:24:02 +03:00

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.;
}*/