[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [34155] trunk/blender: Improved bump mapping patch by M.G.

Brecht Van Lommel brechtvanlommel at pandora.be
Fri Jan 7 15:42:02 CET 2011


Revision: 34155
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=34155
Author:   blendix
Date:     2011-01-07 14:42:01 +0000 (Fri, 07 Jan 2011)
Log Message:
-----------
Improved bump mapping patch by M.G. Kishalmi (lmg) and M.S. Mikkelsen (sparky).
Many thanks to them!

For comparison, see here:
http://kishalmi.servus.at/3D/bumpcode/

Based on algorithm in: Mikkelsen M. S.: Simulation of Wrinkled Surfaces Revisited.
http://jbit.net/~sparky/sfgrad_bump/mm_sfgrad_bump.pdf

This fixes bugs:
#24591: Artefacts/strange normal mapping when anti-aliasing is on
#24735: Error at the Normal function.
#24962: Normals are not calculated correctly if anti-aliasing is off
#25103: Weird artefacts in Normal

This will break render compatibility a bit, but fixing this bugs would have also
done that, so in this case it should be acceptable.

Patch committed with these modifications:
* Bump method Old/3-Tap/5-Tap option in UI, 3-Tap is default
* Only compute normal perturbation vectors when needed
* Fix some middle of block variable definitions for MSVC

Modified Paths:
--------------
    trunk/blender/release/scripts/ui/properties_texture.py
    trunk/blender/source/blender/blenkernel/intern/material.c
    trunk/blender/source/blender/makesdna/DNA_texture_types.h
    trunk/blender/source/blender/makesrna/intern/rna_material.c
    trunk/blender/source/blender/render/intern/source/texture.c

Modified: trunk/blender/release/scripts/ui/properties_texture.py
===================================================================
--- trunk/blender/release/scripts/ui/properties_texture.py	2011-01-07 11:48:35 UTC (rev 34154)
+++ trunk/blender/release/scripts/ui/properties_texture.py	2011-01-07 14:42:01 UTC (rev 34155)
@@ -995,8 +995,9 @@
         col.prop(tex, "color", text="")
 
         if isinstance(idblock, bpy.types.Material):
-            # XXX, dont remove since old files have this users need to be able to disable!
-            col.prop(tex, "use_old_bump", text="Old Bump Mapping")
+            sub = col.row()
+            sub.prop(tex, "bump_method", text="Bump Method")
+            sub.active = tex.use_map_normal
 
         col = split.column()
         col.prop(tex, "invert", text="Negative")

Modified: trunk/blender/source/blender/blenkernel/intern/material.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/material.c	2011-01-07 11:48:35 UTC (rev 34154)
+++ trunk/blender/source/blender/blenkernel/intern/material.c	2011-01-07 14:42:01 UTC (rev 34155)
@@ -816,10 +816,10 @@
 			
 			ma->texco |= mtex->texco;
 			ma->mapto |= mtex->mapto;
-			if(r_mode & R_OSA) {
-				if ELEM3(mtex->tex->type, TEX_IMAGE, TEX_PLUGIN, TEX_ENVMAP) ma->texco |= TEXCO_OSA;
-				else if(mtex->texflag & MTEX_NEW_BUMP) ma->texco |= TEXCO_OSA; // NEWBUMP: need texture derivatives for procedurals as well
-			}
+
+			/* always get derivatives for these textures */
+			if ELEM3(mtex->tex->type, TEX_IMAGE, TEX_PLUGIN, TEX_ENVMAP) ma->texco |= TEXCO_OSA;
+			else if(mtex->texflag & MTEX_NEW_BUMP) ma->texco |= TEXCO_OSA;
 			
 			if(ma->texco & (TEXCO_ORCO|TEXCO_REFL|TEXCO_NORM|TEXCO_STRAND|TEXCO_STRESS)) needuv= 1;
 			else if(ma->texco & (TEXCO_GLOB|TEXCO_UV|TEXCO_OBJECT|TEXCO_SPEED)) needuv= 1;

Modified: trunk/blender/source/blender/makesdna/DNA_texture_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_texture_types.h	2011-01-07 11:48:35 UTC (rev 34154)
+++ trunk/blender/source/blender/makesdna/DNA_texture_types.h	2011-01-07 14:42:01 UTC (rev 34155)
@@ -455,6 +455,7 @@
 #define MTEX_DUPLI_MAPTO	32
 #define MTEX_OB_DUPLI_ORIG	64
 #define MTEX_NEW_BUMP		128
+#define MTEX_5TAP_BUMP		256
 
 /* blendtype */
 #define MTEX_BLEND		0

Modified: trunk/blender/source/blender/makesrna/intern/rna_material.c
===================================================================
--- trunk/blender/source/blender/makesrna/intern/rna_material.c	2011-01-07 11:48:35 UTC (rev 34154)
+++ trunk/blender/source/blender/makesrna/intern/rna_material.c	2011-01-07 14:42:01 UTC (rev 34155)
@@ -367,6 +367,12 @@
 		{MTEX_NSPACE_TANGENT, "TANGENT", 0, "Tangent", ""},
 		{0, NULL, 0, NULL, NULL}};
 
