Blender V4.5
bake.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
51
52#include <climits>
53#include <cstring>
54
55#include "MEM_guardedalloc.h"
56
57#include "BLI_index_range.hh"
58#include "BLI_math_geom.h"
59#include "BLI_math_matrix.h"
60#include "BLI_math_vector.h"
61#include "BLI_task.hh"
62
63#include "BKE_attribute.hh"
64#include "BKE_bvhutils.hh"
65#include "BKE_customdata.hh"
66#include "BKE_image.hh"
67#include "BKE_lib_id.hh"
68#include "BKE_mesh.hh"
69#include "BKE_mesh_runtime.hh"
70#include "BKE_mesh_tangent.hh"
71#include "BKE_node.hh"
72
73#include "IMB_imbuf.hh"
74#include "IMB_imbuf_types.hh"
75
76#include "RE_bake.h"
77#include "RE_texture_margin.h"
78
79/* local include */
80#include "zbuf.h"
81
90
94struct TSpace {
95 float tangent[3];
96 float sign;
97};
98
100 const float *positions[3];
101 const float *vert_normals[3];
102 const TSpace *tspace[3];
103 const float *loop_normal[3];
104 float normal[3]; /* for flat faces */
106};
107
108static void store_bake_pixel(void *handle, int x, int y, float u, float v)
109{
110 BakeDataZSpan *bd = (BakeDataZSpan *)handle;
111 BakePixel *pixel;
112
113 const int width = bd->bk_image->width;
114 const size_t offset = bd->bk_image->offset;
115 const int i = offset + y * width + x;
116
117 pixel = &bd->pixel_array[i];
118 pixel->primitive_id = bd->primitive_id;
119
120 /* At this point object_id is always 0, since this function runs for the
121 * low-poly mesh only. The object_id lookup indices are set afterwards. */
122
123 copy_v2_fl2(pixel->uv, u, v);
124
125 pixel->du_dx = bd->du_dx;
126 pixel->du_dy = bd->du_dy;
127 pixel->dv_dx = bd->dv_dx;
128 pixel->dv_dy = bd->dv_dy;
129 pixel->object_id = 0;
130 pixel->seed = i;
131}
132
133void RE_bake_mask_fill(const BakePixel pixel_array[], const size_t pixels_num, char *mask)
134{
135 size_t i;
136 if (!mask) {
137 return;
138 }
139
140 /* only extend to pixels outside the mask area */
141 for (i = 0; i < pixels_num; i++) {
142 if (pixel_array[i].primitive_id != -1) {
144 }
145 }
146}
147
149 char *mask,
150 const int margin,
151 const char margin_type,
152 const Mesh *mesh,
153 char const *uv_layer,
154 const float uv_offset[2])
155{
156 /* margin */
157 switch (margin_type) {
159 RE_generate_texturemargin_adjacentfaces(ibuf, mask, margin, mesh, uv_layer, uv_offset);
160 break;
161 default:
162 /* fall through */
163 case R_BAKE_EXTEND:
164 IMB_filter_extend(ibuf, mask, margin);
165 break;
166 }
167
168 if (ibuf->planes != R_IMF_PLANES_RGBA) {
169 /* clear alpha added by filtering */
170 IMB_rectfill_alpha(ibuf, 1.0f);
171 }
172}
173
182 TriTessFace *triangles_cage,
183 const float mat_low[4][4],
184 const float mat_cage[4][4],
185 int primitive_id,
186 float u,
187 float v,
188 float r_co[3],
189 float r_dir[3])
190{
191 float data[2][3][3];
192 float coord[2][3];
193 float dir[3];
194 int i;
195
196 TriTessFace *triangle[2];
197
198 triangle[0] = &triangles_low[primitive_id];
199 triangle[1] = &triangles_cage[primitive_id];
200
201 for (i = 0; i < 2; i++) {
202 copy_v3_v3(data[i][0], triangle[i]->positions[0]);
203 copy_v3_v3(data[i][1], triangle[i]->positions[1]);
204 copy_v3_v3(data[i][2], triangle[i]->positions[2]);
205 interp_barycentric_tri_v3(data[i], u, v, coord[i]);
206 }
207
208 /* convert from local to world space */
209 mul_m4_v3(mat_low, coord[0]);
210 mul_m4_v3(mat_cage, coord[1]);
211
212 sub_v3_v3v3(dir, coord[0], coord[1]);
213 normalize_v3(dir);
214
215 copy_v3_v3(r_co, coord[1]);
216 copy_v3_v3(r_dir, dir);
217}
218
225 const float mat[4][4],
226 const float imat[4][4],
227 int primitive_id,
228 float u,
229 float v,
230 float cage_extrusion,
231 float r_co[3],
232 float r_dir[3],
233 const bool is_cage)
234{
235 float data[3][3];
236 float coord[3];
237 float dir[3];
238 float cage[3];
239 bool is_smooth;
240
241 TriTessFace *triangle = &triangles[primitive_id];
242 is_smooth = triangle->is_smooth || is_cage;
243
244 copy_v3_v3(data[0], triangle->positions[0]);
245 copy_v3_v3(data[1], triangle->positions[1]);
246 copy_v3_v3(data[2], triangle->positions[2]);
247
248 interp_barycentric_tri_v3(data, u, v, coord);
249
250 if (is_smooth) {
251 copy_v3_v3(data[0], triangle->vert_normals[0]);
252 copy_v3_v3(data[1], triangle->vert_normals[1]);
253 copy_v3_v3(data[2], triangle->vert_normals[2]);
254
256 normalize_v3(dir);
257 }
258 else {
259 copy_v3_v3(dir, triangle->normal);
260 }
261
262 mul_v3_v3fl(cage, dir, cage_extrusion);
263 add_v3_v3(coord, cage);
264
265 normalize_v3(dir);
266 negate_v3(dir);
267
268 /* convert from local to world space */
269 mul_m4_v3(mat, coord);
270 mul_transposed_mat3_m4_v3(imat, dir);
271 normalize_v3(dir);
272
273 copy_v3_v3(r_co, coord);
274 copy_v3_v3(r_dir, dir);
275}
276
277static void barycentric_differentials_from_position(const float co[3],
278 const float v1[3],
279 const float v2[3],
280 const float v3[3],
281 const float dxco[3],
282 const float dyco[3],
283 const float facenor[3],
284 const bool differentials,
285 float *u,
286 float *v,
287 float *dx_u,
288 float *dx_v,
289 float *dy_u,
290 float *dy_v)
291{
292 /* find most stable axis to project */
293 int axis1, axis2;
294 axis_dominant_v3(&axis1, &axis2, facenor);
295
296 /* compute u,v and derivatives */
297 float t00 = v3[axis1] - v1[axis1];
298 float t01 = v3[axis2] - v1[axis2];
299 float t10 = v3[axis1] - v2[axis1];
300 float t11 = v3[axis2] - v2[axis2];
301
302 float detsh = (t00 * t11 - t10 * t01);
303 detsh = (detsh != 0.0f) ? 1.0f / detsh : 0.0f;
304 t00 *= detsh;
305 t01 *= detsh;
306 t10 *= detsh;
307 t11 *= detsh;
308
309 *u = (v3[axis1] - co[axis1]) * t11 - (v3[axis2] - co[axis2]) * t10;
310 *v = (v3[axis2] - co[axis2]) * t00 - (v3[axis1] - co[axis1]) * t01;
311 if (differentials) {
312 *dx_u = dxco[axis1] * t11 - dxco[axis2] * t10;
313 *dx_v = dxco[axis2] * t00 - dxco[axis1] * t01;
314 *dy_u = dyco[axis1] * t11 - dyco[axis2] * t10;
315 *dy_v = dyco[axis2] * t00 - dyco[axis1] * t01;
316 }
317}
318
323 TriTessFace *triangle_low,
324 TriTessFace *triangles[],
325 BakePixel *pixel_array_low,
326 BakePixel *pixel_array,
327 const float mat_low[4][4],
328 BakeHighPolyData *highpoly,
329 const int highpoly_num,
331 const float co[3],
332 const float dir[3],
333 const int pixel_id,
334 const float max_ray_distance)
335{
336 int hit_mesh = -1;
337 float hit_distance_squared = max_ray_distance * max_ray_distance;
338 if (hit_distance_squared == 0.0f) {
339 /* No ray distance set, use maximum. */
340 hit_distance_squared = FLT_MAX;
341 }
342
343 for (int i = 0; i < highpoly_num; i++) {
344 float co_high[3], dir_high[3];
345
346 hits[i].index = -1;
347 /* TODO: we should use FLT_MAX here, but sweep-sphere code isn't prepared for that. */
348 hits[i].dist = BVH_RAYCAST_DIST_MAX;
349
350 /* Transform the ray from the world space to the `highpoly` space. */
351 mul_v3_m4v3(co_high, highpoly[i].imat, co);
352
353 /* rotates */
354 mul_v3_mat3_m4v3(dir_high, highpoly[i].imat, dir);
355 normalize_v3(dir_high);
356
357 /* cast ray */
358 if (treeData[i].tree) {
359 BLI_bvhtree_ray_cast(treeData[i].tree,
360 co_high,
361 dir_high,
362 0.0f,
363 &hits[i],
364 treeData[i].raycast_callback,
365 &treeData[i]);
366 }
367
368 if (hits[i].index != -1) {
369 /* distance comparison in world space */
370 float hit_world[3];
371 mul_v3_m4v3(hit_world, highpoly[i].obmat, hits[i].co);
372 float distance_squared = len_squared_v3v3(hit_world, co);
373
374 if (distance_squared < hit_distance_squared) {
375 hit_mesh = i;
376 hit_distance_squared = distance_squared;
377 }
378 }
379 }
380
381 if (hit_mesh != -1) {
382 int primitive_id_high = hits[hit_mesh].index;
383 TriTessFace *triangle_high = &triangles[hit_mesh][primitive_id_high];
384 BakePixel *pixel_low = &pixel_array_low[pixel_id];
385 BakePixel *pixel_high = &pixel_array[pixel_id];
386
387 pixel_high->primitive_id = primitive_id_high;
388 pixel_high->object_id = hit_mesh;
389 pixel_high->seed = pixel_id;
390
391 /* ray direction in high poly object space */
392 float dir_high[3];
393 mul_v3_mat3_m4v3(dir_high, highpoly[hit_mesh].imat, dir);
394 normalize_v3(dir_high);
395
396 /* compute position differentials on low poly object */
397 float duco_low[3], dvco_low[3], dxco[3], dyco[3];
398 sub_v3_v3v3(duco_low, triangle_low->positions[0], triangle_low->positions[2]);
399 sub_v3_v3v3(dvco_low, triangle_low->positions[1], triangle_low->positions[2]);
400
401 mul_v3_v3fl(dxco, duco_low, pixel_low->du_dx);
402 madd_v3_v3fl(dxco, dvco_low, pixel_low->dv_dx);
403 mul_v3_v3fl(dyco, duco_low, pixel_low->du_dy);
404 madd_v3_v3fl(dyco, dvco_low, pixel_low->dv_dy);
405
406 /* transform from low poly to high poly object space */
407 mul_mat3_m4_v3(mat_low, dxco);
408 mul_mat3_m4_v3(mat_low, dyco);
409 mul_mat3_m4_v3(highpoly[hit_mesh].imat, dxco);
410 mul_mat3_m4_v3(highpoly[hit_mesh].imat, dyco);
411
412 /* transfer position differentials */
413 float tmp[3];
414 mul_v3_v3fl(tmp, dir_high, 1.0f / dot_v3v3(dir_high, triangle_high->normal));
415 madd_v3_v3fl(dxco, tmp, -dot_v3v3(dxco, triangle_high->normal));
416 madd_v3_v3fl(dyco, tmp, -dot_v3v3(dyco, triangle_high->normal));
417
418 /* compute barycentric differentials from position differentials */
420 triangle_high->positions[0],
421 triangle_high->positions[1],
422 triangle_high->positions[2],
423 dxco,
424 dyco,
425 triangle_high->normal,
426 true,
427 &pixel_high->uv[0],
428 &pixel_high->uv[1],
429 &pixel_high->du_dx,
430 &pixel_high->dv_dx,
431 &pixel_high->du_dy,
432 &pixel_high->dv_dy);
433
434 /* verify we have valid uvs */
435 BLI_assert(pixel_high->uv[0] >= -1e-3f && pixel_high->uv[1] >= -1e-3f &&
436 pixel_high->uv[0] + pixel_high->uv[1] <= 1.0f + 1e-3f);
437 }
438 else {
439 pixel_array[pixel_id].primitive_id = -1;
440 pixel_array[pixel_id].object_id = -1;
441 pixel_array[pixel_id].seed = 0;
442 }
443
444 return hit_mesh != -1;
445}
446
451static TriTessFace *mesh_calc_tri_tessface(Mesh *mesh, bool tangent, Mesh *mesh_eval)
452{
453 using namespace blender;
454 int i;
455
456 const int tottri = poly_to_tri_count(mesh->faces_num, mesh->corners_num);
457 TriTessFace *triangles;
458
459 /* calculate normal for each face only once */
460 uint mpoly_prev = UINT_MAX;
462
463 const blender::Span<blender::float3> positions = mesh->vert_positions();
464 const blender::OffsetIndices faces = mesh->faces();
465 const blender::Span<int> corner_verts = mesh->corner_verts();
466 const bke::AttributeAccessor attributes = mesh->attributes();
467 const VArray<bool> sharp_faces =
468 attributes.lookup_or_default<bool>("sharp_face", bke::AttrDomain::Face, false).varray;
469
470 blender::int3 *corner_tris = static_cast<blender::int3 *>(
471 MEM_mallocN(sizeof(*corner_tris) * tottri, __func__));
472 triangles = MEM_calloc_arrayN<TriTessFace>(tottri, __func__);
473
474 const bool calculate_normal = BKE_mesh_face_normals_are_dirty(mesh);
475 blender::Span<blender::float3> precomputed_normals;
476 if (!calculate_normal) {
477 precomputed_normals = mesh->face_normals();
478 }
479
480 if (!precomputed_normals.is_empty()) {
482 positions, faces, corner_verts, precomputed_normals, {corner_tris, tottri});
483 }
484 else {
485 blender::bke::mesh::corner_tris_calc(positions, faces, corner_verts, {corner_tris, tottri});
486 }
487
488 const TSpace *tspace = nullptr;
489 blender::Span<blender::float3> corner_normals;
490 if (tangent) {
491 BKE_mesh_calc_loop_tangents(mesh_eval, true, nullptr, 0);
492
493 tspace = static_cast<const TSpace *>(
495 BLI_assert(tspace);
496
497 corner_normals = mesh_eval->corner_normals();
498 }
499
500 const blender::Span<blender::float3> vert_normals = mesh->vert_normals();
501 const blender::Span<int> tri_faces = mesh->corner_tri_faces();
502 for (i = 0; i < tottri; i++) {
503 const int3 &tri = corner_tris[i];
504 const int face_i = tri_faces[i];
505
506 triangles[i].positions[0] = positions[corner_verts[tri[0]]];
507 triangles[i].positions[1] = positions[corner_verts[tri[1]]];
508 triangles[i].positions[2] = positions[corner_verts[tri[2]]];
509 triangles[i].vert_normals[0] = vert_normals[corner_verts[tri[0]]];
510 triangles[i].vert_normals[1] = vert_normals[corner_verts[tri[1]]];
511 triangles[i].vert_normals[2] = vert_normals[corner_verts[tri[2]]];
512 triangles[i].is_smooth = !sharp_faces[face_i];
513
514 if (tangent) {
515 triangles[i].tspace[0] = &tspace[tri[0]];
516 triangles[i].tspace[1] = &tspace[tri[1]];
517 triangles[i].tspace[2] = &tspace[tri[2]];
518 }
519
520 if (!corner_normals.is_empty()) {
521 triangles[i].loop_normal[0] = corner_normals[tri[0]];
522 triangles[i].loop_normal[1] = corner_normals[tri[1]];
523 triangles[i].loop_normal[2] = corner_normals[tri[2]];
524 }
525
526 if (calculate_normal) {
527 if (face_i != mpoly_prev) {
528 no = blender::bke::mesh::face_normal_calc(positions, corner_verts.slice(faces[face_i]));
529 mpoly_prev = face_i;
530 }
531 copy_v3_v3(triangles[i].normal, no);
532 }
533 else {
534 copy_v3_v3(triangles[i].normal, precomputed_normals[face_i]);
535 }
536 }
537
538 MEM_freeN(corner_tris);
539
540 return triangles;
541}
542
544 BakePixel pixel_array_from[],
545 BakePixel pixel_array_to[],
546 BakeHighPolyData highpoly[],
547 const int highpoly_num,
548 const size_t pixels_num,
549 const bool is_custom_cage,
550 const float cage_extrusion,
551 const float max_ray_distance,
552 const float mat_low[4][4],
553 const float mat_cage[4][4],
554 Mesh *me_cage)
555{
556 using namespace blender;
557 float imat_low[4][4];
558 bool is_cage = me_cage != nullptr;
559 bool result = true;
560
561 Mesh *me_eval_low = nullptr;
562 Mesh **me_highpoly;
563
564 /* NOTE: all coordinates are in local space. */
565 TriTessFace *tris_low = nullptr;
566 TriTessFace *tris_cage = nullptr;
567 TriTessFace **tris_high;
568
569 /* Assume all low-poly tessfaces can be quads. */
570 tris_high = MEM_calloc_arrayN<TriTessFace *>(highpoly_num, "MVerts Highpoly Mesh Array");
571
572 /* Assume all high-poly tessfaces are triangles. */
573 me_highpoly = MEM_malloc_arrayN<Mesh *>(highpoly_num, "Highpoly Derived Meshes");
574 Array<blender::bke::BVHTreeFromMesh> treeData(highpoly_num);
575
576 if (!is_cage) {
577 me_eval_low = BKE_mesh_copy_for_eval(*me_low);
578 tris_low = mesh_calc_tri_tessface(me_low, true, me_eval_low);
579 }
580 else if (is_custom_cage) {
581 tris_low = mesh_calc_tri_tessface(me_low, false, nullptr);
582 tris_cage = mesh_calc_tri_tessface(me_cage, false, nullptr);
583 }
584 else {
585 tris_cage = mesh_calc_tri_tessface(me_cage, false, nullptr);
586 }
587
588 invert_m4_m4(imat_low, mat_low);
589
590 for (int i = 0; i < highpoly_num; i++) {
591 tris_high[i] = mesh_calc_tri_tessface(highpoly[i].mesh, false, nullptr);
592
593 me_highpoly[i] = highpoly[i].mesh;
594
595 if (BKE_mesh_runtime_corner_tris_len(me_highpoly[i]) != 0) {
596 treeData[i] = me_highpoly[i]->bvh_corner_tris();
597 if (treeData[i].tree == nullptr) {
598 printf("Baking: out of memory while creating BHVTree for object \"%s\"\n",
599 highpoly[i].ob->id.name + 2);
600 result = false;
601 goto cleanup;
602 }
603 }
604 }
605
606 threading::parallel_for(IndexRange(pixels_num), 1024, [&](const IndexRange range) {
607 Array<BVHTreeRayHit> hits(highpoly_num);
608 for (const IndexRange::Iterator::value_type i : range) {
609 int primitive_id = pixel_array_from[i].primitive_id;
610
611 if (primitive_id == -1) {
612 pixel_array_to[i].primitive_id = -1;
613 continue;
614 }
615
616 const float u = pixel_array_from[i].uv[0];
617 const float v = pixel_array_from[i].uv[1];
618 float co[3];
619 float dir[3];
620 TriTessFace *tri_low;
621
622 /* calculate from low poly mesh cage */
623 if (is_custom_cage) {
625 tris_low, tris_cage, mat_low, mat_cage, primitive_id, u, v, co, dir);
626 tri_low = &tris_cage[primitive_id];
627 }
628 else if (is_cage) {
630 tris_cage, mat_low, imat_low, primitive_id, u, v, cage_extrusion, co, dir, true);
631 tri_low = &tris_cage[primitive_id];
632 }
633 else {
635 tris_low, mat_low, imat_low, primitive_id, u, v, cage_extrusion, co, dir, false);
636 tri_low = &tris_low[primitive_id];
637 }
638
639 /* cast ray */
640 if (!cast_ray_highpoly(treeData.data(),
641 tri_low,
642 tris_high,
643 pixel_array_from,
644 pixel_array_to,
645 mat_low,
646 highpoly,
647 highpoly_num,
648 hits,
649 co,
650 dir,
651 i,
652 max_ray_distance))
653 {
654 /* if it fails mask out the original pixel array */
655 pixel_array_from[i].primitive_id = -1;
656 }
657 }
658 });
659
660 /* garbage collection */
661cleanup:
662 for (int i = 0; i < highpoly_num; i++) {
663 if (tris_high[i]) {
664 MEM_freeN(tris_high[i]);
665 }
666 }
667
668 MEM_freeN(tris_high);
669 MEM_freeN(me_highpoly);
670
671 if (me_eval_low) {
672 BKE_id_free(nullptr, me_eval_low);
673 }
674 if (tris_low) {
675 MEM_freeN(tris_low);
676 }
677 if (tris_cage) {
678 MEM_freeN(tris_cage);
679 }
680
681 return result;
682}
683
685 const float *uv1,
686 const float *uv2,
687 const float *uv3)
688{
689 float A;
690
691 /* assumes dPdu = P1 - P3 and dPdv = P2 - P3 */
692 A = (uv2[0] - uv1[0]) * (uv3[1] - uv1[1]) - (uv3[0] - uv1[0]) * (uv2[1] - uv1[1]);
693
694 if (fabsf(A) > FLT_EPSILON) {
695 A = 0.5f / A;
696
697 bd->du_dx = (uv2[1] - uv3[1]) * A;
698 bd->dv_dx = (uv3[1] - uv1[1]) * A;
699
700 bd->du_dy = (uv3[0] - uv2[0]) * A;
701 bd->dv_dy = (uv1[0] - uv3[0]) * A;
702 }
703 else {
704 bd->du_dx = bd->du_dy = 0.0f;
705 bd->dv_dx = bd->dv_dy = 0.0f;
706 }
707}
708
710 BakePixel pixel_array[],
711 const size_t pixels_num,
712 const BakeTargets *targets,
713 const char *uv_layer)
714{
715 using namespace blender;
716 const float(*mloopuv)[2];
717 if ((uv_layer == nullptr) || (uv_layer[0] == '\0')) {
718 mloopuv = static_cast<const float(*)[2]>(
720 }
721 else {
722 int uv_id = CustomData_get_named_layer(&mesh->corner_data, CD_PROP_FLOAT2, uv_layer);
723 mloopuv = static_cast<const float(*)[2]>(
725 }
726
727 if (mloopuv == nullptr) {
728 return;
729 }
730
731 BakeDataZSpan bd;
732 bd.pixel_array = pixel_array;
733 bd.zspan = MEM_calloc_arrayN<ZSpan>(targets->images_num, "bake zspan");
734
735 /* initialize all pixel arrays so we know which ones are 'blank' */
736 for (int i = 0; i < pixels_num; i++) {
737 pixel_array[i].primitive_id = -1;
738 pixel_array[i].object_id = 0;
739 }
740
741 for (int i = 0; i < targets->images_num; i++) {
742 zbuf_alloc_span(&bd.zspan[i], targets->images[i].width, targets->images[i].height);
743 }
744
745 const int tottri = poly_to_tri_count(mesh->faces_num, mesh->corners_num);
746 blender::int3 *corner_tris = MEM_malloc_arrayN<blender::int3>(size_t(tottri), __func__);
747
749 mesh->vert_positions(), mesh->faces(), mesh->corner_verts(), {corner_tris, tottri});
750
751 const blender::Span<int> tri_faces = mesh->corner_tri_faces();
752 const bke::AttributeAccessor attributes = mesh->attributes();
753 const VArraySpan material_indices = *attributes.lookup<int>("material_index",
755
756 const int materials_num = targets->materials_num;
757
758 for (int i = 0; i < tottri; i++) {
759 const int3 &tri = corner_tris[i];
760 const int face_i = tri_faces[i];
761
762 bd.primitive_id = i;
763
764 /* Find images matching this material. */
765 const int material_index = (!material_indices.is_empty() && materials_num) ?
766 clamp_i(material_indices[face_i], 0, materials_num - 1) :
767 0;
768 Image *image = targets->material_to_image[material_index];
769 for (int image_id = 0; image_id < targets->images_num; image_id++) {
770 BakeImage *bk_image = &targets->images[image_id];
771 if (bk_image->image != image) {
772 continue;
773 }
774
775 /* Compute triangle vertex UV coordinates. */
776 float vec[3][2];
777 for (int a = 0; a < 3; a++) {
778 const float *uv = mloopuv[tri[a]];
779
780 /* NOTE(@ideasman42): workaround for pixel aligned UVs which are common and can screw
781 * up our intersection tests where a pixel gets in between 2 faces or the middle of a quad,
782 * camera aligned quads also have this problem but they are less common.
783 * Add a small offset to the UVs, fixes bug #18685. */
784 vec[a][0] = (uv[0] - bk_image->uv_offset[0]) * float(bk_image->width) - (0.5f + 0.001f);
785 vec[a][1] = (uv[1] - bk_image->uv_offset[1]) * float(bk_image->height) - (0.5f + 0.002f);
786 }
787
788 /* Rasterize triangle. */
789 bd.bk_image = bk_image;
790 bake_differentials(&bd, vec[0], vec[1], vec[2]);
792 &bd.zspan[image_id], (void *)&bd, vec[0], vec[1], vec[2], store_bake_pixel);
793 }
794 }
795
796 for (int i = 0; i < targets->images_num; i++) {
797 zbuf_free_span(&bd.zspan[i]);
798 }
799
800 MEM_freeN(corner_tris);
801 MEM_freeN(bd.zspan);
802}
803
804/* ******************** NORMALS ************************ */
805
806static void normal_compress(float out[3],
807 const float in[3],
808 const eBakeNormalSwizzle normal_swizzle[3])
809{
810 const int swizzle_index[6] = {
811 0, /* R_BAKE_POSX */
812 1, /* R_BAKE_POSY */
813 2, /* R_BAKE_POSZ */
814 0, /* R_BAKE_NEGX */
815 1, /* R_BAKE_NEGY */
816 2, /* R_BAKE_NEGZ */
817 };
818 const float swizzle_sign[6] = {
819 +1.0f, /* R_BAKE_POSX */
820 +1.0f, /* R_BAKE_POSY */
821 +1.0f, /* R_BAKE_POSZ */
822 -1.0f, /* R_BAKE_NEGX */
823 -1.0f, /* R_BAKE_NEGY */
824 -1.0f, /* R_BAKE_NEGZ */
825 };
826
827 int i;
828
829 for (i = 0; i < 3; i++) {
830 int index;
831 float sign;
832
833 sign = swizzle_sign[normal_swizzle[i]];
834 index = swizzle_index[normal_swizzle[i]];
835
836 /*
837 * There is a small 1e-5f bias for precision issues. otherwise
838 * we randomly get 127 or 128 for neutral colors in tangent maps.
839 * we choose 128 because it is the convention flat color. *
840 */
841
842 out[i] = sign * in[index] / 2.0f + 0.5f + 1e-5f;
843 }
844}
845
847 const size_t pixels_num,
848 const int depth,
849 float result[],
850 Mesh *mesh,
851 const eBakeNormalSwizzle normal_swizzle[3],
852 const float mat[4][4])
853{
854 size_t i;
855
856 TriTessFace *triangles;
857
858 Mesh *mesh_eval = BKE_mesh_copy_for_eval(*mesh);
859
860 triangles = mesh_calc_tri_tessface(mesh, true, mesh_eval);
861
862 BLI_assert(pixels_num >= 3);
863
864 for (i = 0; i < pixels_num; i++) {
865 TriTessFace *triangle;
866 float tangents[3][3];
867 float normals[3][3];
868 float signs[3];
869 int j;
870
871 float tangent[3];
872 float normal[3];
873 float binormal[3];
874 float sign;
875 float u, v, w;
876
877 float tsm[3][3]; /* tangent space matrix */
878 float itsm[3][3];
879
880 size_t offset;
881 float nor[3]; /* texture normal */
882
883 bool is_smooth;
884
885 int primitive_id = pixel_array[i].primitive_id;
886
887 offset = i * depth;
888
889 if (primitive_id == -1) {
890 if (depth == 4) {
891 copy_v4_fl4(&result[offset], 0.5f, 0.5f, 1.0f, 1.0f);
892 }
893 else {
894 copy_v3_fl3(&result[offset], 0.5f, 0.5f, 1.0f);
895 }
896 continue;
897 }
898
899 triangle = &triangles[primitive_id];
900 is_smooth = triangle->is_smooth;
901
902 for (j = 0; j < 3; j++) {
903 const TSpace *ts;
904
905 if (is_smooth) {
906 if (triangle->loop_normal[j]) {
907 copy_v3_v3(normals[j], triangle->loop_normal[j]);
908 }
909 else {
910 copy_v3_v3(normals[j], triangle->vert_normals[j]);
911 }
912 }
913
914 ts = triangle->tspace[j];
915 copy_v3_v3(tangents[j], ts->tangent);
916 signs[j] = ts->sign;
917 }
918
919 u = pixel_array[i].uv[0];
920 v = pixel_array[i].uv[1];
921 w = 1.0f - u - v;
922
923 /* normal */
924 if (is_smooth) {
926 }
927 else {
928 copy_v3_v3(normal, triangle->normal);
929 }
930
931 /* tangent */
932 interp_barycentric_tri_v3(tangents, u, v, tangent);
933
934 /* sign */
935 /* The sign is the same at all face vertices for any non degenerate face.
936 * Just in case we clamp the interpolated value though. */
937 sign = (signs[0] * u + signs[1] * v + signs[2] * w) < 0 ? (-1.0f) : 1.0f;
938
939 /* binormal */
940 /* `B = sign * cross(N, T)` */
941 cross_v3_v3v3(binormal, normal, tangent);
942 mul_v3_fl(binormal, sign);
943
944 /* populate tangent space matrix */
945 copy_v3_v3(tsm[0], tangent);
946 copy_v3_v3(tsm[1], binormal);
947 copy_v3_v3(tsm[2], normal);
948
949 /* texture values */
950 copy_v3_v3(nor, &result[offset]);
951
952 /* converts from world space to local space */
954
955 invert_m3_m3(itsm, tsm);
956 mul_m3_v3(itsm, nor);
958
959 /* save back the values */
960 normal_compress(&result[offset], nor, normal_swizzle);
961 }
962
963 /* garbage collection */
964 MEM_freeN(triangles);
965
966 if (mesh_eval) {
967 BKE_id_free(nullptr, mesh_eval);
968 }
969}
970
972 const size_t pixels_num,
973 const int depth,
974 float result[],
975 Object *ob,
976 const eBakeNormalSwizzle normal_swizzle[3])
977{
978 size_t i;
979 float iobmat[4][4];
980
981 invert_m4_m4(iobmat, ob->object_to_world().ptr());
982
983 for (i = 0; i < pixels_num; i++) {
984 size_t offset;
985 float nor[3];
986
987 if (pixel_array[i].primitive_id == -1) {
988 continue;
989 }
990
991 offset = i * depth;
992 copy_v3_v3(nor, &result[offset]);
993
994 /* rotates only without translation */
995 mul_mat3_m4_v3(iobmat, nor);
997
998 /* save back the values */
999 normal_compress(&result[offset], nor, normal_swizzle);
1000 }
1001}
1002
1004 const size_t pixels_num,
1005 const int depth,
1006 float result[],
1007 const eBakeNormalSwizzle normal_swizzle[3])
1008{
1009 size_t i;
1010
1011 for (i = 0; i < pixels_num; i++) {
1012 size_t offset;
1013 float nor[3];
1014
1015 if (pixel_array[i].primitive_id == -1) {
1016 continue;
1017 }
1018
1019 offset = i * depth;
1020 copy_v3_v3(nor, &result[offset]);
1021
1022 /* save back the values */
1023 normal_compress(&result[offset], nor, normal_swizzle);
1024 }
1025}
1026
1027void RE_bake_ibuf_clear(Image *image, const bool is_tangent)
1028{
1029 ImBuf *ibuf;
1030 void *lock;
1031
1032 const float vec_alpha[4] = {0.0f, 0.0f, 0.0f, 0.0f};
1033 const float vec_solid[4] = {0.0f, 0.0f, 0.0f, 1.0f};
1034 const float nor_alpha[4] = {0.5f, 0.5f, 1.0f, 0.0f};
1035 const float nor_solid[4] = {0.5f, 0.5f, 1.0f, 1.0f};
1036
1037 ibuf = BKE_image_acquire_ibuf(image, nullptr, &lock);
1038 BLI_assert(ibuf);
1039
1040 if (is_tangent) {
1041 IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? nor_alpha : nor_solid);
1042 }
1043 else {
1044 IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid);
1045 }
1046
1047 BKE_image_release_ibuf(image, ibuf, lock);
1048}
1049
1050/* ************************************************************* */
1051
1052int RE_pass_depth(const eScenePassType pass_type)
1053{
1054 /* IMB_buffer_byte_from_float assumes 4 channels
1055 * making it work for now - XXX */
1056 return 4;
1057
1058 switch (pass_type) {
1059 case SCE_PASS_Z:
1060 case SCE_PASS_AO:
1061 case SCE_PASS_MIST: {
1062 return 1;
1063 }
1064 case SCE_PASS_UV: {
1065 return 2;
1066 }
1067 case SCE_PASS_COMBINED:
1068 case SCE_PASS_SHADOW:
1069 case SCE_PASS_POSITION:
1070 case SCE_PASS_NORMAL:
1071 case SCE_PASS_VECTOR:
1072 case SCE_PASS_INDEXOB: /* XXX double check */
1073 case SCE_PASS_EMIT:
1075 case SCE_PASS_INDEXMA:
1088 default: {
1089 return 3;
1090 }
1091 }
1092}
CustomData interface, see also DNA_customdata_types.h.
const void * CustomData_get_layer_n(const CustomData *data, eCustomDataType type, int n)
int CustomData_get_named_layer(const CustomData *data, eCustomDataType type, blender::StringRef name)
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
ImBuf * BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **r_lock)
void BKE_image_release_ibuf(Image *ima, ImBuf *ibuf, void *lock)
void BKE_id_free(Main *bmain, void *idv)
Mesh * BKE_mesh_copy_for_eval(const Mesh &source)
bool BKE_mesh_face_normals_are_dirty(const Mesh *mesh)
int BKE_mesh_runtime_corner_tris_len(const Mesh *mesh)
void BKE_mesh_calc_loop_tangents(Mesh *mesh_eval, bool calc_active_tangent, const char(*tangent_names)[MAX_CUSTOMDATA_LAYER_NAME], int tangent_names_len)
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BVH_RAYCAST_DIST_MAX
int BLI_bvhtree_ray_cast(const BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata)
MINLINE int clamp_i(int value, int min, int max)
void interp_barycentric_tri_v3(float data[3][3], float u, float v, float res[3])
MINLINE int poly_to_tri_count(int poly_count, int corner_count)
MINLINE void axis_dominant_v3(int *r_axis_a, int *r_axis_b, const float axis[3])
void mul_m3_v3(const float M[3][3], float r[3])
bool invert_m3_m3(float inverse[3][3], const float mat[3][3])
void mul_m4_v3(const float M[4][4], float r[3])
void mul_transposed_mat3_m4_v3(const float M[4][4], float r[3])
void mul_v3_m4v3(float r[3], const float mat[4][4], const float vec[3])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
void mul_v3_mat3_m4v3(float r[3], const float mat[4][4], const float vec[3])
void mul_mat3_m4_v3(const float mat[4][4], float r[3])
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void copy_v2_fl2(float v[2], float x, float y)
MINLINE void copy_v4_fl4(float v[4], float x, float y, float z, float w)
MINLINE float len_squared_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void copy_v3_fl3(float v[3], float x, float y, float z)
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void negate_v3(float r[3])
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE float normalize_v3(float n[3])
unsigned int uint
@ CD_PROP_FLOAT2
eBakeNormalSwizzle
@ R_BAKE_ADJACENT_FACES
@ R_BAKE_EXTEND
@ R_IMF_PLANES_RGBA
eScenePassType
@ SCE_PASS_NORMAL
@ SCE_PASS_GLOSSY_DIRECT
@ SCE_PASS_AO
@ SCE_PASS_DIFFUSE_COLOR
@ SCE_PASS_POSITION
@ SCE_PASS_UV
@ SCE_PASS_SUBSURFACE_INDIRECT
@ SCE_PASS_TRANSM_DIRECT
@ SCE_PASS_SUBSURFACE_COLOR
@ SCE_PASS_GLOSSY_COLOR
@ SCE_PASS_DIFFUSE_DIRECT
@ SCE_PASS_GLOSSY_INDIRECT
@ SCE_PASS_INDEXMA
@ SCE_PASS_INDEXOB
@ SCE_PASS_TRANSM_INDIRECT
@ SCE_PASS_COMBINED
@ SCE_PASS_Z
@ SCE_PASS_VECTOR
@ SCE_PASS_DIFFUSE_INDIRECT
@ SCE_PASS_SUBSURFACE_DIRECT
@ SCE_PASS_SHADOW
@ SCE_PASS_TRANSM_COLOR
@ SCE_PASS_MIST
@ SCE_PASS_EMIT
@ SCE_PASS_ENVIRONMENT
void IMB_rectfill_alpha(ImBuf *ibuf, float value)
Definition rectop.cc:1195
#define FILTER_MASK_USED
Definition IMB_imbuf.hh:297
void IMB_rectfill(ImBuf *drect, const float col[4])
Definition rectop.cc:979
void IMB_filter_extend(ImBuf *ibuf, char *mask, int filter)
Definition filter.cc:317
Read Guarded memory(de)allocation.
volatile int lock
static bool cast_ray_highpoly(blender::bke::BVHTreeFromMesh *treeData, TriTessFace *triangle_low, TriTessFace *triangles[], BakePixel *pixel_array_low, BakePixel *pixel_array, const float mat_low[4][4], BakeHighPolyData *highpoly, const int highpoly_num, blender::MutableSpan< BVHTreeRayHit > hits, const float co[3], const float dir[3], const int pixel_id, const float max_ray_distance)
Definition bake.cc:322
void RE_bake_normal_world_to_tangent(const BakePixel pixel_array[], const size_t pixels_num, const int depth, float result[], Mesh *mesh, const eBakeNormalSwizzle normal_swizzle[3], const float mat[4][4])
Definition bake.cc:846
int RE_pass_depth(const eScenePassType pass_type)
Definition bake.cc:1052
static 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)
Definition bake.cc:277
static void calc_point_from_barycentric_cage(TriTessFace *triangles_low, TriTessFace *triangles_cage, const float mat_low[4][4], const float mat_cage[4][4], int primitive_id, float u, float v, float r_co[3], float r_dir[3])
Definition bake.cc:181
static void store_bake_pixel(void *handle, int x, int y, float u, float v)
Definition bake.cc:108
void RE_bake_ibuf_clear(Image *image, const bool is_tangent)
Definition bake.cc:1027
static void calc_point_from_barycentric_extrusion(TriTessFace *triangles, const float mat[4][4], const float imat[4][4], int primitive_id, float u, float v, float cage_extrusion, float r_co[3], float r_dir[3], const bool is_cage)
Definition bake.cc:224
void RE_bake_normal_world_to_world(const BakePixel pixel_array[], const size_t pixels_num, const int depth, float result[], const eBakeNormalSwizzle normal_swizzle[3])
Definition bake.cc:1003
void RE_bake_pixels_populate(Mesh *mesh, BakePixel pixel_array[], const size_t pixels_num, const BakeTargets *targets, const char *uv_layer)
Definition bake.cc:709
static void normal_compress(float out[3], const float in[3], const eBakeNormalSwizzle normal_swizzle[3])
Definition bake.cc:806
void RE_bake_margin(ImBuf *ibuf, char *mask, const int margin, const char margin_type, const Mesh *mesh, char const *uv_layer, const float uv_offset[2])
Definition bake.cc:148
void RE_bake_normal_world_to_object(const BakePixel pixel_array[], const size_t pixels_num, const int depth, float result[], Object *ob, const eBakeNormalSwizzle normal_swizzle[3])
Definition bake.cc:971
static TriTessFace * mesh_calc_tri_tessface(Mesh *mesh, bool tangent, Mesh *mesh_eval)
Definition bake.cc:451
void RE_bake_mask_fill(const BakePixel pixel_array[], const size_t pixels_num, char *mask)
Definition bake.cc:133
bool RE_bake_pixels_populate_from_objects(Mesh *me_low, BakePixel pixel_array_from[], BakePixel pixel_array_to[], BakeHighPolyData highpoly[], const int highpoly_num, const size_t pixels_num, const bool is_custom_cage, const float cage_extrusion, const float max_ray_distance, const float mat_low[4][4], const float mat_cage[4][4], Mesh *me_cage)
Definition bake.cc:543
static void bake_differentials(BakeDataZSpan *bd, const float *uv1, const float *uv2, const float *uv3)
Definition bake.cc:684
static void raycast_callback(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *)
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
#define A
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
const T * data() const
Definition BLI_array.hh:301
AttributeSet attributes
constexpr Span slice(int64_t start, int64_t size) const
Definition BLI_span.hh:137
constexpr bool is_empty() const
Definition BLI_span.hh:260
GAttributeReader lookup(const StringRef attribute_id) const
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const void *default_value=nullptr) const
#define fabsf(x)
KDTree_3d * tree
static float normals[][3]
uint nor
constexpr T sign(T) RET
#define in
#define out
#define printf(...)
#define UINT_MAX
Definition hash_md5.cc:44
void * MEM_mallocN(size_t len, const char *str)
Definition mallocn.cc:128
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:123
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:133
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
static char faces[256]
float3 face_normal_calc(Span< float3 > vert_positions, Span< int > face_verts)
void corner_tris_calc(Span< float3 > vert_positions, OffsetIndices< int > faces, Span< int > corner_verts, MutableSpan< int3 > corner_tris)
void corner_tris_calc_with_normals(Span< float3 > vert_positions, OffsetIndices< int > faces, Span< int > corner_verts, Span< float3 > face_normals, MutableSpan< int3 > corner_tris)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
Definition BLI_task.hh:93
VecBase< int32_t, 3 > int3
VecBase< float, 3 > float3
#define FLT_MAX
Definition stdcycles.h:14
ZSpan * zspan
Definition bake.cc:86
BakeImage * bk_image
Definition bake.cc:85
float dv_dx
Definition bake.cc:88
float dv_dy
Definition bake.cc:88
float du_dy
Definition bake.cc:87
int primitive_id
Definition bake.cc:84
float du_dx
Definition bake.cc:87
BakePixel * pixel_array
Definition bake.cc:83
struct Mesh * mesh
Definition RE_bake.h:61
int height
Definition RE_bake.h:25
size_t offset
Definition RE_bake.h:26
struct Image * image
Definition RE_bake.h:21
float uv_offset[2]
Definition RE_bake.h:23
int width
Definition RE_bake.h:24
float dv_dx
Definition RE_bake.h:55
float du_dx
Definition RE_bake.h:54
int seed
Definition RE_bake.h:52
float du_dy
Definition RE_bake.h:54
float uv[2]
Definition RE_bake.h:53
float dv_dy
Definition RE_bake.h:55
int object_id
Definition RE_bake.h:51
int primitive_id
Definition RE_bake.h:51
struct Image ** material_to_image
Definition RE_bake.h:38
int materials_num
Definition RE_bake.h:39
int images_num
Definition RE_bake.h:35
BakeImage * images
Definition RE_bake.h:34
unsigned char planes
int corners_num
CustomData corner_data
int faces_num
Definition bake.cc:94
float sign
Definition bake.cc:96
float tangent[3]
Definition bake.cc:95
const TSpace * tspace[3]
Definition bake.cc:102
bool is_smooth
Definition bake.cc:105
const float * loop_normal[3]
Definition bake.cc:103
const float * vert_normals[3]
Definition bake.cc:101
const float * positions[3]
Definition bake.cc:100
float normal[3]
Definition bake.cc:104
Definition zbuf.h:12
i
Definition text_draw.cc:230
void RE_generate_texturemargin_adjacentfaces(ImBuf *ibuf, char *mask, const int margin, const Mesh *mesh, char const *uv_layer, const float uv_offset[2])
void zspan_scanconvert(ZSpan *zspan, void *handle, float *v1, float *v2, float *v3, void(*func)(void *, int, int, float, float))
Definition zbuf.cc:151
void zbuf_alloc_span(ZSpan *zspan, int rectx, int recty)
Definition zbuf.cc:33
void zbuf_free_span(ZSpan *zspan)
Definition zbuf.cc:44