Revision: 15716
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15716
Author:   unclezeiv
Date:     2008-07-23 19:23:56 +0200 (Wed, 23 Jul 2008)

Log Message:
-----------
- readability enhancements for diffuse and specular shaders (mostly used macros 
where possible, leading to clearer and more compact code)
- a couple of slight optimizations (pre-computing parameters being used squared 
in many places, and anticipating a early out)
- a potential fix (parameter g in Blinn specularity could stay uncorrectly at 
0.0 in some extreme corner cases)

Modified Paths:
--------------
    
branches/soc-2008-unclezeiv/source/blender/render/intern/source/shadeoutput.c

Modified: 
branches/soc-2008-unclezeiv/source/blender/render/intern/source/shadeoutput.c
===================================================================
--- 
branches/soc-2008-unclezeiv/source/blender/render/intern/source/shadeoutput.c   
    2008-07-23 16:59:54 UTC (rev 15715)
+++ 
branches/soc-2008-unclezeiv/source/blender/render/intern/source/shadeoutput.c   
    2008-07-23 17:23:56 UTC (rev 15716)
@@ -404,15 +404,13 @@
        
        if(fac==0.0f) return 1.0f;
        
-       t1= (view[0]*vn[0] + view[1]*vn[1] + view[2]*vn[2]);
-       if(t1>0.0f)  t2= 1.0f+t1;
+       t1= INPR(view, vn);
+       if(t1>0.0f) t2= 1.0f+t1;
        else t2= 1.0f-t1;
        
        t2= grad + (1.0f-grad)*pow(t2, fac);
        
-       if(t2<0.0f) return 0.0f;
-       else if(t2>1.0f) return 1.0f;
-       return t2;
+       return CLAMPIS(t2, 0.0f, 1.0f);
 }
 
 static double saacos_d(double fac)
@@ -549,12 +547,10 @@
        float h[3];
        float rslt;
        
-       h[0] = l[0] + v[0];
-       h[1] = l[1] + v[1];
-       h[2] = l[2] + v[2];
+       VECADD(h, v, l);
        Normalize(h);
        
-       rslt = h[0]*n[0] + h[1]*n[1] + h[2]*n[2];
+       rslt = INPR(h, n);
        if(tangent) rslt= sasqrt(1.0f - rslt*rslt);
                
        if( rslt > 0.0f ) rslt= spec(rslt, hard);
@@ -567,25 +563,20 @@
 /* reduced cook torrance spec (for off-specular peak) */
 static float CookTorr_Spec(float *n, float *l, float *v, int hard, int tangent)
 {
-       float i, nh, nv, h[3];
+       float nh, nv, h[3];
 
-       h[0]= v[0]+l[0];
-       h[1]= v[1]+l[1];
-       h[2]= v[2]+l[2];
+       VECADD(h, v, l);
        Normalize(h);
 
-       nh= n[0]*h[0]+n[1]*h[1]+n[2]*h[2];
+       nh= INPR(n, h);
        if(tangent) nh= sasqrt(1.0f - nh*nh);
        else if(nh<0.0f) return 0.0f;
        
-       nv= n[0]*v[0]+n[1]*v[1]+n[2]*v[2];
+       nv= INPR(n, v);
        if(tangent) nv= sasqrt(1.0f - nv*nv);
        else if(nv<0.0f) nv= 0.0f;
 
-       i= spec(nh, hard);
-
-       i= i/(0.1+nv);
-       return i;
+       return spec(nh, hard)/(0.1+nv);
 }
 
 /* Blinn spec */
