diff options
Diffstat (limited to 'source/blender/render/intern/multires_bake.c')
-rw-r--r-- | source/blender/render/intern/multires_bake.c | 193 |
1 files changed, 114 insertions, 79 deletions
diff --git a/source/blender/render/intern/multires_bake.c b/source/blender/render/intern/multires_bake.c index 33d961c027d..f93397eedab 100644 --- a/source/blender/render/intern/multires_bake.c +++ b/source/blender/render/intern/multires_bake.c @@ -51,7 +51,7 @@ typedef void (*MPassKnownData)(DerivedMesh *lores_dm, const int x, const int y); -typedef void *(*MInitBakeData)(MultiresBakeRender *bkr, Image *ima); +typedef void *(*MInitBakeData)(MultiresBakeRender *bkr, ImBuf *ibuf); typedef void (*MFreeBakeData)(void *bake_data); typedef struct MultiresBakeResult { @@ -64,6 +64,7 @@ typedef struct { MPoly *mpoly; MLoop *mloop; MLoopUV *mloopuv; + float uv_offset[2]; const MLoopTri *mlooptri; float *pvtangent; const float (*precomputed_normals)[3]; @@ -91,7 +92,6 @@ typedef struct { typedef struct { float *heights; - Image *ima; DerivedMesh *ssdm; const int *orig_index_mp_to_orig; } MHeightBakeData; @@ -148,7 +148,8 @@ static void init_bake_rast(MBakeRast *bake_rast, static void flush_pixel(const MResolvePixelData *data, const int x, const int y) { - const float st[2] = {(x + 0.5f) / data->w, (y + 0.5f) / data->h}; + const float st[2] = {(x + 0.5f) / data->w + data->uv_offset[0], + (y + 0.5f) / data->h + data->uv_offset[1]}; const float *st0, *st1, *st2; const float *tang0, *tang1, *tang2; float no0[3], no1[3], no2[3]; @@ -395,8 +396,12 @@ static void *do_multires_bake_thread(void *data_v) data->tri_index = tri_index; - bake_rasterize( - bake_rast, mloopuv[lt->tri[0]].uv, mloopuv[lt->tri[1]].uv, mloopuv[lt->tri[2]].uv); + float uv[3][2]; + sub_v2_v2v2(uv[0], mloopuv[lt->tri[0]].uv, data->uv_offset); + sub_v2_v2v2(uv[1], mloopuv[lt->tri[1]].uv, data->uv_offset); + sub_v2_v2v2(uv[2], mloopuv[lt->tri[2]].uv, data->uv_offset); + + bake_rasterize(bake_rast, uv[0], uv[1], uv[2]); /* tag image buffer for refresh */ if (data->ibuf->rect_float) { @@ -447,6 +452,8 @@ static void init_ccgdm_arrays(DerivedMesh *dm) static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, + ImageTile *tile, + ImBuf *ibuf, bool require_tangent, MPassKnownData passKnownData, MInitBakeData initBakeData, @@ -462,7 +469,6 @@ static void do_multires_bake(MultiresBakeRender *bkr, MultiresBakeThread *handles; MultiresBakeQueue queue; - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); MVert *mvert = dm->getVertArray(dm); MPoly *mpoly = dm->getPolyArray(dm); MLoop *mloop = dm->getLoopArray(dm); @@ -511,7 +517,7 @@ static void do_multires_bake(MultiresBakeRender *bkr, /* all threads shares the same custom bake data */ if (initBakeData) { - bake_data = initBakeData(bkr, ima); + bake_data = initBakeData(bkr, ibuf); } if (tot_thread > 1) { @@ -539,6 +545,7 @@ static void do_multires_bake(MultiresBakeRender *bkr, handle->data.mvert = mvert; handle->data.vert_normals = vert_normals; handle->data.mloopuv = mloopuv; + BKE_image_get_tile_uv(ima, tile->tile_number, handle->data.uv_offset); handle->data.mlooptri = mlooptri; handle->data.mloop = mloop; handle->data.pvtangent = pvtangent; @@ -590,8 +597,6 @@ static void do_multires_bake(MultiresBakeRender *bkr, MEM_freeN(handles); BKE_id_free(NULL, temp_mesh); - - BKE_image_release_ibuf(ima, ibuf, NULL); } } @@ -758,10 +763,9 @@ static void interp_barycentric_mlooptri(DerivedMesh *dm, /* **************** Displacement Baker **************** */ -static void *init_heights_data(MultiresBakeRender *bkr, Image *ima) +static void *init_heights_data(MultiresBakeRender *bkr, ImBuf *ibuf) { MHeightBakeData *height_data; - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); DerivedMesh *lodm = bkr->lores_dm; BakeImBufuserData *userdata = ibuf->userdata; @@ -772,7 +776,6 @@ static void *init_heights_data(MultiresBakeRender *bkr, Image *ima) height_data = MEM_callocN(sizeof(MHeightBakeData), "MultiresBake heightData"); - height_data->ima = ima; height_data->heights = userdata->displacement_buffer; if (!bkr->use_lores_mesh) { @@ -794,8 +797,6 @@ static void *init_heights_data(MultiresBakeRender *bkr, Image *ima) height_data->orig_index_mp_to_orig = lodm->getPolyDataArray(lodm, CD_ORIGINDEX); - BKE_image_release_ibuf(ima, ibuf, NULL); - return (void *)height_data; } @@ -903,7 +904,7 @@ static void apply_heights_callback(DerivedMesh *lores_dm, /* **************** Normal Maps Baker **************** */ -static void *init_normal_data(MultiresBakeRender *bkr, Image *UNUSED(ima)) +static void *init_normal_data(MultiresBakeRender *bkr, ImBuf *UNUSED(ibuf)) { MNormalBakeData *normal_data; DerivedMesh *lodm = bkr->lores_dm; @@ -1099,7 +1100,7 @@ static void create_ao_raytree(MultiresBakeRender *bkr, MAOBakeData *ao_data) RE_rayobject_done(raytree); } -static void *init_ao_data(MultiresBakeRender *bkr, Image *UNUSED(ima)) +static void *init_ao_data(MultiresBakeRender *bkr, ImBuf *UNUSED(ibuf)) { MAOBakeData *ao_data; DerivedMesh *lodm = bkr->lores_dm; @@ -1313,8 +1314,12 @@ static void apply_ao_callback(DerivedMesh *lores_dm, /* ******$***************** Post processing ************************* */ -static void bake_ibuf_filter( - ImBuf *ibuf, char *mask, const int margin, const char margin_type, DerivedMesh *dm) +static void bake_ibuf_filter(ImBuf *ibuf, + char *mask, + const int margin, + const char margin_type, + DerivedMesh *dm, + const float uv_offset[2]) { /* must check before filtering */ const bool is_new_alpha = (ibuf->planes != R_IMF_PLANES_RGBA) && BKE_imbuf_alpha_test(ibuf); @@ -1322,7 +1327,7 @@ static void bake_ibuf_filter( if (margin) { switch (margin_type) { case R_BAKE_ADJACENT_FACES: - RE_generate_texturemargin_adjacentfaces_dm(ibuf, mask, margin, dm); + RE_generate_texturemargin_adjacentfaces_dm(ibuf, mask, margin, dm, uv_offset); break; default: /* fall through */ @@ -1427,38 +1432,54 @@ static void bake_images(MultiresBakeRender *bkr, MultiresBakeResult *result) for (link = bkr->image.first; link; link = link->next) { Image *ima = (Image *)link->data; - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); - - if (ibuf->x > 0 && ibuf->y > 0) { - BakeImBufuserData *userdata = MEM_callocN(sizeof(BakeImBufuserData), - "MultiresBake userdata"); - userdata->mask_buffer = MEM_callocN(ibuf->y * ibuf->x, "MultiresBake imbuf mask"); - ibuf->userdata = userdata; - - switch (bkr->mode) { - case RE_BAKE_NORMALS: - do_multires_bake( - bkr, ima, true, apply_tangmat_callback, init_normal_data, free_normal_data, result); - break; - case RE_BAKE_DISPLACEMENT: - do_multires_bake(bkr, - ima, - false, - apply_heights_callback, - init_heights_data, - free_heights_data, - result); - break; -/* TODO: restore ambient occlusion baking support. */ + + LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) { + ImageUser iuser; + BKE_imageuser_default(&iuser); + iuser.tile = tile->tile_number; + + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); + + if (ibuf->x > 0 && ibuf->y > 0) { + BakeImBufuserData *userdata = MEM_callocN(sizeof(BakeImBufuserData), + "MultiresBake userdata"); + userdata->mask_buffer = MEM_callocN(ibuf->y * ibuf->x, "MultiresBake imbuf mask"); + ibuf->userdata = userdata; + + switch (bkr->mode) { + case RE_BAKE_NORMALS: + do_multires_bake(bkr, + ima, + tile, + ibuf, + true, + apply_tangmat_callback, + init_normal_data, + free_normal_data, + result); + break; + case RE_BAKE_DISPLACEMENT: + do_multires_bake(bkr, + ima, + tile, + ibuf, + false, + apply_heights_callback, + init_heights_data, + free_heights_data, + result); + break; + /* TODO: restore ambient occlusion baking support. */ #if 0 - case RE_BAKE_AO: - do_multires_bake(bkr, ima, false, apply_ao_callback, init_ao_data, free_ao_data, result); - break; + case RE_BAKE_AO: + do_multires_bake(bkr, ima, tile, ibuf, false, apply_ao_callback, init_ao_data, free_ao_data, result); + break; #endif + } } - } - BKE_image_release_ibuf(ima, ibuf, NULL); + BKE_image_release_ibuf(ima, ibuf, NULL); + } ima->id.tag |= LIB_TAG_DOIT; } @@ -1471,48 +1492,62 @@ static void finish_images(MultiresBakeRender *bkr, MultiresBakeResult *result) for (link = bkr->image.first; link; link = link->next) { Image *ima = (Image *)link->data; - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); - BakeImBufuserData *userdata = (BakeImBufuserData *)ibuf->userdata; - if (ibuf->x <= 0 || ibuf->y <= 0) { - continue; - } + LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) { + ImageUser iuser; + BKE_imageuser_default(&iuser); + iuser.tile = tile->tile_number; - if (use_displacement_buffer) { - bake_ibuf_normalize_displacement(ibuf, - userdata->displacement_buffer, - userdata->mask_buffer, - result->height_min, - result->height_max); - } + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); + BakeImBufuserData *userdata = (BakeImBufuserData *)ibuf->userdata; - bake_ibuf_filter( - ibuf, userdata->mask_buffer, bkr->bake_margin, bkr->bake_margin_type, bkr->lores_dm); + if (ibuf->x <= 0 || ibuf->y <= 0) { + continue; + } - ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; - BKE_image_mark_dirty(ima, ibuf); + if (use_displacement_buffer) { + bake_ibuf_normalize_displacement(ibuf, + userdata->displacement_buffer, + userdata->mask_buffer, + result->height_min, + result->height_max); + } - if (ibuf->rect_float) { - ibuf->userflags |= IB_RECT_INVALID; - } + float uv_offset[2]; + BKE_image_get_tile_uv(ima, tile->tile_number, uv_offset); - if (ibuf->mipmap[0]) { - ibuf->userflags |= IB_MIPMAP_INVALID; - imb_freemipmapImBuf(ibuf); - } + bake_ibuf_filter(ibuf, + userdata->mask_buffer, + bkr->bake_margin, + bkr->bake_margin_type, + bkr->lores_dm, + uv_offset); + + ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; + BKE_image_mark_dirty(ima, ibuf); - if (ibuf->userdata) { - if (userdata->displacement_buffer) { - MEM_freeN(userdata->displacement_buffer); + if (ibuf->rect_float) { + ibuf->userflags |= IB_RECT_INVALID; } - MEM_freeN(userdata->mask_buffer); - MEM_freeN(userdata); - ibuf->userdata = NULL; - } + if (ibuf->mipmap[0]) { + ibuf->userflags |= IB_MIPMAP_INVALID; + imb_freemipmapImBuf(ibuf); + } + + if (ibuf->userdata) { + if (userdata->displacement_buffer) { + MEM_freeN(userdata->displacement_buffer); + } - BKE_image_release_ibuf(ima, ibuf, NULL); - DEG_id_tag_update(&ima->id, 0); + MEM_freeN(userdata->mask_buffer); + MEM_freeN(userdata); + ibuf->userdata = NULL; + } + + BKE_image_release_ibuf(ima, ibuf, NULL); + DEG_id_tag_update(&ima->id, 0); + } } } |