[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [27713] branches/render25/source/blender/ render/intern: Render Branch: displacement now preserves smooth normals from the base mesh,

Brecht Van Lommel brecht at blender.org
Wed Mar 24 12:33:39 CET 2010


Revision: 27713
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=27713
Author:   blendix
Date:     2010-03-24 12:33:39 +0100 (Wed, 24 Mar 2010)

Log Message:
-----------
Render Branch: displacement now preserves smooth normals from the base mesh,
which got lost due to linear subdivision. It now does this:

final normal = displaced normal + (base mesh normal - subdivided normal)

Modified Paths:
--------------
    branches/render25/source/blender/render/intern/include/object.h
    branches/render25/source/blender/render/intern/include/object_mesh.h
    branches/render25/source/blender/render/intern/source/object.c
    branches/render25/source/blender/render/intern/source/object_displace.c
    branches/render25/source/blender/render/intern/source/object_mesh.c
    branches/render25/source/blender/render/intern/source/object_particle.c

Modified: branches/render25/source/blender/render/intern/include/object.h
===================================================================
--- branches/render25/source/blender/render/intern/include/object.h	2010-03-24 10:56:37 UTC (rev 27712)
+++ branches/render25/source/blender/render/intern/include/object.h	2010-03-24 11:33:39 UTC (rev 27713)
@@ -167,6 +167,7 @@
 #define RE_FACE_ELEMS			1
 #define RE_NMAP_TANGENT_ELEMS	12
 #define RE_STRANDCO_ELEMS		1
+#define RE_BASENOR_ELEMS		3
 
 #endif /* __RENDER_OBJECT_H__ */
 

Modified: branches/render25/source/blender/render/intern/include/object_mesh.h
===================================================================
--- branches/render25/source/blender/render/intern/include/object_mesh.h	2010-03-24 10:56:37 UTC (rev 27712)
+++ branches/render25/source/blender/render/intern/include/object_mesh.h	2010-03-24 11:33:39 UTC (rev 27713)
@@ -55,6 +55,7 @@
 float *render_vert_get_tangent(struct ObjectRen *obr, struct VertRen *ver, int verify);
 float *render_vert_get_strandco(struct ObjectRen *obr, struct VertRen *ver, int verify);
 float *render_vert_get_winspeed(struct ObjectInstanceRen *obi, struct VertRen *ver, int verify);
+float *render_vert_get_basenor(struct ObjectRen *obr, struct VertRen *ren, int verify);
 
 /* Face Texture Coordinates */
 
@@ -69,7 +70,7 @@
 void init_render_object_data(struct Render *re, struct ObjectRen *obr, int timeoffset);
 void init_render_particle_system(struct Render *re, struct ObjectRen *obr, struct ParticleSystem *psys, int timeoffset);
 void finalize_render_object(struct Render *re, struct ObjectRen *obr, int timeoffset);
-void render_object_calc_vnormals(struct Render *re, struct ObjectRen *obr, int do_tangent, int do_nmap_tangent);
+void render_object_calc_vnormals(struct Render *re, struct ObjectRen *obr, int do_tangent, int do_nmap_tangent, float (**diffnor)[3]);
 int render_object_has_displacement(struct Render *re, struct ObjectRen *obr);
 void render_object_displace(struct Render *re, struct ObjectRen *obr, float mat[][4], float nmat[][3]);
 
@@ -84,6 +85,7 @@
 	float *stress;
 	float *winspeed;
 	float *strandco;
+	float *basenor;
 } VertTableNode;
 
 typedef struct VlakTableNode {

Modified: branches/render25/source/blender/render/intern/source/object.c
===================================================================
--- branches/render25/source/blender/render/intern/source/object.c	2010-03-24 10:56:37 UTC (rev 27712)
+++ branches/render25/source/blender/render/intern/source/object.c	2010-03-24 11:33:39 UTC (rev 27713)
@@ -204,6 +204,8 @@
 			MEM_freeN(vertnodes[a].winspeed);
 		if(vertnodes[a].strandco)
 			MEM_freeN(vertnodes[a].strandco);
+		if(vertnodes[a].basenor)
+			MEM_freeN(vertnodes[a].basenor);
 	}
 	
 	MEM_freeN(vertnodes);

Modified: branches/render25/source/blender/render/intern/source/object_displace.c
===================================================================
--- branches/render25/source/blender/render/intern/source/object_displace.c	2010-03-24 10:56:37 UTC (rev 27712)
+++ branches/render25/source/blender/render/intern/source/object_displace.c	2010-03-24 11:33:39 UTC (rev 27713)
@@ -227,11 +227,14 @@
 	Object *obt;
 	VlakRen *vlr;
 	VertRen *vr;
-	float scale[3]={1.0f, 1.0f, 1.0f}, temp[3], *sample;
+	float scale[3]={1.0f, 1.0f, 1.0f}, temp[3], *sample, (*diffnor)[3]= NULL;
 	int i;
 
 	sample= MEM_callocN(sizeof(float)*obr->totvert, "render_object_displace sample");
 
+	/* calculate difference between base smooth and new smooth normals */
+	render_object_calc_vnormals(re, obr, 0, 0, &diffnor);
+
 	/* Object Size with parenting */
 	obt=obr->ob;
 	while(obt){
@@ -253,7 +256,7 @@
 
 	MEM_freeN(sample);
 	
-	/* Recalc vertex normals */
-	render_object_calc_vnormals(re, obr, 0, 0);
+	/* recalculate displaced smooth normals, and apply difference */
+	render_object_calc_vnormals(re, obr, 0, 0, &diffnor);
 }
 