@@ -593,6 +584,7 @@
 {
        float i, nh, nv, nl, vh, h[3];
        float a, b, c, g=0.0f, p, f, ang;
+       float num, den, pm, pp;
 
        if(refrac < 1.0f) return 0.0f;
        if(spec_power == 0.0f) return 0.0f;
@@ -602,38 +594,44 @@
                spec_power= sqrt(1.0f/spec_power);
        else spec_power= 10.0f/spec_power;
        
-       h[0]= v[0]+l[0];
-       h[1]= v[1]+l[1];
-       h[2]= v[2]+l[2];
+       VECADD(h, v, l);
        Normalize(h);
 
-       nh= n[0]*h[0]+n[1]*h[1]+n[2]*h[2]; /* Dot product between surface 
normal and half-way vector */
+       /* Dot product between surface normal and half-way vector */
+       nh= INPR(n, h);
        if(tangent) nh= sasqrt(1.0f - nh*nh);
        else if(nh<0.0f) return 0.0f;
 
-       nv= n[0]*v[0]+n[1]*v[1]+n[2]*v[2]; /* Dot product between surface 
normal and view vector */
+       /* Dot product between surface normal and view vector */
+       nv= INPR(n, v);
        if(tangent) nv= sasqrt(1.0f - nv*nv);
        if(nv<=0.01f) nv= 0.01f;                                /* hrms... */
 
-       nl= n[0]*l[0]+n[1]*l[1]+n[2]*l[2]; /* Dot product between surface 
normal and light vector */
+       /* Dot product between surface normal and light vector */
+       nl= INPR(n, l);
        if(tangent) nl= sasqrt(1.0f - nl*nl);
        if(nl<=0.01f) {
                return 0.0f;
        }
 
-       vh= v[0]*h[0]+v[1]*h[1]+v[2]*h[2]; /* Dot product between view vector 
and half-way vector */
+       /* Dot product between view vector and half-way vector */
+       vh= INPR(v, h); 
        if(vh<=0.0f) vh= 0.01f;
 
        a = 1.0f;
        b = (2.0f*nh*nv)/vh;
        c = (2.0f*nh*nl)/vh;
+       
+       g= MIN3(a, b, c);
 
-       if( a < b && a < c ) g = a;
-       else if( b < a && b < c ) g = b;
-       else if( c < a && c < b ) g = c;
-
        p = sqrt( (double)((refrac * refrac)+(vh*vh)-1.0f) );
-       f = 
(((p-vh)*(p-vh))/((p+vh)*(p+vh)))*(1+((((vh*(p+vh))-1.0f)*((vh*(p+vh))-1.0f))/(((vh*(p-vh))+1.0f)*((vh*(p-vh))+1.0f))));
+       pm= p-vh;
+       pp= p+vh;
+       num= (vh*pp)-1.0f;
+       num*= num;
+       den= (vh*pm)+1.0f;
+       den*= den;
+       f = (pm*pm/(pp*pp)) * (1.0f + num/den);
        ang = saacos(nh);
 
        i= f * g * exp((double)(-(ang*ang) / (2.0f*spec_power*spec_power)));
@@ -649,12 +647,10 @@
        float ang;
        float rslt;
        
-       h[0] = l[0] + v[0];
-       h[1] = l[1] + v[1];
-       h[2] = l[2] + v[2];
+       VECADD(h, v, l);
        Normalize(h);
        
-       rslt = h[0]*n[0] + h[1]*n[1] + h[2]*n[2];
+       rslt = INPR(h, n);
        if(tangent) rslt = sasqrt(1.0f - rslt*rslt);
        
        ang = saacos( rslt ); 
@@ -669,31 +665,32 @@
 /* Ward isotropic gaussian spec */
 static float WardIso_Spec( float *n, float *l, float *v, float rms, int 
tangent)
 {
-       float i, nh, nv, nl, h[3], angle, alpha;
+       float i, nh, nv, nl, h[3], angle, alpha_sq;
 
-
        /* half-way vector */
-       h[0] = l[0] + v[0];
-       h[1] = l[1] + v[1];
-       h[2] = l[2] + v[2];
+       VECADD(h, l, v);
        Normalize(h);
 
-       nh = n[0]*h[0]+n[1]*h[1]+n[2]*h[2]; /* Dot product between surface 
normal and half-way vector */
+       /* Dot product between surface normal and half-way vector */
+       nh = INPR(n, h);
        if(tangent) nh = sasqrt(1.0f - nh*nh);
        if(nh<=0.0f) nh = 0.001f;
        
-       nv = n[0]*v[0]+n[1]*v[1]+n[2]*v[2]; /* Dot product between surface 
normal and view vector */
+       /* Dot product between surface normal and view vector */
+       nv = INPR(n, v);
        if(tangent) nv = sasqrt(1.0f - nv*nv);
        if(nv<=0.0f) nv = 0.001f;
 
-       nl = n[0]*l[0]+n[1]*l[1]+n[2]*l[2]; /* Dot product between surface 
normal and light vector */
+       /* Dot product between surface normal and light vector */
+       nl = INPR(n, l);
        if(tangent) nl = sasqrt(1.0f - nl*nl);
        if(nl<=0.0f) nl = 0.001f;
 
        angle = tan(saacos(nh));
-       alpha = MAX2(rms, 0.001f);
+       alpha_sq = MAX2(rms, 0.001f);
+       alpha_sq*= alpha_sq;
 
-       i= nl * (1.0f/(4.0f*M_PI*alpha*alpha)) * (exp( 
-(angle*angle)/(alpha*alpha))/(sqrt(nv*nl)));
+       i= nl * (1.0f/(4.0f*M_PI*alpha_sq)) * (exp( 
-(angle*angle)/alpha_sq)/(sqrt(nv*nl)));
 
        return i;
 }
@@ -703,7 +700,7 @@
 {
        float rslt, ang;
 
-       rslt = n[0]*l[0] + n[1]*l[1] + n[2]*l[2];
+       rslt = INPR(n, l);
 
        ang = saacos( (double)(rslt) );
 
@@ -718,45 +715,46 @@
 
 /* 'nl' is either dot product, or return value of area light */
 /* in latter case, only last multiplication uses 'nl' */
-static float OrenNayar_Diff(float nl, float *n, float *l, float *v, float 
rough )
+static float OrenNayar_Diff(float nl, float *n, float *l, float *v, float 
rough_sq )
 {
        float i, nh, nv, vh, realnl, h[3];
        float a, b, t, A, B;
        float Lit_A, View_A, Lit_B[3], View_B[3];
        
+       if(nl<0.0f) return 0.0f; /* value from area light */
+       
        h[0]= v[0]+l[0];
        h[1]= v[1]+l[1];
        h[2]= v[2]+l[2];
        Normalize(h);
        
-       nh= n[0]*h[0]+n[1]*h[1]+n[2]*h[2]; /* Dot product between surface 
normal and half-way vector */
-       if(nh<0.0f) nh = 0.0f;
+       /* Dot product between surface normal and half-way vector */
+       nh= INPR(n, h);
+       nh= MAX2(nh, 0.0f);
        
-       nv= n[0]*v[0]+n[1]*v[1]+n[2]*v[2]; /* Dot product between surface 
normal and view vector */
-       if(nv<=0.0f) nv= 0.0f;
+       /* Dot product between surface normal and view vector */
+       nv= INPR(n, v);
+       nv= MAX2(nv, 0.0f);
        
-       realnl= n[0]*l[0]+n[1]*l[1]+n[2]*l[2]; /* Dot product between surface 
normal and light vector */
+       /* Dot product between surface normal and light vector */
+       realnl= INPR(n, l);
        if(realnl<=0.0f) return 0.0f;
-       if(nl<0.0f) return 0.0f;                /* value from area light */
        
-       vh= v[0]*h[0]+v[1]*h[1]+v[2]*h[2]; /* Dot product between view vector 
and halfway vector */
-       if(vh<=0.0f) vh= 0.0f;
+       /* Dot product between view vector and halfway vector */
+       vh= INPR(v, h);
+       vh= MAX2(vh, 0.0f);
        
        Lit_A = saacos(realnl);
        View_A = saacos( nv );
        
-       Lit_B[0] = l[0] - (realnl * n[0]);
-       Lit_B[1] = l[1] - (realnl * n[1]);
-       Lit_B[2] = l[2] - (realnl * n[2]);
-       Normalize( Lit_B );
+       VECADDFAC(Lit_B, l, n, -realnl);
+       Normalize(Lit_B);
        
-       View_B[0] = v[0] - (nv * n[0]);
-       View_B[1] = v[1] - (nv * n[1]);
-       View_B[2] = v[2] - (nv * n[2]);
-       Normalize( View_B );
+       VECADDFAC(View_B, v, n, -nv);
+       Normalize(View_B);
        
-       t = Lit_B[0]*View_B[0] + Lit_B[1]*View_B[1] + Lit_B[2]*View_B[2];
-       if( t < 0 ) t = 0;
+       t= INPR(Lit_B, View_B);
+       t= MAX2(t, 0.0f);
        
        if( Lit_A > View_A ) {
                a = Lit_A;
@@ -766,12 +764,12 @@
                a = View_A;
                b = Lit_A;
        }
+       b*= 0.95f;      /* prevent tangents from shooting t(rough * rough)o 
inf, 'nl' can be not a dot product here. */
+                               /* overflow only happens with extreme size area 
light, and higher roughness */
        
-       A = 1.0f - (0.5f * ((rough * rough) / ((rough * rough) + 0.33f)));
-       B = 0.45f * ((rough * rough) / ((rough * rough) + 0.09f));
+       A = 1.0f - 0.5f * rough_sq / (rough_sq + 0.33f);
+       B = 0.45f * rough_sq / (rough_sq + 0.09f);
        
-       b*= 0.95f;      /* prevent tangens from shooting to inf, 'nl' can be 
not a dot product here. */
-                               /* overflow only happens with extreme size area 
light, and higher roughness */
        i = nl * ( A + ( B * t * sin(a) * tan(b) ) );
        
        return i;
@@ -780,7 +778,6 @@
 /* Minnaert diffuse */
 static float Minnaert_Diff(float nl, float *n, float *v, float darkness)
 {
-
        float i, nv;
 
        /* nl = dot product between surface normal and light vector */
@@ -788,7 +785,7 @@
                return 0.0f;
 
        /* nv = dot product between surface normal and view vector */
-       nv = n[0]*v[0]+n[1]*v[1]+n[2]*v[2];
+       nv = INPR(n, v);
        if (nv < 0.0f)
                nv = 0.0f;
 
@@ -1302,7 +1299,7 @@
                        inp= area_lamp_energy_multisample(lar, shi->co, vn);
                
                /* diffuse shaders (oren nayer gets inp from area light) */
-               if(ma->diff_shader==MA_DIFF_ORENNAYAR) is= OrenNayar_Diff(inp, 
vn, lv, view, ma->roughness);
+               if(ma->diff_shader==MA_DIFF_ORENNAYAR) is= OrenNayar_Diff(inp, 
vn, lv, view, ma->roughness * ma->roughness);
                else if(ma->diff_shader==MA_DIFF_TOON) is= Toon_Diff(vn, lv, 
view, ma->param[0], ma->param[1]);
                else if(ma->diff_shader==MA_DIFF_MINNAERT) is= 
Minnaert_Diff(inp, vn, view, ma->darkness);
                else if(ma->diff_shader==MA_DIFF_FRESNEL) is= Fresnel_Diff(vn, 
lv, view, ma->param[0], ma->param[1]);
@@ -1924,7 +1921,7 @@
 
 #ifdef LC_LATER /* we start by supporting only lambert */
                /* diffuse shaders (oren nayer gets inp from area light) */
-               if(ma->diff_shader==MA_DIFF_ORENNAYAR) is= OrenNayar_Diff(inp, 
vn, lv, view, ma->roughness);
+               if(ma->diff_shader==MA_DIFF_ORENNAYAR) is= OrenNayar_Diff(inp, 
vn, lv, view, ma->roughness * ma->roughness);
                else if(ma->diff_shader==MA_DIFF_TOON) is= Toon_Diff(vn, lv, 
view, ma->param[0], ma->param[1]);
                else if(ma->diff_shader==MA_DIFF_MINNAERT) is= 
Minnaert_Diff(inp, vn, view, ma->darkness);
                else if(ma->diff_shader==MA_DIFF_FRESNEL) is= Fresnel_Diff(vn, 
lv, view, ma->param[0], ma->param[1]);


_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to