[Bf-blender-cvs] [6787cc13d4e] master: Bake: add UDIM tile baking support

Brecht Van Lommel noreply at git.blender.org
Fri Apr 22 23:18:55 CEST 2022


Commit: 6787cc13d4efef19eb708e1912356f8c1d4d2e01
Author: Brecht Van Lommel
Date:   Fri Apr 22 20:44:49 2022 +0200
Branches: master
https://developer.blender.org/rB6787cc13d4efef19eb708e1912356f8c1d4d2e01

Bake: add UDIM tile baking support

Works for both Cycles and multires bake. Triangles are baked to multiple
UDIM images if they span across them, though such UV layouts are generally
discouraged as there is no filtering across UDIM tiles.

The bake margin currently only works within UDIM tiles. For the extend method
this is logical, for the adjacent faces method it may be useful to support
copying pixels from other UDIM tiles, though this seems somewhat complicated.

Fixes T95190

Ref T72390

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

M	source/blender/blenkernel/BKE_image.h
M	source/blender/blenkernel/intern/image.cc
M	source/blender/editors/object/object_bake.c
M	source/blender/editors/object/object_bake_api.c
M	source/blender/render/RE_bake.h
M	source/blender/render/RE_texture_margin.h
M	source/blender/render/intern/bake.c
M	source/blender/render/intern/multires_bake.c
M	source/blender/render/intern/texture_margin.cc

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

diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index fff3b2a8f89..42d0e66cf49 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -414,6 +414,8 @@ int BKE_image_get_tile_from_pos(struct Image *ima,
                                 const float uv[2],
                                 float r_uv[2],
                                 float r_ofs[2]);
+void BKE_image_get_tile_uv(const struct Image *ima, const int tile_number, float r_uv[2]);
+
 /**
  * Return the tile_number for the closest UDIM tile.
  */
diff --git a/source/blender/blenkernel/intern/image.cc b/source/blender/blenkernel/intern/image.cc
index 53ec148fd2d..dfa820519a5 100644
--- a/source/blender/blenkernel/intern/image.cc
+++ b/source/blender/blenkernel/intern/image.cc
@@ -829,10 +829,7 @@ ImageTile *BKE_image_get_tile_from_iuser(Image *ima, const ImageUser *iuser)
   return BKE_image_get_tile(ima, image_get_tile_number_from_iuser(ima, iuser));
 }
 
