diff options
Diffstat (limited to 'source/blender/render/intern')
-rw-r--r-- | source/blender/render/intern/bake.c | 49 | ||||
-rw-r--r-- | source/blender/render/intern/multires_bake.c | 193 | ||||
-rw-r--r-- | source/blender/render/intern/texture_margin.cc | 38 | ||||
-rw-r--r-- | source/blender/render/intern/texture_pointdensity.c | 9 |
4 files changed, 171 insertions, 118 deletions
diff --git a/source/blender/render/intern/bake.c b/source/blender/render/intern/bake.c index 69235fb6cb1..5953c0f0f8f 100644 --- a/source/blender/render/intern/bake.c +++ b/source/blender/render/intern/bake.c @@ -146,12 +146,13 @@ void RE_bake_margin(ImBuf *ibuf, const int margin, const char margin_type, Mesh const *me, - char const *uv_layer) + char const *uv_layer, + const float uv_offset[2]) { /* margin */ switch (margin_type) { case R_BAKE_ADJACENT_FACES: - RE_generate_texturemargin_adjacentfaces(ibuf, mask, margin, me, uv_layer); + RE_generate_texturemargin_adjacentfaces(ibuf, mask, margin, me, uv_layer, uv_offset); break; default: /* fall through */ @@ -746,30 +747,36 @@ void RE_bake_pixels_populate(Mesh *me, for (int i = 0; i < tottri; i++) { const MLoopTri *lt = &looptri[i]; const MPoly *mp = &me->mpoly[lt->poly]; - float vec[3][2]; - int mat_nr = mp->mat_nr; - int image_id = targets->material_to_image[mat_nr]; - if (image_id < 0) { - continue; - } - - bd.bk_image = &targets->images[image_id]; bd.primitive_id = i; - for (int a = 0; a < 3; a++) { - const float *uv = mloopuv[lt->tri[a]].uv; + /* Find images matching this material. */ + Image *image = targets->material_to_image[mp->mat_nr]; + for (int image_id = 0; image_id < targets->images_num; image_id++) { + BakeImage *bk_image = &targets->images[image_id]; + if (bk_image->image != image) { + continue; + } - /* NOTE(campbell): workaround for pixel aligned UVs which are common and can screw up our - * intersection tests where a pixel gets in between 2 faces or the middle of a quad, - * camera aligned quads also have this problem but they are less common. - * Add a small offset to the UVs, fixes bug T18685. */ - vec[a][0] = uv[0] * (float)bd.bk_image->width - (0.5f + 0.001f); - vec[a][1] = uv[1] * (float)bd.bk_image->height - (0.5f + 0.002f); - } + /* Compute triangle vertex UV coordinates. */ + float vec[3][2]; + for (int a = 0; a < 3; a++) { + const float *uv = mloopuv[lt->tri[a]].uv; + + /* NOTE(campbell): workaround for pixel aligned UVs which are common and can screw up our + * intersection tests where a pixel gets in between 2 faces or the middle of a quad, + * camera aligned quads also have this problem but they are less common. + * Add a small offset to the UVs, fixes bug T18685. */ + vec[a][0] = (uv[0] - bk_image->uv_offset[0]) * (float)bk_image->width - (0.5f + 0.001f); + vec[a][1] = (uv[1] - bk_image->uv_offset[1]) * (float)bk_image->height - (0.5f + 0.002f); + } - bake_differentials(&bd, vec[0], vec[1], vec[2]); - zspan_scanconvert(&bd.zspan[image_id], (void *)&bd, vec[0], vec[1], vec[2], store_bake_pixel); + /* Rasterize triangle. */ + bd.bk_image = bk_image; + bake_differentials(&bd, vec[0], vec[1], vec[2]); + zspan_scanconvert( + &bd.zspan[image_id], (void *)&bd, vec[0], vec[1], vec[2], store_bake_pixel); + } } for (int i = 0; i < targets->images_num; i++) { 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); + } } } diff --git a/source/blender/render/intern/texture_margin.cc b/source/blender/render/intern/texture_margin.cc index d01c0dbea71..2d68148a86a 100644 --- a/source/blender/render/intern/texture_margin.cc +++ b/source/blender/render/intern/texture_margin.cc @@ -46,6 +46,7 @@ class TextureMarginMap { Vector<int> loop_to_poly_map_; int w_, h_; + float uv_offset_[2]; Vector<uint32_t> pixel_data_; ZSpan zspan_; uint32_t value_to_store_; @@ -61,6 +62,7 @@ class TextureMarginMap { public: TextureMarginMap(size_t w, size_t h, + const float uv_offset[2], MPoly const *mpoly, MLoop const *mloop, MLoopUV const *mloopuv, @@ -76,6 +78,8 @@ class TextureMarginMap { totloop_(totloop), totedge_(totedge) { + copy_v2_v2(uv_offset_, uv_offset); + pixel_data_.resize(w_ * h_, 0xFFFFFFFF); zbuf_alloc_span(&zspan_, w_, h_); @@ -277,8 +281,8 @@ class TextureMarginMap { float2 uv_to_xy(MLoopUV const &mloopuv) const { float2 ret; - ret.x = ((mloopuv.uv[0] * w_) - (0.5f + 0.001f)); - ret.y = ((mloopuv.uv[1] * h_) - (0.5f + 0.001f)); + ret.x = (((mloopuv.uv[0] - uv_offset_[0]) * w_) - (0.5f + 0.001f)); + ret.y = (((mloopuv.uv[1] - uv_offset_[1]) * h_) - (0.5f + 0.001f)); return ret; } @@ -482,7 +486,8 @@ static void generate_margin(ImBuf *ibuf, const int margin, const Mesh *me, DerivedMesh *dm, - char const *uv_layer) + char const *uv_layer, + const float uv_offset[2]) { MPoly *mpoly; @@ -531,7 +536,8 @@ static void generate_margin(ImBuf *ibuf, tottri = dm->getNumLoopTri(dm); } - TextureMarginMap map(ibuf->x, ibuf->y, mpoly, mloop, mloopuv, totpoly, totloop, totedge); + TextureMarginMap map( + ibuf->x, ibuf->y, uv_offset, mpoly, mloop, mloopuv, totpoly, totloop, totedge); bool draw_new_mask = false; /* Now the map contains 3 sorts of values: 0xFFFFFFFF for empty pixels, `0x80000000 + polyindex` @@ -555,8 +561,8 @@ static void generate_margin(ImBuf *ibuf, * intersection tests where a pixel gets in between 2 faces or the middle of a quad, * camera aligned quads also have this problem but they are less common. * Add a small offset to the UVs, fixes bug T18685. */ - vec[a][0] = uv[0] * (float)ibuf->x - (0.5f + 0.001f); - vec[a][1] = uv[1] * (float)ibuf->y - (0.5f + 0.002f); + vec[a][0] = (uv[0] - uv_offset[0]) * (float)ibuf->x - (0.5f + 0.001f); + vec[a][1] = (uv[1] - uv_offset[1]) * (float)ibuf->y - (0.5f + 0.002f); } /* NOTE: we need the top bit for the dijkstra distance map. */ @@ -592,16 +598,20 @@ static void generate_margin(ImBuf *ibuf, } // namespace blender::render::texturemargin -void RE_generate_texturemargin_adjacentfaces( - ImBuf *ibuf, char *mask, const int margin, const Mesh *me, char const *uv_layer) +void RE_generate_texturemargin_adjacentfaces(ImBuf *ibuf, + char *mask, + const int margin, + const Mesh *me, + char const *uv_layer, + const float uv_offset[2]) { - blender::render::texturemargin::generate_margin(ibuf, mask, margin, me, nullptr, uv_layer); + blender::render::texturemargin::generate_margin( + ibuf, mask, margin, me, nullptr, uv_layer, uv_offset); } -void RE_generate_texturemargin_adjacentfaces_dm(ImBuf *ibuf, - char *mask, - const int margin, - DerivedMesh *dm) +void RE_generate_texturemargin_adjacentfaces_dm( + ImBuf *ibuf, char *mask, const int margin, DerivedMesh *dm, const float uv_offset[2]) { - blender::render::texturemargin::generate_margin(ibuf, mask, margin, nullptr, dm, nullptr); + blender::render::texturemargin::generate_margin( + ibuf, mask, margin, nullptr, dm, nullptr, uv_offset); } diff --git a/source/blender/render/intern/texture_pointdensity.c b/source/blender/render/intern/texture_pointdensity.c index bb313d4962c..8ba3bac7cad 100644 --- a/source/blender/render/intern/texture_pointdensity.c +++ b/source/blender/render/intern/texture_pointdensity.c @@ -277,11 +277,12 @@ static void pointdensity_cache_vertex_color(PointDensity *pd, BLI_assert(data_color); - if (!CustomData_has_layer(&mesh->ldata, CD_MLOOPCOL)) { + if (!CustomData_has_layer(&mesh->ldata, CD_PROP_BYTE_COLOR)) { return; } - CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPCOL, pd->vertex_attribute_name, layername); - mcol = CustomData_get_layer_named(&mesh->ldata, CD_MLOOPCOL, layername); + CustomData_validate_layer_name( + &mesh->ldata, CD_PROP_BYTE_COLOR, pd->vertex_attribute_name, layername); + mcol = CustomData_get_layer_named(&mesh->ldata, CD_PROP_BYTE_COLOR, layername); if (!mcol) { return; } @@ -372,7 +373,7 @@ static void pointdensity_cache_object(PointDensity *pd, Object *ob) mask.fmask |= CD_MASK_MTFACE | CD_MASK_MCOL; switch (pd->ob_color_source) { case TEX_PD_COLOR_VERTCOL: - mask.lmask |= CD_MASK_MLOOPCOL; + mask.lmask |= CD_MASK_PROP_BYTE_COLOR; break; case TEX_PD_COLOR_VERTWEIGHT: mask.vmask |= CD_MASK_MDEFORMVERT; |