glsl and render support for derivative maps
authorMorten Mikkelsen <mikkelsen7@gmail.com>
Mon, 22 Aug 2011 19:57:54 +0000 (19:57 +0000)
committerMorten Mikkelsen <mikkelsen7@gmail.com>
Mon, 22 Aug 2011 19:57:54 +0000 (19:57 +0000)
release/scripts/startup/bl_ui/properties_texture.py
source/blender/gpu/intern/gpu_material.c
source/blender/gpu/intern/gpu_shader_material.glsl
source/blender/gpu/intern/gpu_shader_material.glsl.c
source/blender/makesdna/DNA_texture_types.h
source/blender/makesrna/intern/rna_texture.c
source/blender/render/intern/source/render_texture.c

index ead65b92c3fe93f8b35bd7e448da9601c1c5e069..0172fbcbadd678fc5ddc6c0d391ed25384694d5a 100644 (file)
@@ -414,6 +414,10 @@ class TEXTURE_PT_image_sampling(TextureTypePanel, Panel):
             row = col.row()
             row.active = tex.use_normal_map
             row.prop(slot, "normal_map_space", text="")
+            
+            row = col.row()
+            row.active = not tex.use_normal_map
+            row.prop(tex, "use_derivative_map")
 
         col.prop(tex, "use_mipmap")
         row = col.row()
@@ -1025,12 +1029,14 @@ class TEXTURE_PT_influence(TextureSlotPanel, Panel):
 
             # only show bump settings if activated but not for normalmap images
             row = layout.row()
-            row.active = (tex.use_map_normal or tex.use_map_warp) and not (tex.texture.type == 'IMAGE' and tex.texture.use_normal_map)
-
-            row.prop(tex, "bump_method", text="Method")
+            
+            sub = row.row()
+            sub.active = (tex.use_map_normal or tex.use_map_warp) and not (tex.texture.type == 'IMAGE' and (tex.texture.use_normal_map or tex.texture.use_derivative_map))
+            sub.prop(tex, "bump_method", text="Method")
 
+                       # the space setting is supported for: derivmaps + bumpmaps (DEFAULT,BEST_QUALITY), not for normalmaps
             sub = row.row()
-            sub.active = tex.bump_method in {'BUMP_DEFAULT', 'BUMP_BEST_QUALITY'}
+            sub.active = (tex.use_map_normal or tex.use_map_warp) and not (tex.texture.type == 'IMAGE' and tex.texture.use_normal_map) and ((tex.bump_method in {'BUMP_DEFAULT', 'BUMP_BEST_QUALITY'}) or (tex.texture.type == 'IMAGE' and tex.texture.use_derivative_map)) 
             sub.prop(tex, "bump_objectspace", text="Space")
 
 
index 274884000dbbc8314f92db764c4819e2572bcb50..28624e9350c964abc029909b3d7658de3f3a5756 100644 (file)
@@ -906,6 +906,7 @@ static void do_material_tex(GPUShadeInput *shi)
        int init_done = 0, iBumpSpacePrev;
        GPUNodeLink *vNorg, *vNacc, *fPrevMagnitude;
        int iFirstTimeNMap=1;
+       int found_deriv_map = 0;
 
        GPU_link(mat, "set_value", GPU_uniform(&one), &stencil);
 
