refmod_test

annotate sdr_ref_models.glsl @ 0:b469e6a72636

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 18 Feb 2016 23:15:43 +0200
parents
children
rev   line source
nuclear@0 1 #version 110
nuclear@0 2
nuclear@0 3 #define SQ(x) ((x) * (x))
nuclear@0 4 #define PI 3.141592653
nuclear@0 5
nuclear@0 6 /* -- Lambert's cosine law
nuclear@0 7 * J. H. Lambert, Photometria sive de mensura de gratibus luminis, colorum et umbrae.
nuclear@0 8 * Eberhard Klett, 1760.
nuclear@0 9 */
nuclear@0 10 float lambert(vec3 norm, vec3 ldir)
nuclear@0 11 {
nuclear@0 12 return max(dot(norm, ldir), 0.0);
nuclear@0 13 }
nuclear@0 14
nuclear@0 15 /* -- Phong specular model
nuclear@0 16 * B. T. Phong, "Illumination for Computer Generated Pictures"
nuclear@0 17 * Communications of the ACM, 1975.
nuclear@0 18 */
nuclear@0 19 float phong(vec3 view, vec3 norm, vec3 ldir, float spow)
nuclear@0 20 {
nuclear@0 21 vec3 lref = reflect(-ldir, norm);
nuclear@0 22 return pow(max(dot(lref, view), 0.0), spow);
nuclear@0 23 }
nuclear@0 24
nuclear@0 25 /* -- Blinn-Phong specular model
nuclear@0 26 * J. F. Blinn, "Models of Light Reflection for Computer Synthesized Pictures"
nuclear@0 27 * in Proceedings of SIGGRAPH 1977
nuclear@0 28 */
nuclear@0 29 float blinn(vec3 norm, vec3 hvec, float spow)
nuclear@0 30 {
nuclear@0 31 return pow(max(dot(norm, hvec), 0.0), spow);
nuclear@0 32 }
nuclear@0 33
nuclear@0 34 /* -- Cook & Torrance model.
nuclear@0 35 * R. L. Cook and K. E. Torrance, "A Reflectance Model for Computer Graphics"
nuclear@0 36 * in Proceedings of SIGGRAPH 1981.
nuclear@0 37 */
nuclear@0 38 float cook_torrance(vec3 view, vec3 norm, vec3 ldir, vec3 hvec, float rough, float ior)
nuclear@0 39 {
nuclear@0 40 float m = max(rough, 0.0001);
nuclear@0 41
nuclear@0 42 // various useful dot products
nuclear@0 43 float ndoth = max(dot(norm, hvec), 0.0);
nuclear@0 44 float ndotv = max(dot(norm, view), 0.0);
nuclear@0 45 float ndotl = dot(norm, ldir);
nuclear@0 46 float vdoth = max(dot(view, hvec), 0.0);
nuclear@0 47 float ndoth_sq = SQ(ndoth);
nuclear@0 48
nuclear@0 49 // geometric term (shadowing/masking)
nuclear@0 50 float geom_a = (2.0 * ndoth * ndotv) / vdoth;
nuclear@0 51 float geom_b = (2.0 * ndoth * ndotl) / vdoth;
nuclear@0 52 float geom = min(1.0, min(geom_a, geom_b));
nuclear@0 53
nuclear@0 54 // beckmann microfacet distribution term
nuclear@0 55 float sin2_ang = 1.0 - ndoth_sq; // sin^2(a) = 1 - cos^2(a)
nuclear@0 56 float tan2_ang = sin2_ang / ndoth_sq; // tan^2(a) = sin^2(a) / cos^2(a)
nuclear@0 57 float d_mf = exp(-tan2_ang / SQ(m)) / (SQ(m) * SQ(ndoth_sq));
nuclear@0 58
nuclear@0 59 // fresnel term
nuclear@0 60 float c = vdoth;
nuclear@0 61 float g = sqrt(SQ(ior) + SQ(c) - 1.0);
nuclear@0 62 float ftmp = (c * (g + c) - 1.0) / (c * (g - c) + 1.0);
nuclear@0 63 float fres = 0.5 * (SQ(g - c) / SQ(g + c)) * (1.0 + SQ(ftmp));
nuclear@0 64
nuclear@0 65 return (fres / PI) * (d_mf / ndotl) * (geom / ndotv);
nuclear@0 66 }
nuclear@0 67
nuclear@0 68 /* -- Oren & Nayar model
nuclear@0 69 * M. Oren and S. K. Nayar, "Generalization of Lambert's Reflectance Model"
nuclear@0 70 * in Proceedings of SIGGRAPH 1994.
nuclear@0 71 */
nuclear@0 72 float oren_nayar(vec3 view, vec3 norm, vec3 ldir, float rough)
nuclear@0 73 {
nuclear@0 74 float vdotn = max(dot(view, norm), 0.0);
nuclear@0 75 float ldotn = max(dot(ldir, norm), 0.0);
nuclear@0 76
nuclear@0 77 float theta_r = acos(vdotn);
nuclear@0 78 float theta_i = acos(ldotn);
nuclear@0 79 float cos_pr_minus_pi = dot(normalize(view - norm * vdotn), normalize(ldir - norm * ldotn));
nuclear@0 80 float alpha = max(theta_r, theta_i);
nuclear@0 81 float beta = min(theta_r, theta_i);
nuclear@0 82
nuclear@0 83 float sigma_sq = SQ(rough);
nuclear@0 84 float a = 1.0 - 0.5 * sigma_sq / (sigma_sq + 0.33);
nuclear@0 85 float b = 0.45 * sigma_sq / (sigma_sq + 0.09);
nuclear@0 86
nuclear@0 87 if(cos_pr_minus_pi >= 0.0) {
nuclear@0 88 b *= cos_pr_minus_pi * sin(alpha) * tan(beta);
nuclear@0 89 } else {
nuclear@0 90 b = 0.0;
nuclear@0 91 }
nuclear@0 92
nuclear@0 93 return ldotn * (a + b);
nuclear@0 94 }
nuclear@0 95
nuclear@0 96 /* TODO: need tangent/bitangent
nuclear@0 97 float ward(vec3 view, vec3 norm, vec3 ldir, vec3 hvec, vec3 tang, vec3 bitan, float ax, float ay)
nuclear@0 98 {
nuclear@0 99 float vdotn = dot(view, norm);
nuclear@0 100 float ldotn = dot(light, norm);
nuclear@0 101 }
nuclear@0 102 */