+	static EnumPropertyItem prop_bump_method_items[] = {
+		{0, "BUMP_OLD", 0, "Old Bump", ""},
+		{MTEX_NEW_BUMP, "BUMP_3_TAP", 0, "3-Tap", ""},
+		{MTEX_NEW_BUMP|MTEX_5TAP_BUMP, "BUMP_5_TAP", 0, "5-Tap", ""},
+		{0, NULL, 0, NULL, NULL}};
+
 	srna= RNA_def_struct(brna, "MaterialTextureSlot", "TextureSlot");
 	RNA_def_struct_sdna(srna, "MTex");
 	RNA_def_struct_ui_text(srna, "Material Texture Slot", "Texture slot for textures in a Material datablock");
@@ -668,9 +674,10 @@
 	RNA_def_property_ui_text(prop, "Enabled", "Enable this material texture slot");
 	RNA_def_property_update(prop, 0, "rna_Material_update");
 
-	prop= RNA_def_property(srna, "use_old_bump", PROP_BOOLEAN, PROP_NONE);
-	RNA_def_property_boolean_negative_sdna(prop, NULL, "texflag", MTEX_NEW_BUMP);
-	RNA_def_property_ui_text(prop, "Old Bump", "Use old bump mapping (backwards compatibility option)");
+	prop= RNA_def_property(srna, "bump_method", PROP_ENUM, PROP_NONE);
+	RNA_def_property_enum_bitflag_sdna(prop, NULL, "texflag");
+	RNA_def_property_enum_items(prop, prop_bump_method_items);
+	RNA_def_property_ui_text(prop, "Bump Method", "Method to use for bump mapping");
 	RNA_def_property_update(prop, 0, "rna_Material_update");
 }
 

Modified: trunk/blender/source/blender/render/intern/source/texture.c
===================================================================
--- trunk/blender/source/blender/render/intern/source/texture.c	2011-01-07 11:48:35 UTC (rev 34154)
+++ trunk/blender/source/blender/render/intern/source/texture.c	2011-01-07 14:42:01 UTC (rev 34155)
@@ -1677,9 +1677,12 @@
 	float fact, facm, factt, facmm, stencilTin=1.0;
 	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;
-	float nu[3] = {0,0,0}, nv[3] = {0,0,0}, nn[3] = {0,0,0}, dudnu = 1.f, dudnv = 0.f, dvdnu = 0.f, dvdnv = 1.f; // bump mapping
 	int nunvdone= 0, newbump;
-
+	// bumpmapping
+	float vNacc[3]; // original surface normal minus the surface gradient of every bump map which is encountered
+	float vR1[3], vR2[3]; // cross products (sigma_y, original_normal), (original_normal, sigma_x)
+	float sgn_det=0.0f; // sign of the determinant of the matrix {sigma_x, sigma_y, original_normal}
+	
 	if (R.r.scemode & R_NO_TEX) return;
 	/* here: test flag if there's a tex (todo) */
 