-int BKE_image_get_tile_from_pos(struct Image *ima,
-                                const float uv[2],
-                                float r_uv[2],
-                                float r_ofs[2])
+int BKE_image_get_tile_from_pos(Image *ima, const float uv[2], float r_uv[2], float r_ofs[2])
 {
   float local_ofs[2];
   if (r_ofs == nullptr) {
@@ -860,6 +857,18 @@ int BKE_image_get_tile_from_pos(struct Image *ima,
   return tile_number;
 }
 
+void BKE_image_get_tile_uv(const Image *ima, const int tile_number, float r_uv[2])
+{
+  if (ima->source != IMA_SRC_TILED) {
+    zero_v2(r_uv);
+  }
+  else {
+    const int tile_index = tile_number - 1001;
+    r_uv[0] = static_cast<float>(tile_index % 10);
+    r_uv[1] = static_cast<float>(tile_index / 10);
+  }
+}
+
 int BKE_image_find_nearest_tile(const Image *image, const float co[2])
 {
   const float co_floor[2] = {floorf(co[0]), floorf(co[1])};
@@ -868,17 +877,15 @@ int BKE_image_find_nearest_tile(const Image *image, const float co[2])
   int tile_number_best = -1;
 
   LISTBASE_FOREACH (const ImageTile *, tile, &image->tiles) {
-    const int tile_index = tile->tile_number - 1001;
-    /* Coordinates of the current tile. */
-    const float tile_index_co[2] = {static_cast<float>(tile_index % 10),
-                                    static_cast<float>(tile_index / 10)};
+    float uv_offset[2];
+    BKE_image_get_tile_uv(image, tile->tile_number, uv_offset);
 
-    if (equals_v2v2(co_floor, tile_index_co)) {
+    if (equals_v2v2(co_floor, uv_offset)) {
       return tile->tile_number;
     }
 
     /* Distance between co[2] and UDIM tile. */
-    const float dist_sq = len_squared_v2v2(tile_index_co, co);
+    const float dist_sq = len_squared_v2v2(uv_offset, co);
 
     if (dist_sq < dist_best_sq) {
       dist_best_sq = dist_sq;
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c
index d469efbd0a1..1483c24ac70 100644
--- a/source/blender/editors/object/object_bake.c
+++ b/source/blender/editors/object/object_bake.c
@@ -172,28 +172,35 @@ static bool multiresbake_check(bContext *C, wmOperator *op)
           ok = false;
         }
         else {
-          ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
+          LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
+            ImageUser iuser;
+            BKE_imageuser_default(&iuser);
+            iuser.tile = tile->tile_number;
 
-          if (!ibuf) {
-            BKE_report(op->reports, RPT_ERROR, "Baking should happen to image with image buffer");
+            ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
 
-            ok = false;
-          }
-          else {
-            if (ibuf->rect == NULL && ibuf->rect_float == NULL) {
-              ok = false;
-            }
+            if (!ibuf) {
+              BKE_report(
+                  op->reports, RPT_ERROR, "Baking should happen to image with image buffer");
 
-            if (ibuf->rect_float && !(ELEM(ibuf->channels, 0, 4))) {
               ok = false;
             }
-
-            if (!ok) {
-              BKE_report(op->reports, RPT_ERROR, "Baking to unsupported image type");
+            else {
+              if (ibuf->rect == NULL && ibuf->rect_float == NULL) {
+                ok = false;
+              }
+
+              if (ibuf->rect_float && !(ELEM(ibuf->channels, 0, 4))) {
+                ok = false;
+              }
+
+              if (!ok) {
+                BKE_report(op->reports, RPT_ERROR, "Baking to unsupported image type");
+              }
             }
-          }
 
-          BKE_image_release_ibuf(ima, ibuf, NULL);
+            BKE_image_release_ibuf(ima, ibuf, NULL);
+          }
         }
       }
     }
@@ -274,21 +281,27 @@ static void clear_single_image(Image *image, ClearFlag flag)
   const float disp_solid[4] = {0.5f, 0.5f, 0.5f, 1.0f};
 
   if ((image->id.tag & LIB_TAG_DOIT) == 0) {
-    ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
+    LISTBASE_FOREACH (ImageTile *, tile, &image->tiles) {
+      ImageUser iuser;
+      BKE_imageuser_default(&iuser);
+      iuser.tile = tile->tile_number;
 
-    if (flag == CLEAR_TANGENT_NORMAL) {
-      IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? nor_alpha : nor_solid);
-    }
-    else if (flag == CLEAR_DISPLACEMENT) {
-      IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? disp_alpha : disp_solid);
-    }
-    else {
-      IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid);
-    }
+      ImBuf *ibuf = BKE_image_acquire_ibuf(image, &iuser, NULL);
 
-    image->id.tag |= LIB_TAG_DOIT;
+      if (flag == CLEAR_TANGENT_NORMAL) {
+        IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? nor_alpha : nor_solid);
+      }
+      else if (flag == CLEAR_DISPLACEMENT) {
+        IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? disp_alpha : disp_solid);
+      }
+      else {
+        IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid);
+      }
+
+      image->id.tag |= LIB_TAG_DOIT;
 
-    BKE_image_release_ibuf(image, ibuf, NULL);
+      BKE_image_release_ibuf(image, ibuf, NULL);
+    }
   }
 }
 
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index 4ec8b7a05d5..a7379d7e492 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -19,6 +19,7 @@
 #include "BLI_fileops.h"
 #include "BLI_listbase.h"
 #include "BLI_path_util.h"