Modified: branches/render25/source/blender/render/intern/source/object_mesh.c
===================================================================
--- branches/render25/source/blender/render/intern/source/object_mesh.c	2010-03-24 10:56:37 UTC (rev 27712)
+++ branches/render25/source/blender/render/intern/source/object_mesh.c	2010-03-24 11:33:39 UTC (rev 27713)
@@ -219,6 +219,21 @@
 	return winspeed + ver->index*RE_WINSPEED_ELEMS;
 }
 
+float *render_vert_get_basenor(ObjectRen *obr, VertRen *ver, int verify)
+{
+	float *basenor;
+	int nr= ver->index>>8;
+	
+	basenor= obr->vertnodes[nr].basenor;
+	if(basenor==NULL) {
+		if(verify) 
+			basenor= obr->vertnodes[nr].basenor= MEM_callocN(256*RE_BASENOR_ELEMS*sizeof(float), "basenor table");
+		else
+			return NULL;
+	}
+	return basenor + (ver->index & 255)*RE_BASENOR_ELEMS;
+}
+
 VertRen *render_object_vert_copy(ObjectRen *obrn, ObjectRen *obr, VertRen *ver)
 {
 	VertRen *vern= render_object_vert_get(obrn, obrn->totvert++);
@@ -253,6 +268,12 @@
 		fp2= render_vert_get_strandco(obrn, vern, 1);
 		memcpy(fp2, fp1, RE_STRANDCO_ELEMS*sizeof(float));
 	}
+	fp1= render_vert_get_basenor(obr, ver, 0);
+	if(fp1) {
+		fp2= render_vert_get_basenor(obrn, vern, 1);
+		memcpy(fp2, fp1, RE_BASENOR_ELEMS*sizeof(float));
+	}
+
 	return vern;
 }
 
@@ -797,10 +818,11 @@
 }
 
 
-void render_object_calc_vnormals(Render *re, ObjectRen *obr, int do_tangent, int do_nmap_tangent)
+void render_object_calc_vnormals(Render *re, ObjectRen *obr, int do_tangent, int do_nmap_tangent, float (**dispnor)[3])
 {
 	MemArena *arena= NULL;
 	VertexTangent **vtangents= NULL;
+	float (*backupnor)[3]= NULL, (*diffnor)[3]= NULL;
 	int a;
 
 	if(do_nmap_tangent) {
@@ -810,9 +832,19 @@
 		vtangents= MEM_callocN(sizeof(VertexTangent*)*obr->totvert, "VertexTangent");
 	}
 
+	/* for displacement, we compute difference between smooth base & subdivded nor,
+	   and then add that difference to the displaced normal to keep it smooth */
+	if(dispnor) {
+		if(*dispnor)
+			diffnor= *dispnor;
+		else
+			*dispnor= backupnor= MEM_callocN(sizeof(float)*3*obr->totvert, "backupnor");
+	}
+
 		/* clear all vertex normals */
 	for(a=0; a<obr->totvert; a++) {
 		VertRen *ver= render_object_vert_get(obr, a);
+		if(backupnor) copy_v3_v3(backupnor[a], ver->n);
 		ver->n[0]=ver->n[1]=ver->n[2]= 0.0f;
 	}
 
@@ -945,9 +977,20 @@
 				normalize_v3(tav);
 			}
 		}
+
+		if(backupnor) {
+			float tmp[3];
+			
+			copy_v3_v3(tmp, backupnor[a]);
+			sub_v3_v3(backupnor[a], ver->n);
+			copy_v3_v3(ver->n, tmp);
+		}
+		else if(diffnor)
+			add_v3_v3(ver->n, diffnor[a]);
 	}
 
-
+	if(diffnor)
+		MEM_freeN(diffnor);
 	if(arena)
 		BLI_memarena_free(arena);
 	if(vtangents)
@@ -1558,7 +1601,7 @@
 		}
 
 		/* Normals */
-		render_object_calc_vnormals(re, obr, 0, 0);
+		render_object_calc_vnormals(re, obr, 0, 0, NULL);
 	}
 
 }
@@ -2253,7 +2296,7 @@
 	
 	if(!timeoffset) {
 		if (!(ob->flag & OB_RENDER_SUBDIVIDE) && render_object_has_displacement(re, obr) ) {
-			render_object_calc_vnormals(re, obr, 0, 0);
+			render_object_calc_vnormals(re, obr, 0, 0, NULL);
 			if(do_autosmooth)
 				render_object_displace(re, obr, mat, nmat);
 			else
@@ -2264,7 +2307,7 @@
 			autosmooth(re, obr, mat, me->smoothresh);
 		}
 
-		render_object_calc_vnormals(re, obr, need_tangent, need_nmap_tangent);
+		render_object_calc_vnormals(re, obr, need_tangent, need_nmap_tangent, NULL);
 
 		if(need_stress)
 			calc_edge_stress(re, obr, me);

Modified: branches/render25/source/blender/render/intern/source/object_particle.c
===================================================================
--- branches/render25/source/blender/render/intern/source/object_particle.c	2010-03-24 10:56:37 UTC (rev 27712)
+++ branches/render25/source/blender/render/intern/source/object_particle.c	2010-03-24 11:33:39 UTC (rev 27713)
@@ -1138,6 +1138,6 @@
 	}
 
 	if(path_nbr && (ma->mode_l & MA_TANGENT_STR)==0)
-		render_object_calc_vnormals(re, obr, 0, 0);
+		render_object_calc_vnormals(re, obr, 0, 0, NULL);
 }
 





More information about the Bf-blender-cvs mailing list