@@ -1043,6 +1044,8 @@ static void do_material_tex(GPUShadeInput *shi)
 
                        if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && (mtex->mapto & MAP_NORM)) {
                                if(tex->type==TEX_IMAGE) {
+                                       found_deriv_map = tex->imaflag & TEX_DERIVATIVEMAP;
+
                                        if(tex->imaflag & TEX_NORMALMAP) {
                                                /* normalmap image */
                                                GPU_link(mat, "mtex_normal", texco, GPU_image(tex->ima, &tex->iuser), &tnor );
@@ -1082,9 +1085,10 @@ static void do_material_tex(GPUShadeInput *shi)
                                                        GPU_link(mat, "mtex_blend_normal", tnorfac, shi->vn, newnor, &shi->vn);
                                                }
                                                
-                                       } else if( mtex->texflag & (MTEX_3TAP_BUMP|MTEX_5TAP_BUMP)) {
+                                       } else if( (mtex->texflag & (MTEX_3TAP_BUMP|MTEX_5TAP_BUMP)) || found_deriv_map) {
                                                /* ntap bumpmap image */
                                                int iBumpSpace;
+                                               float ima_x, ima_y;
                                                float hScale = 0.1f; // compatibility adjustment factor for all bumpspace types
                                                float hScaleTex = 13.0f; // factor for scaling texspace bumps
                                                
@@ -1142,9 +1146,24 @@ static void do_material_tex(GPUShadeInput *shi)
                                                        
                                                        iBumpSpacePrev = iBumpSpace;
                                                }
+
+                                               // resolve texture resolution
+                                               if( (mtex->texflag & MTEX_BUMP_TEXTURESPACE) || found_deriv_map ) {
+                                                       ImBuf *ibuf= BKE_image_get_ibuf(tex->ima, &tex->iuser);
+                                                       ima_x= 512.0f; ima_y= 512.f;            // prevent calling textureSize, glsl 1.3 only
+                                                       if(ibuf) {
+                                                               ima_x= ibuf->x;
+                                                               ima_y= ibuf->y;
+                                                       }
+                                               }
                                                
                                                
-                                               if( mtex->texflag & MTEX_3TAP_BUMP )
+                                               if(found_deriv_map) {
+                                                       GPU_link( mat, "mtex_bump_deriv", 
+                                                                 texco, GPU_image(tex->ima, &tex->iuser), GPU_uniform(&ima_x), GPU_uniform(&ima_y), tnorfac,
+                                                                 &dBs, &dBt );
+                                               }
+                                               else if( mtex->texflag & MTEX_3TAP_BUMP )
                                                        GPU_link( mat, "mtex_bump_tap3", 
                                                                  texco, GPU_image(tex->ima, &tex->iuser), tnorfac,
                                                                  &dBs, &dBt );
@@ -1155,12 +1174,6 @@ static void do_material_tex(GPUShadeInput *shi)
                                                
                                                
                                                if( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) {
-                                                       float ima_x= 512.0f, ima_y= 512.f;              // prevent calling textureSize, glsl 1.3 only
-                                                       ImBuf *ibuf= BKE_image_get_ibuf(tex->ima, &tex->iuser);
-                                                       if(ibuf) {
-                                                               ima_x= ibuf->x;
-                                                               ima_y= ibuf->y;
-                                                       }
                                                        
                                                        GPU_link( mat, "mtex_bump_apply_texspace",
                                                                  fDet, dBs, dBt, vR1, vR2, 
index feb0a84fa874a551fe45263bacd9be4295b0ce46..0aae6d84a01bffbe06c194c2a8c956dfd26307c5 100644 (file)
@@ -1226,6 +1226,22 @@ void mtex_bump_tap5( vec3 texco, sampler2D ima, float hScale,
        dBt = hScale * (Hu - Hd);
 }
 
+void mtex_bump_deriv( vec3 texco, sampler2D ima, float ima_x, float ima_y, float hScale, 
+                     out float dBs, out float dBt ) 
+{
+       float s = 1;            // negate this if flipped texture coordinate
+       vec2 TexDx = dFdx(texco.xy);
+       vec2 TexDy = dFdy(texco.xy);
+       
+       // this variant using a derivative map is described here
+       // http://mmikkelsen3d.blogspot.com/2011/07/derivative-maps.html
+       vec2 dim = vec2(ima_x, ima_y);
+       vec2 dBduv = hScale*dim*(2*texture2D(ima, texco.xy).xy-1);
+       
+       dBs = dBduv.x*TexDx.x + s*dBduv.y*TexDx.y;
+       dBt = dBduv.x*TexDy.x + s*dBduv.y*TexDy.y;
+}
+
 void mtex_bump_apply( float fDet, float dBs, float dBt, vec3 vR1, vec3 vR2, vec3 vNacc_in,
                                          out vec3 vNacc_out, out vec3 perturbed_norm ) 
 {
index b60f7f1555ee283b8f27489639cd1fc0da377db8..8b23e2b205dbc75bdcadeaf111cc7db2173aba60 100644 (file)
@@ -1,6 +1,6 @@
 /* DataToC output of file <gpu_shader_material_glsl> */
 
-int datatoc_gpu_shader_material_glsl_size= 39207;
+int datatoc_gpu_shader_material_glsl_size= 39783;
 char datatoc_gpu_shader_material_glsl[]= {
  10,102,108,111, 97,116, 32,
 101,120,112, 95, 98,108,101,110,100,101,114, 40,102,108,111, 97,116, 32,102, 41, 10,123, 10,  9,114,101,116,117,114,110, 32,112,
@@ -838,6 +838,24 @@ char datatoc_gpu_shader_material_glsl[]= {
 119, 40, 32,116,101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 83, 84,117, 41, 44, 32, 72,117, 32, 41, 59, 10,  9, 10,
   9,100, 66,115, 32, 61, 32,104, 83, 99, 97,108,101, 32, 42, 32, 40, 72,114, 32, 45, 32, 72,108, 41, 59, 10,  9,100, 66,116, 32,
  61, 32,104, 83, 99, 97,108,101, 32, 42, 32, 40, 72,117, 32, 45, 32, 72,100, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,
+101,120, 95, 98,117,109,112, 95,100,101,114,105,118, 40, 32,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,115, 97,109,112,108,
+101,114, 50, 68, 32,105,109, 97, 44, 32,102,108,111, 97,116, 32,105,109, 97, 95,120, 44, 32,102,108,111, 97,116, 32,105,109, 97,
+ 95,121, 44, 32,102,108,111, 97,116, 32,104, 83, 99, 97,108,101, 44, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32,111,117,116, 32,102,108,111, 97,116, 32,100, 66,115, 44, 32,111,117,116, 32,102,108,111, 97,116,
+ 32,100, 66,116, 32, 41, 32, 10,123, 10,  9,102,108,111, 97,116, 32,115, 32, 61, 32, 49, 59,  9,  9, 47, 47, 32,110,101,103, 97,
+116,101, 32,116,104,105,115, 32,105,102, 32,102,108,105,112,112,101,100, 32,116,101,120,116,117,114,101, 32, 99,111,111,114,100,
+105,110, 97,116,101, 10,  9,118,101, 99, 50, 32, 84,101,120, 68,120, 32, 61, 32,100, 70,100,120, 40,116,101,120, 99,111, 46,120,
+121, 41, 59, 10,  9,118,101, 99, 50, 32, 84,101,120, 68,121, 32, 61, 32,100, 70,100,121, 40,116,101,120, 99,111, 46,120,121, 41,
+ 59, 10,  9, 10,  9, 47, 47, 32,116,104,105,115, 32,118, 97,114,105, 97,110,116, 32,117,115,105,110,103, 32, 97, 32,100,101,114,
+105,118, 97,116,105,118,101, 32,109, 97,112, 32,105,115, 32,100,101,115, 99,114,105, 98,101,100, 32,104,101,114,101, 10,  9, 47,
+ 47, 32,104,116,116,112, 58, 47, 47,109,109,105,107,107,101,108,115,101,110, 51,100, 46, 98,108,111,103,115,112,111,116, 46, 99,
+111,109, 47, 50, 48, 49, 49, 47, 48, 55, 47,100,101,114,105,118, 97,116,105,118,101, 45,109, 97,112,115, 46,104,116,109,108, 10,
+  9,118,101, 99, 50, 32,100,105,109, 32, 61, 32,118,101, 99, 50, 40,105,109, 97, 95,120, 44, 32,105,109, 97, 95,121, 41, 59, 10,
+  9,118,101, 99, 50, 32,100, 66,100,117,118, 32, 61, 32,104, 83, 99, 97,108,101, 42,100,105,109, 42, 40, 50, 42,116,101,120,116,
+117,114,101, 50, 68, 40,105,109, 97, 44, 32,116,101,120, 99,111, 46,120,121, 41, 46,120,121, 45, 49, 41, 59, 10,  9, 10,  9,100,
+ 66,115, 32, 61, 32,100, 66,100,117,118, 46,120, 42, 84,101,120, 68,120, 46,120, 32, 43, 32,115, 42,100, 66,100,117,118, 46,121,
+ 42, 84,101,120, 68,120, 46,121, 59, 10,  9,100, 66,116, 32, 61, 32,100, 66,100,117,118, 46,120, 42, 84,101,120, 68,121, 46,120,
+ 32, 43, 32,115, 42,100, 66,100,117,118, 46,121, 42, 84,101,120, 68,121, 46,121, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,
 101,120, 95, 98,117,109,112, 95, 97,112,112,108,121, 40, 32,102,108,111, 97,116, 32,102, 68,101,116, 44, 32,102,108,111, 97,116,
  32,100, 66,115, 44, 32,102,108,111, 97,116, 32,100, 66,116, 44, 32,118,101, 99, 51, 32,118, 82, 49, 44, 32,118,101, 99, 51, 32,
 118, 82, 50, 44, 32,118,101, 99, 51, 32,118, 78, 97, 99, 99, 95,105,110, 44, 10,  9,  9,  9,  9,  9, 32, 32,111,117,116, 32,118,
index e81a9979c12864de15b881cdc4021199e86beccf..6e850a07d94a2941cd5a6012253229cb3301a21a 100644 (file)
@@ -342,6 +342,7 @@ typedef struct TexMapping {
 #define TEX_NORMALMAP  2048
 #define TEX_GAUSS_MIP  4096
 #define TEX_FILTER_MIN 8192
+#define TEX_DERIVATIVEMAP      16384
 
 /* texfilter */
 // TXF_BOX -> blender's old texture filtering method
index 9e3a31ddb2e15a992ece8ea7f100ce9194bcf7bc..f459563f49eff6b34a5d66bcc6770d324c9622cd 100644 (file)
@@ -1147,6 +1147,12 @@ static void rna_def_texture_image(BlenderRNA *brna)
        RNA_def_property_boolean_sdna(prop, NULL, "imaflag", TEX_NORMALMAP);
        RNA_def_property_ui_text(prop, "Normal Map", "Uses image RGB values for normal mapping");
        RNA_def_property_update(prop, 0, "rna_Texture_update");
+
+       /* Derivative Map */
+       prop= RNA_def_property(srna, "use_derivative_map", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "imaflag", TEX_DERIVATIVEMAP);
+       RNA_def_property_ui_text(prop, "Derivative Map", "Uses red and green as derivative values");
+       RNA_def_property_update(prop, 0, "rna_Texture_update");
 }
 
 static void rna_def_texture_plugin(BlenderRNA *brna)
index ef1b1cd159cce8896af552cd86a750d88b17d8bf..a4c1778c62417b220e2b3e3b56ebe49d26e19ce1 100644 (file)
@@ -1905,11 +1905,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;
@@ -1929,8 +1931,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;
@@ -2084,15 +2109,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];
@@ -2126,7 +2144,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);
@@ -2146,8 +2164,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) {