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