[Bf-blender-cvs] [0136046] master: Fix T45343: incorrect Cycles baking of bump maps from selected to active.

Brecht Van Lommel noreply at git.blender.org
Thu Feb 18 20:06:26 CET 2016


Commit: 01360463352736eebb5f42ad7ae7d61530615b84
Author: Brecht Van Lommel
Date:   Thu Feb 18 01:35:52 2016 +0100
Branches: master
https://developer.blender.org/rB01360463352736eebb5f42ad7ae7d61530615b84

Fix T45343: incorrect Cycles baking of bump maps from selected to active.

The differentials were incorrect, now they are properly transferred from the
low to the high poly mesh.

===================================================================

M	source/blender/render/intern/include/shading.h
M	source/blender/render/intern/source/bake_api.c
M	source/blender/render/intern/source/shadeinput.c

===================================================================

diff --git a/source/blender/render/intern/include/shading.h b/source/blender/render/intern/include/shading.h
index 11dcc9d..27867ea 100644
--- a/source/blender/render/intern/include/shading.h
+++ b/source/blender/render/intern/include/shading.h
@@ -82,6 +82,10 @@ void vlr_set_uv_indices(struct VlakRen *vlr, int *i1, int *i2, int *i3);
 
 void	calc_R_ref(struct ShadeInput *shi);
 
+void barycentric_differentials_from_position(
+	const float co[3], const float v1[3], const float v2[3], const float v3[3],
+	const float dxco[3], const float dyco[3], const float facenor[3], const bool differentials,
+	float *u, float *v, float *dx_u, float *dx_v, float *dy_u, float *dy_v);
 
 /* shadeoutput. */
 void shade_lamp_loop(struct ShadeInput *shi, struct ShadeResult *shr);
diff --git a/source/blender/render/intern/source/bake_api.c b/source/blender/render/intern/source/bake_api.c
index 21460c7..63aa0d5 100644
--- a/source/blender/render/intern/source/bake_api.c
+++ b/source/blender/render/intern/source/bake_api.c
@@ -84,6 +84,7 @@
 
 /* local include */
 #include "render_types.h"
+#include "shading.h"
 #include "zbuf.h"
 
 /* Remove when Cycles moves from MFace to MLoopTri */
