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