@@ -1705,7 +1708,9 @@
 					dyt[0]= dyt[1]= dyt[2]= 0.0f;
 				}
 				else {
-					co= shi->lo; dx= shi->dxlo; dy= shi->dylo;
+					co= shi->lo;
+					dx= shi->dxlo;
+					dy= shi->dylo;
 				}
 			}
 			else if(mtex->texco==TEXCO_STICKY) {
@@ -1768,59 +1773,8 @@
 
 					co= suv->uv;
 					dx= suv->dxuv;
-					dy= suv->dyuv; 
+					dy= suv->dyuv;
 
-					// uvmapping only, calculation of normal tangent u/v partial derivatives
-					// (should not be here, dudnu, dudnv, dvdnu & dvdnv should probably be part of ShadeInputUV struct,
-					//  nu/nv in ShadeInput and this calculation should then move to shadeinput.c, shade_input_set_shade_texco() func.)
-					// NOTE: test for shi->obr->ob here, since vlr/obr/obi can be 'fake' when called from fastshade(), another reason to move it..
-					// NOTE: shi->v1 is NULL when called from displace_render_vert, assigning verts in this case is not trivial because the shi quad face side is not know.
-					if ((mtex->texflag & MTEX_NEW_BUMP) && shi->obr && shi->obr->ob && shi->v1) {
-						if(mtex->mapto & (MAP_NORM|MAP_WARP) && !((tex->type==TEX_IMAGE) && (tex->imaflag & TEX_NORMALMAP))) {
-							MTFace* tf = RE_vlakren_get_tface(shi->obr, shi->vlr, i, NULL, 0);
-							int j1 = shi->i1, j2 = shi->i2, j3 = shi->i3;
-
-							vlr_set_uv_indices(shi->vlr, &j1, &j2, &j3);
-
-							// compute ortho basis around normal
-							if(!nunvdone) {
-								// render normal is negated
-								nn[0] = -shi->vn[0];
-								nn[1] = -shi->vn[1];
-								nn[2] = -shi->vn[2];
-								ortho_basis_v3v3_v3( nu, nv,nn);
-								nunvdone= 1;
-							}
-
-							if (tf) {
-								float *uv1 = tf->uv[j1], *uv2 = tf->uv[j2], *uv3 = tf->uv[j3];
-								const float an[3] = {fabsf(nn[0]), fabsf(nn[1]), fabsf(nn[2])};
-								const int a1 = (an[0] > an[1] && an[0] > an[2]) ? 1 : 0;
-								const int a2 = (an[2] > an[0] && an[2] > an[1]) ? 1 : 2;
-								const float dp1_a1 = shi->v1->co[a1] - shi->v3->co[a1];
-								const float dp1_a2 = shi->v1->co[a2] - shi->v3->co[a2];
-								const float dp2_a1 = shi->v2->co[a1] - shi->v3->co[a1];
-								const float dp2_a2 = shi->v2->co[a2] - shi->v3->co[a2];
-								const float du1 = uv1[0] - uv3[0], du2 = uv2[0] - uv3[0];
-								const float dv1 = uv1[1] - uv3[1], dv2 = uv2[1] - uv3[1];
-								const float dpdu_a1 = dv2*dp1_a1 - dv1*dp2_a1;
-								const float dpdu_a2 = dv2*dp1_a2 - dv1*dp2_a2;
-								const float dpdv_a1 = du1*dp2_a1 - du2*dp1_a1;
-								const float dpdv_a2 = du1*dp2_a2 - du2*dp1_a2;
-								float d = dpdu_a1*dpdv_a2 - dpdv_a1*dpdu_a2;
-								float uvd = du1*dv2 - dv1*du2;
-
-								if (uvd == 0.f) uvd = 1e-5f;
-								if (d == 0.f) d = 1e-5f;
-								d = uvd / d;
-
-								dudnu = (dpdv_a2*nu[a1] - dpdv_a1*nu[a2])*d;
-								dvdnu = (dpdu_a1*nu[a2] - dpdu_a2*nu[a1])*d;
-								dudnv = (dpdv_a2*nv[a1] - dpdv_a1*nv[a2])*d;
-								dvdnv = (dpdu_a1*nv[a2] - dpdu_a2*nv[a1])*d;
-							}
-						}
-					}
 				}
 			}
 			else if(mtex->texco==TEXCO_WINDOW) {
@@ -1854,142 +1808,145 @@
 			else texres.nor= NULL;
 			
 			if(warpdone) {
-				VECADD(tempvec, co, warpvec);
+				VECADD(tempvec, co, warpvec)
 				co= tempvec;
 			}
 
 			/* XXX texture node trees don't work for this yet */
 			if(newbump) {
-				// compute ortho basis around normal
-				if(!nunvdone) {
-					// render normal is negated
-					nn[0] = -shi->vn[0];
-					nn[1] = -shi->vn[1];
-					nn[2] = -shi->vn[2];
-					ortho_basis_v3v3_v3( nu, nv,nn);
-					nunvdone= 1;
-				}
 
 				if(texres.nor && !((tex->type==TEX_IMAGE) && (tex->imaflag & TEX_NORMALMAP))) {
+					
 					TexResult ttexr = {0, 0, 0, 0, 0, texres.talpha, NULL};	// temp TexResult
-					float tco[3], texv[3], cd, ud, vd, du, dv, idu, idv;
+					float texv[3];
+					
 					const int fromrgb = ((tex->type == TEX_IMAGE) || ((tex->flag & TEX_COLORBAND)!=0));
-					const float bf = 0.04f*Tnor*stencilTin*mtex->norfac;
-					// disable internal bump eval
-					float* nvec = texres.nor;
+					const float Hscale = 0.016f * Tnor*stencilTin*mtex->norfac; // factor 0.016 proved to look like the previous bump code
+					
+					// 2 channels for 2D texture and 3 for 3D textures.
+					const int nr_channels = (mtex->texco == TEXCO_UV)? 2 : 3;
+					int c;
+					float dHdx, dHdy;
+
+					// disable internal bump eval in sampler, save pointer
+					float *nvec = texres.nor;
 					texres.nor = NULL;
-					// du & dv estimates, constant value defaults
-					du = dv = 0.01f;
 
-					// two methods, either constant based on main image resolution,
-					// (which also works without osa, though of course not always good (or even very bad) results),
-					// or based on tex derivative max values (osa only). Not sure which is best...
+					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;
 
-					if (!shi->osatex && (tex->type == TEX_IMAGE) && tex->ima) {
-						// in case we have no proper derivatives, fall back to
-						// computing du/dv it based on image size
-						ImBuf* ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser);
-						if (ibuf) {
-							du = 1.f/(float)ibuf->x;
-							dv = 1.f/(float)ibuf->y;
+						for(c=0; c<nr_channels; c++) {

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list