@@ -263,31 +264,14 @@ static void calc_point_from_barycentric_extrusion(
 }
 
 /**
- * This function returns the barycentric u,v of a face for a coordinate. The face is defined by its index.
- */
-static void calc_barycentric_from_point(
-        TriTessFace *triangles, const int index, const float co[3],
-        int *r_primitive_id, float r_uv[2])
-{
-	TriTessFace *triangle = &triangles[index];
-	resolve_tri_uv_v3(r_uv, co,
-	                  triangle->mverts[0]->co,
-	                  triangle->mverts[1]->co,
-	                  triangle->mverts[2]->co);
-	*r_primitive_id = index;
-}
-
-/**
  * This function populates pixel_array and returns TRUE if things are correct
  */
 static bool cast_ray_highpoly(
-        BVHTreeFromMesh *treeData, TriTessFace *triangles[], BakePixel *pixel_array, BakeHighPolyData *highpoly,
-        const float co[3], const float dir[3], const int pixel_id, const int tot_highpoly,
-        const float du_dx, const float du_dy, const float dv_dx, const float dv_dy)
+        BVHTreeFromMesh *treeData, TriTessFace *triangle_low, TriTessFace *triangles[],
+        BakePixel *pixel_array_low, BakePixel *pixel_array, float mat_low[4][4], BakeHighPolyData *highpoly,
+        const float co[3], const float dir[3], const int pixel_id, const int tot_highpoly)
 {
 	int i;
-	int primitive_id = -1;
-	float uv[2];
 	int hit_mesh = -1;
 	float hit_distance = FLT_MAX;
 
@@ -333,17 +317,47 @@ static bool cast_ray_highpoly(
 	}
 
 	if (hit_mesh != -1) {
-		calc_barycentric_from_point(triangles[hit_mesh], hits[hit_mesh].index, hits[hit_mesh].co, &primitive_id, uv);
-		pixel_array[pixel_id].primitive_id = primitive_id;
+		int primitive_id_high = hits[hit_mesh].index;
+		TriTessFace *triangle_high = &triangles[hit_mesh][primitive_id_high];
+
+		pixel_array[pixel_id].primitive_id = primitive_id_high;
 		pixel_array[pixel_id].object_id = hit_mesh;
-		copy_v2_v2(pixel_array[pixel_id].uv, uv);
 
-		/* the differentials are relative to the UV/image space, so the highpoly differentials
-		 * are the same as the low poly differentials */
-		pixel_array[pixel_id].du_dx = du_dx;
-		pixel_array[pixel_id].du_dy = du_dy;
-		pixel_array[pixel_id].dv_dx = dv_dx;
-		pixel_array[pixel_id].dv_dy = dv_dy;
+		/* ray direction in high poly object space */
+		float dir_high[3];
+		mul_v3_mat3_m4v3(dir_high, highpoly[hit_mesh].imat, dir);
+		normalize_v3(dir_high);
+
+		/* compute position differentials on low poly object */
+		float duco_low[3], dvco_low[3], dxco[3], dyco[3];
+		sub_v3_v3v3(duco_low, triangle_low->mverts[0]->co, triangle_low->mverts[2]->co);
+		sub_v3_v3v3(dvco_low, triangle_low->mverts[1]->co, triangle_low->mverts[2]->co);
+
+		mul_v3_v3fl(dxco, duco_low, pixel_array_low[pixel_id].du_dx);
+		madd_v3_v3fl(dxco, dvco_low, pixel_array_low[pixel_id].dv_dx);
+		mul_v3_v3fl(dyco, duco_low, pixel_array_low[pixel_id].du_dy);
+		madd_v3_v3fl(dyco, dvco_low, pixel_array_low[pixel_id].dv_dy);
+
+		/* transform from low poly to to high poly object space */
+		mul_mat3_m4_v3(mat_low, dxco);
+		mul_mat3_m4_v3(mat_low, dyco);
+		mul_mat3_m4_v3(highpoly[hit_mesh].imat, dxco);
+		mul_mat3_m4_v3(highpoly[hit_mesh].imat, dyco);
+
+		/* transfer position differentials */
+		float tmp[3];
+		mul_v3_v3fl(tmp, dir_high, 1.0f/dot_v3v3(dir_high, triangle_high->normal));
+		madd_v3_v3fl(dxco, tmp, -dot_v3v3(dxco, triangle_high->normal));
+		madd_v3_v3fl(dyco, tmp, -dot_v3v3(dyco, triangle_high->normal));
+
+		/* compute barycentric differentials from position differentials */
+		barycentric_differentials_from_position(
+			hits[hit_mesh].co, triangle_high->mverts[0]->co,
+			triangle_high->mverts[1]->co, triangle_high->mverts[2]->co,
+			dxco, dyco, triangle_high->normal, true,
+			&pixel_array[pixel_id].uv[0], &pixel_array[pixel_id].uv[1],
+			&pixel_array[pixel_id].du_dx, &pixel_array[pixel_id].dv_dx,
+			&pixel_array[pixel_id].du_dy, &pixel_array[pixel_id].dv_dy);
 	}
 	else {
 		pixel_array[pixel_id].primitive_id = -1;
@@ -441,17 +455,17 @@ static TriTessFace *mesh_calc_tri_tessface(
 			triangles[i].tspace[0] = &tspace[lt->tri[0]];
 			triangles[i].tspace[1] = &tspace[lt->tri[1]];
 			triangles[i].tspace[2] = &tspace[lt->tri[2]];
+		}
 
-			if (calculate_normal) {
-				if (lt->poly != mpoly_prev) {
-					BKE_mesh_calc_poly_normal(mp, &me->mloop[mp->loopstart], me->mvert, no);
-					mpoly_prev = lt->poly;
-				}
-				copy_v3_v3(triangles[i].normal, no);
-			}
-			else {
-				copy_v3_v3(triangles[i].normal, &precomputed_normals[lt->poly]);
+		if (calculate_normal) {
+			if (lt->poly != mpoly_prev) {
+				BKE_mesh_calc_poly_normal(mp, &me->mloop[mp->loopstart], me->mvert, no);
+				mpoly_prev = lt->poly;
 			}
+			copy_v3_v3(triangles[i].normal, no);
+		}
+		else {
+			copy_v3_v3(triangles[i].normal, &precomputed_normals[lt->poly]);
 		}
 	}
 
@@ -546,9 +560,9 @@ bool RE_bake_pixels_populate_from_objects(
 		}
 
 		/* cast ray */
-		if (!cast_ray_highpoly(treeData, tris_high, pixel_array_to, highpoly, co, dir, i, tot_highpoly,
-		                       pixel_array_from[i].du_dx, pixel_array_from[i].du_dy,
-		                       pixel_array_from[i].dv_dx, pixel_array_from[i].dv_dy)) {
+		if (!cast_ray_highpoly(treeData, &tris_low[primitive_id], tris_high,
+		                       pixel_array_from, pixel_array_to, mat_low,
+		                       highpoly, co, dir, i, tot_highpoly)) {
 			/* if it fails mask out the original pixel array */
 			pixel_array_from[i].primitive_id = -1;
 		}
diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c
index 05097bb..e60a5a7 100644
--- a/source/blender/render/intern/source/shadeinput.c
+++ b/source/blender/render/intern/source/shadeinput.c
@@ -705,6 +705,35 @@ void shade_input_set_viewco(ShadeInput *shi, float x, float y, float xs, float y
 	shade_input_calc_viewco(shi, xs, ys, z, shi->view, dxyview, shi->co, dxco, dyco);
 }
 
+void barycentric_differentials_from_position(
+	const float co[3], const float v1[3], const float v2[3], const float v3[3],
+	const float dxco[3], const float dyco[3], const float facenor[3], const bool differentials,
+	float *u, float *v, float *dx_u, float *dx_v, float *dy_u, float *dy_v)
+{
+	/* find most stable axis to project */
+	int axis1, axis2;
+	axis_dominant_v3(&axis1, &axis2, facenor);
+
+	/* compute u,v and derivatives */
+	float t00 = v3[axis1] - v1[axis1];
+	float t01 = v3[axis2] - v1[axis2];
+	float t10 = v3[axis1] - v2[axis1];
+	float t11 = v3[axis2] - v2[axis2];
+
+	float detsh = (t00 * t11 - t10 * t01);
+	detsh = (detsh != 0.0f) ? 1.0f / detsh : 0.0f;
+	t00 *= detsh; t01 *= detsh;
+	t10 *= detsh; t11 *= detsh;
+
+	*u = (v3[axis1] - co[axis1]) * t11 - (v3[axis2] - co[axis2]) * t10;
+	*v = (v3[axis2] - co[axis2]) * t00 - (v3[axis1] - co[axis1]) * t01;
+	if (differentials) {
+		*dx_u =  dxco[axis1] * t11 - dxco[axis2] * t10;
+		*dx_v =  dxco[axis2] * t00 - dxco[axis1] * t01;
+		*dy_u =  dyco[axis1] * t11 - dyco[axis2] * t10;
+		*dy_v =  dyco[axis2] * t00 - dyco[axis1] * t01;
+	}
+}
 /* calculate U and V, for scanline (silly render face u and v are in range -1 to 0) */
 void shade_input_set_uv(ShadeInput *shi)
 {
@@ -746,30 +775,12 @@ void shade_input_set_uv(ShadeInput *shi)
 			}
 		}
 		else {
-			/* most of this could become re-used for faces */
-			float detsh, t00, t10, t01, t11;
-			int axis1, axis2;
-
-			/* find most stable axis to project */
-			axis_dominant_v3(&axis1, &axis2, shi->facenor);
+			barycentric_differentials_from_position(
+				shi->co, v1, v2, v3, shi->dxco, shi->dyco, shi->facenor, shi->osatex,
+				&shi->u, &shi->v, &shi->dx_u, &shi->dx_v, &shi->dy_u, &shi->dy_v);
 
-			/* compute u,v and derivatives */
-			t00 = v3[axis1] - v1[axis1]; t01 = v3[axis2] - v1[axis2];
-			t10 = v3[axis1] - v2[axis1]; t11 = v3[axis2] - v2[axis2];
-
-			detsh = (t00 * t11 - t10 * t01);
-			detsh = (detsh != 0.0f) ? 1.0f / detsh : 0.0f;
-			t00 *= detsh; t01 *= detsh;
-			t10 *= detsh; t11 *= detsh;
-
-			shi->u = (shi->co[axis1] - v3[axis1]) * t11 - (shi->co[axis2] - v3[axis2]) * t10;
-			shi->v = (shi->co[axis2] - v3[axis2]) * t00 - (shi->co[axis1] - v3[axis1]) * t01;
-			if (shi->osatex) {
-				shi->dx_u =  shi->dxco[axis1] * t11 - shi->dxco[axis2] * t10;
-				shi->dx_v =  shi->dxco[axis2] * t00 - shi->dxco[axis1] * t01;
-				shi->dy_u =  shi->dyco[axis1] * t11 - shi->dyco[axis2] * t10;
-				shi->dy_v =  shi->dyco[axis2] * t00 - shi->dyco[axis1] * t01;
-			}
+			shi->u = -shi->u;
+			shi->v = -shi->v;
 
 			/* u and v are in range -1 to 0, we allow a little bit extra but not too much, screws up speedvectors */
 			CLAMP(shi->u, -2.0f, 1.0f);




More information about the Bf-blender-cvs mailing list