Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/render/intern')
-rw-r--r--source/blender/render/intern/bake.c49
-rw-r--r--source/blender/render/intern/multires_bake.c193
-rw-r--r--source/blender/render/intern/texture_margin.cc38
-rw-r--r--source/blender/render/intern/texture_pointdensity.c9
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;