+#include "BLI_string.h"
 
 #include "BKE_context.h"
 #include "BKE_global.h"
@@ -165,6 +166,7 @@ static void bake_update_image(ScrArea *area, Image *image)
 }
 
 static bool write_internal_bake_pixels(Image *image,
+                                       const int image_tile_number,
                                        BakePixel pixel_array[],
                                        float *buffer,
                                        const int width,
@@ -174,7 +176,8 @@ static bool write_internal_bake_pixels(Image *image,
                                        const bool is_clear,
                                        const bool is_noncolor,
                                        Mesh const *mesh_eval,
-                                       char const *uv_layer)
+                                       char const *uv_layer,
+                                       const float uv_offset[2])
 {
   ImBuf *ibuf;
   void *lock;
@@ -182,7 +185,10 @@ static bool write_internal_bake_pixels(Image *image,
   char *mask_buffer = NULL;
   const size_t pixels_num = (size_t)width * (size_t)height;
 
-  ibuf = BKE_image_acquire_ibuf(image, NULL, &lock);
+  ImageUser iuser;
+  BKE_imageuser_default(&iuser);
+  iuser.tile = image_tile_number;
+  ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
 
   if (!ibuf) {
     return false;
@@ -270,7 +276,7 @@ static bool write_internal_bake_pixels(Image *image,
 
   /* margins */
   if (margin > 0) {
-    RE_bake_margin(ibuf, mask_buffer, margin, margin_type, mesh_eval, uv_layer);
+    RE_bake_margin(ibuf, mask_buffer, margin, margin_type, mesh_eval, uv_layer, uv_offset);
   }
 
   ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
@@ -303,10 +309,8 @@ static void bake_targets_refresh(BakeTargets *targets)
 
     if (ima) {
       BKE_image_partial_update_mark_full_update(ima);
-      LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
-        BKE_image_free_gputextures(ima);
-        DEG_id_tag_update(&ima->id, 0);
-      }
+      BKE_image_free_gputextures(ima);
+      DEG_id_tag_update(&ima->id, 0);
     }
   }
 }
@@ -321,7 +325,8 @@ static bool write_external_bake_pixels(const char *filepath,
                                        ImageFormatData *im_format,
                                        const bool is_noncolor,
                                        Mesh const *mesh_eval,
-                                       char const *uv_layer)
+                                       char const *uv_layer,
+                                       const float uv_offset[2])
 {
   ImBuf *ibuf = NULL;
   bool ok = false;
@@ -378,7 +383,7 @@ static bool write_external_bake_pixels(const char *filepath,
 
     mask_buffer = MEM_callocN(sizeof(char) * pixels_num, "Bake Mask");
     RE_bake_mask_fill(pixel_array, pixels_num, mask_buffer);
-    RE_bake_margin(ibuf, mask_buffer, margin, margin_type, mesh_eval, uv_layer);
+    RE_bake_margin(ibuf, mask_buffer, margin, margin_type, mesh_eval, uv_layer, uv_offset);
 
     if (mask_buffer) {
       MEM_freeN(mask_buffer);
@@ -467,7 +472,6 @@ static bool bake_object_check(ViewLayer *view_layer,
       ED_object_get_active_image(ob, mat_nr, &image, NULL, &node, &ntree);
 
       if (image) {
-        ImBuf *ibuf;
 
         if (node) {
           if (BKE_node_is_connected_to_output(ntree, node)) {
@@ -482,21 +486,27 @@ static bool bake_object_check(ViewLayer *view_layer,
           }
         }
 
-        void *lock;
-        ibuf = BKE_image_acquire_ibuf(image, NULL, &lock);
+        LISTBASE_FOREACH (ImageTile *, tile, &image->tiles) {
+          ImageUser iuser;
+          BKE_imageuser_default(&iuser);
+          iuser.tile = tile->tile

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list