Merge with trunk r39750
[blender.git] / source / blender / render / intern / source / render_texture.c
index 88f1f2f5e71d9cb6d8fa3d32377f3e8b22827a2e..138eca2dd9b6cd66021c09b6044d0d58ecfa4c5f 100644 (file)
@@ -1804,7 +1804,7 @@ static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi,
                        const float adx[3] = {fabsf(dx[0]), fabsf(dx[1]), fabsf(dx[2])};
                        const float ady[3] = {fabsf(dy[0]), fabsf(dy[1]), fabsf(dy[2])};
                        du = MAX3(adx[0], adx[1], adx[2]);
-                       dv = MAX3(ady[1], ady[1], ady[2]);
+                       dv = MAX3(ady[0], ady[1], ady[2]);
                }
        }
 
@@ -1920,11 +1920,13 @@ static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, T
 
        const int fromrgb = ((tex->type == TEX_IMAGE) || ((tex->flag & TEX_COLORBAND)!=0));
        float Hscale = Tnor*mtex->norfac;
+       int dimx=512, dimy=512;
 
        // 2 channels for 2D texture and 3 for 3D textures.
        const int nr_channels = (mtex->texco == TEXCO_UV)? 2 : 3;
        int c, rgbnor, iBumpSpace;
        float dHdx, dHdy;
+       int found_deriv_map = (tex->type==TEX_IMAGE) && (tex->imaflag & TEX_DERIVATIVEMAP);
 
        // disable internal bump eval in sampler, save pointer
        float *nvec = texres->nor;
@@ -1944,8 +1946,31 @@ static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, T
                
                ntap_bump->init_done = 1;
        }
+
+       // resolve image dimensions
+       if(found_deriv_map || (mtex->texflag&MTEX_BUMP_TEXTURESPACE)!=0) {
+               ImBuf* ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser);
+               if (ibuf) {
+                       dimx = ibuf->x;
+                       dimy = ibuf->y;
+               }
+       }
        
-       if(!(mtex->texflag & MTEX_5TAP_BUMP)) {
+       if(found_deriv_map) {
+               float dBdu, dBdv;
+               float s = 1;            // negate this if flipped texture coordinate
+               texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
+               rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, texres);
+               
+               // this variant using a derivative map is described here
+               // http://mmikkelsen3d.blogspot.com/2011/07/derivative-maps.html
+               dBdu = Hscale*dimx*(2*texres->tr-1);
+               dBdv = Hscale*dimy*(2*texres->tg-1);
+
+               dHdx = dBdu*dxt[0] + s * dBdv*dxt[1];
+               dHdy = dBdu*dyt[0] + s * dBdv*dyt[1];
+       }
+       else if(!(mtex->texflag & MTEX_5TAP_BUMP)) {
                // compute height derivatives with respect to output image pixel coordinates x and y
                float STll[3], STlr[3], STul[3];
                float Hll, Hlr, Hul;
@@ -2099,15 +2124,8 @@ static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, T
 
        if( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) {
                if(tex->ima) {
-                       float vec[2];
-                       int dimx=512, dimy=512; 
-                       ImBuf* ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser);
-                       if (ibuf) {
-                               dimx = ibuf->x;
-                               dimy = ibuf->y;
-                       }
-
                        // crazy hack solution that gives results similar to normal mapping - part 2
+                       float vec[2];
                        
                        vec[0] = dimx*dxt[0];
                        vec[1] = dimy*dxt[1];
@@ -2141,7 +2159,7 @@ void do_material_tex(ShadeInput *shi)
        float texvec[3], dxt[3], dyt[3], tempvec[3], norvec[3], warpvec[3]={0.0f, 0.0f, 0.0f}, Tnor=1.0;
        int tex_nr, rgbnor= 0, warpdone=0;
        int use_compat_bump = 0, use_ntap_bump = 0;
-       int found_nmapping = 0;
+       int found_nmapping = 0, found_deriv_map = 0;
        int iFirstTimeNMap=1;
 
        compatible_bump_init(&compat_bump);
@@ -2161,8 +2179,9 @@ void do_material_tex(ShadeInput *shi)
                        tex= mtex->tex;
                        if(tex==0) continue;
 
+                       found_deriv_map = (tex->type==TEX_IMAGE) && (tex->imaflag & TEX_DERIVATIVEMAP);
                        use_compat_bump= (mtex->texflag & MTEX_COMPAT_BUMP);
-                       use_ntap_bump= (mtex->texflag & (MTEX_3TAP_BUMP|MTEX_5TAP_BUMP));
+                       use_ntap_bump= ((mtex->texflag & (MTEX_3TAP_BUMP|MTEX_5TAP_BUMP))!=0 || found_deriv_map!=0) ? 1 : 0;
 
                        /* XXX texture node trees don't work for this yet */
                        if(tex->nodetree && tex->use_nodes) {
@@ -2354,7 +2373,6 @@ void do_material_tex(ShadeInput *shi)
                                                f1= shi->vn[0];
                                                f2= shi->vn[1];
                                                texres.nor[0]= f1*co_nor+f2*si;
-                                               texres.nor[1]= f2*co_nor-f1*si;
                                                f1= shi->vn[1];
                                                f2= shi->vn[2];
                                                texres.nor[1]= f1*co_nor+f2*si;