[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